xref: /linux/drivers/pinctrl/stm32/pinctrl-stm32-hdp.c (revision 186f3edfdd41f2ae87fc40a9ccba52a3bf930994) !
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) STMicroelectronics 2025 - All Rights Reserved
4  * Author: Clément Le Goffic <clement.legoffic@foss.st.com> for STMicroelectronics.
5  */
6 #include <linux/bits.h>
7 #include <linux/clk.h>
8 #include <linux/gpio/driver.h>
9 #include <linux/io.h>
10 #include <linux/of.h>
11 #include <linux/of_device.h>
12 #include <linux/pinctrl/consumer.h>
13 #include <linux/pinctrl/pinconf-generic.h>
14 #include <linux/pinctrl/pinctrl.h>
15 #include <linux/pinctrl/pinmux.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm.h>
18 
19 #include "../core.h"
20 
21 #define DRIVER_NAME		"stm32_hdp"
22 #define HDP_CTRL_ENABLE		1
23 #define HDP_CTRL_DISABLE	0
24 
25 #define HDP_CTRL		0x000
26 #define HDP_MUX			0x004
27 #define HDP_VAL			0x010
28 #define HDP_GPOSET		0x014
29 #define HDP_GPOCLR		0x018
30 #define HDP_GPOVAL		0x01c
31 #define HDP_VERR		0x3f4
32 #define HDP_IPIDR		0x3f8
33 #define HDP_SIDR		0x3fc
34 
35 #define HDP_MUX_SHIFT(n)	((n) * 4)
36 #define HDP_MUX_MASK(n)		(GENMASK(3, 0) << HDP_MUX_SHIFT(n))
37 #define HDP_MUX_GPOVAL(n)	(0xf << HDP_MUX_SHIFT(n))
38 
39 #define HDP_PIN			8
40 #define HDP_FUNC		16
41 #define HDP_FUNC_TOTAL		(HDP_PIN * HDP_FUNC)
42 
43 struct stm32_hdp {
44 	struct device *dev;
45 	void __iomem *base;
46 	struct clk *clk;
47 	struct pinctrl_dev *pctl_dev;
48 	struct gpio_chip gpio_chip;
49 	u32 mux_conf;
50 	u32 gposet_conf;
51 	const char * const *func_name;
52 };
53 
54 static const struct pinctrl_pin_desc stm32_hdp_pins[] = {
55 	PINCTRL_PIN(0, "HDP0"),
56 	PINCTRL_PIN(1, "HDP1"),
57 	PINCTRL_PIN(2, "HDP2"),
58 	PINCTRL_PIN(3, "HDP3"),
59 	PINCTRL_PIN(4, "HDP4"),
60 	PINCTRL_PIN(5, "HDP5"),
61 	PINCTRL_PIN(6, "HDP6"),
62 	PINCTRL_PIN(7, "HDP7"),
63 };
64 
65 static const char * const func_name_mp13[] = {
66 	//HDP0 functions:
67 	"pwr_pwrwake_sys",
68 	"pwr_stop_forbidden",
69 	"pwr_stdby_wakeup",
70 	"pwr_encomp_vddcore",
71 	"bsec_out_sec_niden",
72 	"aiec_sys_wakeup",
73 	"none",
74 	"none",
75 	"ddrctrl_lp_req",
76 	"pwr_ddr_ret_enable_n",
77 	"dts_clk_ptat",
78 	"none",
79 	"sram3ctrl_tamp_erase_act",
80 	"none",
81 	"none",
82 	"gpoval0",
83 	//HDP1 functions:
84 	"pwr_sel_vth_vddcpu",
85 	"pwr_mpu_ram_lowspeed",
86 	"ca7_naxierrirq",
87 	"pwr_okin_mr",
88 	"bsec_out_sec_dbgen",
89 	"aiec_c1_wakeup",
90 	"rcc_pwrds_mpu",
91 	"none",
92 	"ddrctrl_dfi_ctrlupd_req",
93 	"ddrctrl_cactive_ddrc_asr",
94 	"none",
95 	"none",
96 	"sram3ctrl_hw_erase_act",
97 	"nic400_s0_bready",
98 	"none",
99 	"gpoval1",
100 	//HDP2 functions:
101 	"pwr_pwrwake_mpu",
102 	"pwr_mpu_clock_disable_ack",
103 	"ca7_ndbgreset_i",
104 	"none",
105 	"bsec_in_rstcore_n",
106 	"bsec_out_sec_bsc_dis",
107 	"none",
108 	"none",
109 	"ddrctrl_dfi_init_complete",
110 	"ddrctrl_perf_op_is_refresh",
111 	"ddrctrl_gskp_dfi_lp_req",
112 	"none",
113 	"sram3ctrl_sw_erase_act",
114 	"nic400_s0_bvalid",
115 	"none",
116 	"gpoval2",
117 	//HDP3 functions:
118 	"pwr_sel_vth_vddcore",
119 	"pwr_mpu_clock_disable_req",
120 	"ca7_npmuirq0",
121 	"ca7_nfiqout0",
122 	"bsec_out_sec_dftlock",
123 	"bsec_out_sec_jtag_dis",
124 	"rcc_pwrds_sys",
125 	"sram3ctrl_tamp_erase_req",
126 	"ddrctrl_stat_ddrc_reg_selfref_type0",
127 	"none",
128 	"dts_valobus1_0",
129 	"dts_valobus2_0",
130 	"tamp_potential_tamp_erfcfg",
131 	"nic400_s0_wready",
132 	"nic400_s0_rready",
133 	"gpoval3",
134 	//HDP4 functions:
135 	"none",
136 	"pwr_stop2_active",
137 	"ca7_nl2reset_i",
138 	"ca7_npreset_varm_i",
139 	"bsec_out_sec_dften",
140 	"bsec_out_sec_dbgswenable",
141 	"eth1_out_pmt_intr_o",
142 	"eth2_out_pmt_intr_o",
143 	"ddrctrl_stat_ddrc_reg_selfref_type1",
144 	"ddrctrl_cactive_0",
145 	"dts_valobus1_1",
146 	"dts_valobus2_1",
147 	"tamp_nreset_sram_ercfg",
148 	"nic400_s0_wlast",
149 	"nic400_s0_rlast",
150 	"gpoval4",
151 	//HDP5 functions:
152 	"ca7_standbywfil2",
153 	"pwr_vth_vddcore_ack",
154 	"ca7_ncorereset_i",
155 	"ca7_nirqout0",
156 	"bsec_in_pwrok",
157 	"bsec_out_sec_deviceen",
158 	"eth1_out_lpi_intr_o",
159 	"eth2_out_lpi_intr_o",
160 	"ddrctrl_cactive_ddrc",
161 	"ddrctrl_wr_credit_cnt",
162 	"dts_valobus1_2",
163 	"dts_valobus2_2",
164 	"pka_pka_itamp_out",
165 	"nic400_s0_wvalid",
166 	"nic400_s0_rvalid",
167 	"gpoval5",
168 	//HDP6 functions:
169 	"ca7_standbywfe0",
170 	"pwr_vth_vddcpu_ack",
171 	"ca7_evento",
172 	"none",
173 	"bsec_in_tamper_det",
174 	"bsec_out_sec_spniden",
175 	"eth1_out_mac_speed_o1",
176 	"eth2_out_mac_speed_o1",
177 	"ddrctrl_csysack_ddrc",
178 	"ddrctrl_lpr_credit_cnt",
179 	"dts_valobus1_3",
180 	"dts_valobus2_3",
181 	"saes_tamper_out",
182 	"nic400_s0_awready",
183 	"nic400_s0_arready",
184 	"gpoval6",
185 	//HDP7 functions:
186 	"ca7_standbywfi0",
187 	"pwr_rcc_vcpu_rdy",
188 	"ca7_eventi",
189 	"ca7_dbgack0",
190 	"bsec_out_fuse_ok",
191 	"bsec_out_sec_spiden",
192 	"eth1_out_mac_speed_o0",
193 	"eth2_out_mac_speed_o0",
194 	"ddrctrl_csysreq_ddrc",
195 	"ddrctrl_hpr_credit_cnt",
196 	"dts_valobus1_4",
197 	"dts_valobus2_4",
198 	"rng_tamper_out",
199 	"nic400_s0_awavalid",
200 	"nic400_s0_aravalid",
201 	"gpoval7",
202 };
203 
204 static const char * const func_name_mp15[] = {
205 	//HDP0 functions:
206 	"pwr_pwrwake_sys",
207 	"cm4_sleepdeep",
208 	"pwr_stdby_wkup",
209 	"pwr_encomp_vddcore",
210 	"bsec_out_sec_niden",
211 	"none",
212 	"rcc_cm4_sleepdeep",
213 	"gpu_dbg7",
214 	"ddrctrl_lp_req",
215 	"pwr_ddr_ret_enable_n",
216 	"dts_clk_ptat",
217 	"none",
218 	"none",
219 	"none",
220 	"none",
221 	"gpoval0",
222 	//HDP1 functions:
223 	"pwr_pwrwake_mcu",
224 	"cm4_halted",
225 	"ca7_naxierrirq",
226 	"pwr_okin_mr",
227 	"bsec_out_sec_dbgen",
228 	"exti_sys_wakeup",
229 	"rcc_pwrds_mpu",
230 	"gpu_dbg6",
231 	"ddrctrl_dfi_ctrlupd_req",
232 	"ddrctrl_cactive_ddrc_asr",
233 	"none",
234 	"none",
235 	"none",
236 	"none",
237 	"none",
238 	"gpoval1",
239 	//HDP2 functions:
240 	"pwr_pwrwake_mpu",
241 	"cm4_rxev",
242 	"ca7_npmuirq1",
243 	"ca7_nfiqout1",
244 	"bsec_in_rstcore_n",
245 	"exti_c2_wakeup",
246 	"rcc_pwrds_mcu",
247 	"gpu_dbg5",
248 	"ddrctrl_dfi_init_complete",
249 	"ddrctrl_perf_op_is_refresh",
250 	"ddrctrl_gskp_dfi_lp_req",
251 	"none",
252 	"none",
253 	"none",
254 	"none",
255 	"gpoval2",
256 	//HDP3 functions:
257 	"pwr_sel_vth_vddcore",
258 	"cm4_txev",
259 	"ca7_npmuirq0",
260 	"ca7_nfiqout0",
261 	"bsec_out_sec_dftlock",
262 	"exti_c1_wakeup",
263 	"rcc_pwrds_sys",
264 	"gpu_dbg4",
265 	"ddrctrl_stat_ddrc_reg_selfref_type0",
266 	"ddrctrl_cactive_1",
267 	"dts_valobus1_0",
268 	"dts_valobus2_0",
269 	"none",
270 	"none",
271 	"none",
272 	"gpoval3",
273 	//HDP4 functions:
274 	"pwr_mpu_pdds_not_cstbydis",
275 	"cm4_sleeping",
276 	"ca7_nreset1",
277 	"ca7_nirqout1",
278 	"bsec_out_sec_dften",
279 	"bsec_out_sec_dbgswenable",
280 	"eth_out_pmt_intr_o",
281 	"gpu_dbg3",
282 	"ddrctrl_stat_ddrc_reg_selfref_type1",
283 	"ddrctrl_cactive_0",
284 	"dts_valobus1_1",
285 	"dts_valobus2_1",
286 	"none",
287 	"none",
288 	"none",
289 	"gpoval4",
290 	//HDP5 functions:
291 	"ca7_standbywfil2",
292 	"pwr_vth_vddcore_ack",
293 	"ca7_nreset0",
294 	"ca7_nirqout0",
295 	"bsec_in_pwrok",
296 	"bsec_out_sec_deviceen",
297 	"eth_out_lpi_intr_o",
298 	"gpu_dbg2",
299 	"ddrctrl_cactive_ddrc",
300 	"ddrctrl_wr_credit_cnt",
301 	"dts_valobus1_2",
302 	"dts_valobus2_2",
303 	"none",
304 	"none",
305 	"none",
306 	"gpoval5",
307 	//HDP6 functions:
308 	"ca7_standbywfi1",
309 	"ca7_standbywfe1",
310 	"ca7_evento",
311 	"ca7_dbgack1",
312 	"none",
313 	"bsec_out_sec_spniden",
314 	"eth_out_mac_speed_o1",
315 	"gpu_dbg1",
316 	"ddrctrl_csysack_ddrc",
317 	"ddrctrl_lpr_credit_cnt",
318 	"dts_valobus1_3",
319 	"dts_valobus2_3",
320 	"none",
321 	"none",
322 	"none",
323 	"gpoval6",
324 	//HDP7 functions:
325 	"ca7_standbywfi0",
326 	"ca7_standbywfe0",
327 	"none",
328 	"ca7_dbgack0",
329 	"bsec_out_fuse_ok",
330 	"bsec_out_sec_spiden",
331 	"eth_out_mac_speed_o0",
332 	"gpu_dbg0",
333 	"ddrctrl_csysreq_ddrc",
334 	"ddrctrl_hpr_credit_cnt",
335 	"dts_valobus1_4",
336 	"dts_valobus2_4",
337 	"none",
338 	"none",
339 	"none",
340 	"gpoval7"
341 };
342 
343 static const char * const func_name_mp25[] = {
344 	//HDP0 functions:
345 	"pwr_pwrwake_sys",
346 	"cpu2_sleep_deep",
347 	"bsec_out_tst_sdr_unlock_or_disable_scan",
348 	"bsec_out_nidenm",
349 	"bsec_out_nidena",
350 	"cpu2_state_0",
351 	"rcc_pwrds_sys",
352 	"gpu_dbg7",
353 	"ddrss_csysreq_ddrc",
354 	"ddrss_dfi_phyupd_req",
355 	"cpu3_sleep_deep",
356 	"d2_gbl_per_clk_bus_req",
357 	"pcie_usb_cxpl_debug_info_ei_0",
358 	"pcie_usb_cxpl_debug_info_ei_8",
359 	"d3_state_0",
360 	"gpoval0",
361 	//HDP1 functions:
362 	"pwr_pwrwake_cpu2",
363 	"cpu2_halted",
364 	"cpu2_state_1",
365 	"bsec_out_dbgenm",
366 	"bsec_out_dbgena",
367 	"exti1_sys_wakeup",
368 	"rcc_pwrds_cpu2",
369 	"gpu_dbg6",
370 	"ddrss_csysack_ddrc",
371 	"ddrss_dfi_phymstr_req",
372 	"cpu3_halted",
373 	"d2_gbl_per_dma_req",
374 	"pcie_usb_cxpl_debug_info_ei_1",
375 	"pcie_usb_cxpl_debug_info_ei_9",
376 	"d3_state_1",
377 	"gpoval1",
378 	//HDP2 functions:
379 	"pwr_pwrwake_cpu1",
380 	"cpu2_rxev",
381 	"cpu1_npumirq1",
382 	"cpu1_nfiqout1",
383 	"bsec_out_shdbgen",
384 	"exti1_cpu2_wakeup",
385 	"rcc_pwrds_cpu1",
386 	"gpu_dbg5",
387 	"ddrss_cactive_ddrc",
388 	"ddrss_dfi_lp_req",
389 	"cpu3_rxev",
390 	"hpdma1_clk_bus_req",
391 	"pcie_usb_cxpl_debug_info_ei_2",
392 	"pcie_usb_cxpl_debug_info_ei_10",
393 	"d3_state_2",
394 	"gpoval2",
395 	//HDP3 functions:
396 	"pwr_sel_vth_vddcpu",
397 	"cpu2_txev",
398 	"cpu1_npumirq0",
399 	"cpu1_nfiqout0",
400 	"bsec_out_ddbgen",
401 	"exti1_cpu1_wakeup",
402 	"cpu3_state_0",
403 	"gpu_dbg4",
404 	"ddrss_mcdcg_en",
405 	"ddrss_dfi_freq_0",
406 	"cpu3_txev",
407 	"hpdma2_clk_bus_req",
408 	"pcie_usb_cxpl_debug_info_ei_3",
409 	"pcie_usb_cxpl_debug_info_ei_11",
410 	"d1_state_0",
411 	"gpoval3",
412 	//HDP4 functions:
413 	"pwr_sel_vth_vddcore",
414 	"cpu2_sleeping",
415 	"cpu1_evento",
416 	"cpu1_nirqout1",
417 	"bsec_out_spnidena",
418 	"exti2_d3_wakeup",
419 	"eth1_out_pmt_intr_o",
420 	"gpu_dbg3",
421 	"ddrss_dphycg_en",
422 	"ddrss_obsp0",
423 	"cpu3_sleeping",
424 	"hpdma3_clk_bus_req",
425 	"pcie_usb_cxpl_debug_info_ei_4",
426 	"pcie_usb_cxpl_debug_info_ei_12",
427 	"d1_state_1",
428 	"gpoval4",
429 	//HDP5 functions:
430 	"cpu1_standby_wfil2",
431 	"none",
432 	"none",
433 	"cpu1_nirqout0",
434 	"bsec_out_spidena",
435 	"exti2_cpu3_wakeup",
436 	"eth1_out_lpi_intr_o",
437 	"gpu_dbg2",
438 	"ddrctrl_dfi_init_start",
439 	"ddrss_obsp1",
440 	"cpu3_state_1",
441 	"d3_gbl_per_clk_bus_req",
442 	"pcie_usb_cxpl_debug_info_ei_5",
443 	"pcie_usb_cxpl_debug_info_ei_13",
444 	"d1_state_2",
445 	"gpoval5",
446 	//HDP6 functions:
447 	"cpu1_standby_wfi1",
448 	"cpu1_standby_wfe1",
449 	"cpu1_halted1",
450 	"cpu1_naxierrirq",
451 	"bsec_out_spnidenm",
452 	"exti2_cpu2_wakeup",
453 	"eth2_out_pmt_intr_o",
454 	"gpu_dbg1",
455 	"ddrss_dfi_init_complete",
456 	"ddrss_obsp2",
457 	"d2_state_0",
458 	"d3_gbl_per_dma_req",
459 	"pcie_usb_cxpl_debug_info_ei_6",
460 	"pcie_usb_cxpl_debug_info_ei_14",
461 	"cpu1_state_0",
462 	"gpoval6",
463 	//HDP7 functions:
464 	"cpu1_standby_wfi0",
465 	"cpu1_standby_wfe0",
466 	"cpu1_halted0",
467 	"none",
468 	"bsec_out_spidenm",
469 	"exti2_cpu1__wakeup",
470 	"eth2_out_lpi_intr_o",
471 	"gpu_dbg0",
472 	"ddrss_dfi_ctrlupd_req",
473 	"ddrss_obsp3",
474 	"d2_state_1",
475 	"lpdma1_clk_bus_req",
476 	"pcie_usb_cxpl_debug_info_ei_7",
477 	"pcie_usb_cxpl_debug_info_ei_15",
478 	"cpu1_state_1",
479 	"gpoval7",
480 };
481 
482 static const char * const stm32_hdp_pins_group[] = {
483 	"HDP0",
484 	"HDP1",
485 	"HDP2",
486 	"HDP3",
487 	"HDP4",
488 	"HDP5",
489 	"HDP6",
490 	"HDP7"
491 };
492 
stm32_hdp_gpio_get_direction(struct gpio_chip * gc,unsigned int offset)493 static int stm32_hdp_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
494 {
495 	return GPIO_LINE_DIRECTION_OUT;
496 }
497 
stm32_hdp_pinctrl_get_groups_count(struct pinctrl_dev * pctldev)498 static int stm32_hdp_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
499 {
500 	return ARRAY_SIZE(stm32_hdp_pins);
501 }
502 
stm32_hdp_pinctrl_get_group_name(struct pinctrl_dev * pctldev,unsigned int selector)503 static const char *stm32_hdp_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
504 						    unsigned int selector)
505 {
506 	return stm32_hdp_pins[selector].name;
507 }
508 
stm32_hdp_pinctrl_get_group_pins(struct pinctrl_dev * pctldev,unsigned int selector,const unsigned int ** pins,unsigned int * num_pins)509 static int stm32_hdp_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
510 					    const unsigned int **pins, unsigned int *num_pins)
511 {
512 	*pins = &stm32_hdp_pins[selector].number;
513 	*num_pins = 1;
514 
515 	return 0;
516 }
517 
518 static const struct pinctrl_ops stm32_hdp_pinctrl_ops = {
519 	.get_groups_count = stm32_hdp_pinctrl_get_groups_count,
520 	.get_group_name	  = stm32_hdp_pinctrl_get_group_name,
521 	.get_group_pins	  = stm32_hdp_pinctrl_get_group_pins,
522 	.dt_node_to_map	  = pinconf_generic_dt_node_to_map_all,
523 	.dt_free_map	  = pinconf_generic_dt_free_map,
524 };
525 
stm32_hdp_pinmux_get_functions_count(struct pinctrl_dev * pctldev)526 static int stm32_hdp_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
527 {
528 	return HDP_FUNC_TOTAL;
529 }
530 
stm32_hdp_pinmux_get_function_name(struct pinctrl_dev * pctldev,unsigned int selector)531 static const char *stm32_hdp_pinmux_get_function_name(struct pinctrl_dev *pctldev,
532 							  unsigned int selector)
533 {
534 	struct stm32_hdp *hdp = pinctrl_dev_get_drvdata(pctldev);
535 
536 	return hdp->func_name[selector];
537 }
538 
stm32_hdp_pinmux_get_function_groups(struct pinctrl_dev * pctldev,unsigned int selector,const char * const ** groups,unsigned int * num_groups)539 static int stm32_hdp_pinmux_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector,
540 						const char *const **groups,
541 						unsigned int *num_groups)
542 {
543 	u32 index = selector / HDP_FUNC;
544 
545 	*groups = &stm32_hdp_pins[index].name;
546 	*num_groups = 1;
547 
548 	return 0;
549 }
550 
stm32_hdp_pinmux_set_mux(struct pinctrl_dev * pctldev,unsigned int func_selector,unsigned int group_selector)551 static int stm32_hdp_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
552 				    unsigned int group_selector)
553 {
554 	struct stm32_hdp *hdp = pinctrl_dev_get_drvdata(pctldev);
555 
556 	unsigned int pin = stm32_hdp_pins[group_selector].number;
557 	u32 mux;
558 
559 	func_selector %= HDP_FUNC;
560 	mux = readl_relaxed(hdp->base + HDP_MUX);
561 	mux &= ~HDP_MUX_MASK(pin);
562 	mux |= func_selector << HDP_MUX_SHIFT(pin);
563 
564 	writel_relaxed(mux, hdp->base + HDP_MUX);
565 	hdp->mux_conf = mux;
566 
567 	return 0;
568 }
569 
570 static const struct pinmux_ops stm32_hdp_pinmux_ops = {
571 	.get_functions_count = stm32_hdp_pinmux_get_functions_count,
572 	.get_function_name   = stm32_hdp_pinmux_get_function_name,
573 	.get_function_groups = stm32_hdp_pinmux_get_function_groups,
574 	.set_mux	     = stm32_hdp_pinmux_set_mux,
575 	.gpio_set_direction  = NULL,
576 };
577 
578 static struct pinctrl_desc stm32_hdp_pdesc = {
579 	.name	 = DRIVER_NAME,
580 	.pins	 = stm32_hdp_pins,
581 	.npins	 = ARRAY_SIZE(stm32_hdp_pins),
582 	.pctlops = &stm32_hdp_pinctrl_ops,
583 	.pmxops	 = &stm32_hdp_pinmux_ops,
584 	.owner	 = THIS_MODULE,
585 };
586 
587 static const struct of_device_id stm32_hdp_of_match[] = {
588 	{
589 		.compatible = "st,stm32mp131-hdp",
590 		.data = &func_name_mp13,
591 	},
592 	{
593 		.compatible = "st,stm32mp151-hdp",
594 		.data = &func_name_mp15,
595 	},
596 	{
597 		.compatible = "st,stm32mp251-hdp",
598 		.data = &func_name_mp25,
599 	},
600 	{}
601 };
602 MODULE_DEVICE_TABLE(of, stm32_hdp_of_match);
603 
stm32_hdp_probe(struct platform_device * pdev)604 static int stm32_hdp_probe(struct platform_device *pdev)
605 {
606 	struct device *dev = &pdev->dev;
607 	struct stm32_hdp *hdp;
608 	u8 version;
609 	int err;
610 
611 	hdp = devm_kzalloc(dev, sizeof(*hdp), GFP_KERNEL);
612 	if (!hdp)
613 		return -ENOMEM;
614 	hdp->dev = dev;
615 
616 	platform_set_drvdata(pdev, hdp);
617 
618 	hdp->base = devm_platform_ioremap_resource(pdev, 0);
619 	if (IS_ERR(hdp->base))
620 		return PTR_ERR(hdp->base);
621 
622 	hdp->func_name = of_device_get_match_data(dev);
623 	if (!hdp->func_name)
624 		return dev_err_probe(dev, -ENODEV, "No function name provided\n");
625 
626 	hdp->clk = devm_clk_get_enabled(dev, NULL);
627 	if (IS_ERR(hdp->clk))
628 		return dev_err_probe(dev, PTR_ERR(hdp->clk), "No HDP clock provided\n");
629 
630 	err = devm_pinctrl_register_and_init(dev, &stm32_hdp_pdesc, hdp, &hdp->pctl_dev);
631 	if (err)
632 		return dev_err_probe(dev, err, "Failed to register pinctrl\n");
633 
634 	err = pinctrl_enable(hdp->pctl_dev);
635 	if (err)
636 		return dev_err_probe(dev, err, "Failed to enable pinctrl\n");
637 
638 	hdp->gpio_chip.get_direction = stm32_hdp_gpio_get_direction;
639 	hdp->gpio_chip.ngpio	     = ARRAY_SIZE(stm32_hdp_pins);
640 	hdp->gpio_chip.can_sleep     = true;
641 	hdp->gpio_chip.names	     = stm32_hdp_pins_group;
642 
643 	err = bgpio_init(&hdp->gpio_chip, dev, 4,
644 			 hdp->base + HDP_GPOVAL,
645 			 hdp->base + HDP_GPOSET,
646 			 hdp->base + HDP_GPOCLR,
647 			 NULL, NULL, BGPIOF_NO_INPUT);
648 	if (err)
649 		return dev_err_probe(dev, err, "Failed to init bgpio\n");
650 
651 
652 	err = devm_gpiochip_add_data(dev, &hdp->gpio_chip, hdp);
653 	if (err)
654 		return dev_err_probe(dev, err, "Failed to add gpiochip\n");
655 
656 	writel_relaxed(HDP_CTRL_ENABLE, hdp->base + HDP_CTRL);
657 
658 	version = readl_relaxed(hdp->base + HDP_VERR);
659 	dev_dbg(dev, "STM32 HDP version %u.%u initialized\n", version >> 4, version & 0x0f);
660 
661 	return 0;
662 }
663 
stm32_hdp_remove(struct platform_device * pdev)664 static void stm32_hdp_remove(struct platform_device *pdev)
665 {
666 	struct stm32_hdp *hdp = platform_get_drvdata(pdev);
667 
668 	writel_relaxed(HDP_CTRL_DISABLE, hdp->base + HDP_CTRL);
669 }
670 
stm32_hdp_suspend(struct device * dev)671 static int stm32_hdp_suspend(struct device *dev)
672 {
673 	struct stm32_hdp *hdp = dev_get_drvdata(dev);
674 
675 	hdp->gposet_conf = readl_relaxed(hdp->base + HDP_GPOSET);
676 
677 	pinctrl_pm_select_sleep_state(dev);
678 
679 	clk_disable_unprepare(hdp->clk);
680 
681 	return 0;
682 }
683 
stm32_hdp_resume(struct device * dev)684 static int stm32_hdp_resume(struct device *dev)
685 {
686 	struct stm32_hdp *hdp = dev_get_drvdata(dev);
687 	int err;
688 
689 	err = clk_prepare_enable(hdp->clk);
690 	if (err) {
691 		dev_err(dev, "Failed to prepare_enable clk (%d)\n", err);
692 		return err;
693 	}
694 
695 	writel_relaxed(HDP_CTRL_ENABLE, hdp->base + HDP_CTRL);
696 	writel_relaxed(hdp->gposet_conf, hdp->base + HDP_GPOSET);
697 	writel_relaxed(hdp->mux_conf, hdp->base + HDP_MUX);
698 
699 	pinctrl_pm_select_default_state(dev);
700 
701 	return 0;
702 }
703 
704 static DEFINE_SIMPLE_DEV_PM_OPS(stm32_hdp_pm_ops, stm32_hdp_suspend, stm32_hdp_resume);
705 
706 static struct platform_driver stm32_hdp_driver = {
707 	.probe = stm32_hdp_probe,
708 	.remove = stm32_hdp_remove,
709 	.driver = {
710 		.name = DRIVER_NAME,
711 		.pm = pm_sleep_ptr(&stm32_hdp_pm_ops),
712 		.of_match_table = stm32_hdp_of_match,
713 	}
714 };
715 
716 module_platform_driver(stm32_hdp_driver);
717 
718 MODULE_AUTHOR("Clément Le Goffic");
719 MODULE_DESCRIPTION("STMicroelectronics STM32 Hardware Debug Port driver");
720 MODULE_LICENSE("GPL");
721