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