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