Merge tag 'pmdomain-v6.19-rc3-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm

Pull pmdomain fixes from Ulf Hansson:

- imx:
- Fix system wakeup support for imx8mp power domains
- Fix potential out-of-range access for imx8m power domains
- Fix the imx8mm gpu hang

- qcom: Fix off-by-one error for highest state in rpmpd

* tag 'pmdomain-v6.19-rc3-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm:
pmdomain: imx8mp-blk-ctrl: Keep usb phy power domain on for system wakeup
pmdomain: imx8mp-blk-ctrl: Keep gpc power domain on for system wakeup
pmdomain: imx8m-blk-ctrl: fix out-of-range access of bc->domains
pmdomain: imx: gpcv2: Fix the imx8mm gpu hang due to wrong adb400 reset
pmdomain: qcom: rpmpd: fix off-by-one error in clamping to the highest state

+34 -8
+2 -6
drivers/pmdomain/imx/gpcv2.c
··· 165 #define IMX8M_VPU_HSK_PWRDNREQN BIT(5) 166 #define IMX8M_DISP_HSK_PWRDNREQN BIT(4) 167 168 - #define IMX8MM_GPUMIX_HSK_PWRDNACKN BIT(29) 169 - #define IMX8MM_GPU_HSK_PWRDNACKN (BIT(27) | BIT(28)) 170 #define IMX8MM_VPUMIX_HSK_PWRDNACKN BIT(26) 171 #define IMX8MM_DISPMIX_HSK_PWRDNACKN BIT(25) 172 #define IMX8MM_HSIO_HSK_PWRDNACKN (BIT(23) | BIT(24)) 173 - #define IMX8MM_GPUMIX_HSK_PWRDNREQN BIT(11) 174 - #define IMX8MM_GPU_HSK_PWRDNREQN (BIT(9) | BIT(10)) 175 #define IMX8MM_VPUMIX_HSK_PWRDNREQN BIT(8) 176 #define IMX8MM_DISPMIX_HSK_PWRDNREQN BIT(7) 177 #define IMX8MM_HSIO_HSK_PWRDNREQN (BIT(5) | BIT(6)) ··· 792 .bits = { 793 .pxx = IMX8MM_GPUMIX_SW_Pxx_REQ, 794 .map = IMX8MM_GPUMIX_A53_DOMAIN, 795 - .hskreq = IMX8MM_GPUMIX_HSK_PWRDNREQN, 796 - .hskack = IMX8MM_GPUMIX_HSK_PWRDNACKN, 797 }, 798 .pgc = BIT(IMX8MM_PGC_GPUMIX), 799 .keep_clocks = true,
··· 165 #define IMX8M_VPU_HSK_PWRDNREQN BIT(5) 166 #define IMX8M_DISP_HSK_PWRDNREQN BIT(4) 167 168 + #define IMX8MM_GPU_HSK_PWRDNACKN GENMASK(29, 27) 169 #define IMX8MM_VPUMIX_HSK_PWRDNACKN BIT(26) 170 #define IMX8MM_DISPMIX_HSK_PWRDNACKN BIT(25) 171 #define IMX8MM_HSIO_HSK_PWRDNACKN (BIT(23) | BIT(24)) 172 + #define IMX8MM_GPU_HSK_PWRDNREQN GENMASK(11, 9) 173 #define IMX8MM_VPUMIX_HSK_PWRDNREQN BIT(8) 174 #define IMX8MM_DISPMIX_HSK_PWRDNREQN BIT(7) 175 #define IMX8MM_HSIO_HSK_PWRDNREQN (BIT(5) | BIT(6)) ··· 794 .bits = { 795 .pxx = IMX8MM_GPUMIX_SW_Pxx_REQ, 796 .map = IMX8MM_GPUMIX_A53_DOMAIN, 797 }, 798 .pgc = BIT(IMX8MM_PGC_GPUMIX), 799 .keep_clocks = true,
+1 -1
drivers/pmdomain/imx/imx8m-blk-ctrl.c
··· 340 341 of_genpd_del_provider(pdev->dev.of_node); 342 343 - for (i = 0; bc->onecell_data.num_domains; i++) { 344 struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; 345 346 pm_genpd_remove(&domain->genpd);
··· 340 341 of_genpd_del_provider(pdev->dev.of_node); 342 343 + for (i = 0; i < bc->onecell_data.num_domains; i++) { 344 struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; 345 346 pm_genpd_remove(&domain->genpd);
+30
drivers/pmdomain/imx/imx8mp-blk-ctrl.c
··· 53 const char * const *path_names; 54 int num_paths; 55 const char *gpc_name; 56 }; 57 58 #define DOMAIN_MAX_CLKS 3 ··· 66 struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; 67 struct device *power_dev; 68 struct imx8mp_blk_ctrl *bc; 69 int num_paths; 70 int id; 71 }; ··· 266 [IMX8MP_HSIOBLK_PD_USB_PHY1] = { 267 .name = "hsioblk-usb-phy1", 268 .gpc_name = "usb-phy1", 269 }, 270 [IMX8MP_HSIOBLK_PD_USB_PHY2] = { 271 .name = "hsioblk-usb-phy2", 272 .gpc_name = "usb-phy2", 273 }, 274 [IMX8MP_HSIOBLK_PD_PCIE] = { 275 .name = "hsioblk-pcie", ··· 598 return 0; 599 } 600 601 static struct lock_class_key blk_ctrl_genpd_lock_class; 602 603 static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) ··· 716 goto cleanup_pds; 717 } 718 719 domain->genpd.name = data->name; 720 domain->genpd.power_on = imx8mp_blk_ctrl_power_on; 721 domain->genpd.power_off = imx8mp_blk_ctrl_power_off; 722 domain->bc = bc; 723 domain->id = i; 724 725 ret = pm_genpd_init(&domain->genpd, NULL, true); 726 if (ret) { 727 dev_err_probe(dev, ret, "failed to init power domain\n"); 728 dev_pm_domain_detach(domain->power_dev, true); 729 goto cleanup_pds; 730 } ··· 783 cleanup_pds: 784 for (i--; i >= 0; i--) { 785 pm_genpd_remove(&bc->domains[i].genpd); 786 dev_pm_domain_detach(bc->domains[i].power_dev, true); 787 } 788 ··· 803 struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; 804 805 pm_genpd_remove(&domain->genpd); 806 dev_pm_domain_detach(domain->power_dev, true); 807 } 808
··· 53 const char * const *path_names; 54 int num_paths; 55 const char *gpc_name; 56 + const unsigned int flags; 57 }; 58 59 #define DOMAIN_MAX_CLKS 3 ··· 65 struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; 66 struct device *power_dev; 67 struct imx8mp_blk_ctrl *bc; 68 + struct notifier_block power_nb; 69 int num_paths; 70 int id; 71 }; ··· 264 [IMX8MP_HSIOBLK_PD_USB_PHY1] = { 265 .name = "hsioblk-usb-phy1", 266 .gpc_name = "usb-phy1", 267 + .flags = GENPD_FLAG_ACTIVE_WAKEUP, 268 }, 269 [IMX8MP_HSIOBLK_PD_USB_PHY2] = { 270 .name = "hsioblk-usb-phy2", 271 .gpc_name = "usb-phy2", 272 + .flags = GENPD_FLAG_ACTIVE_WAKEUP, 273 }, 274 [IMX8MP_HSIOBLK_PD_PCIE] = { 275 .name = "hsioblk-pcie", ··· 594 return 0; 595 } 596 597 + static int imx8mp_blk_ctrl_gpc_notifier(struct notifier_block *nb, 598 + unsigned long action, void *data) 599 + { 600 + struct imx8mp_blk_ctrl_domain *domain = 601 + container_of(nb, struct imx8mp_blk_ctrl_domain, power_nb); 602 + 603 + if (action == GENPD_NOTIFY_PRE_OFF) { 604 + if (domain->genpd.status == GENPD_STATE_ON) 605 + return NOTIFY_BAD; 606 + } 607 + 608 + return NOTIFY_OK; 609 + } 610 + 611 static struct lock_class_key blk_ctrl_genpd_lock_class; 612 613 static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) ··· 698 goto cleanup_pds; 699 } 700 701 + domain->power_nb.notifier_call = imx8mp_blk_ctrl_gpc_notifier; 702 + ret = dev_pm_genpd_add_notifier(domain->power_dev, &domain->power_nb); 703 + if (ret) { 704 + dev_err_probe(dev, ret, "failed to add power notifier\n"); 705 + dev_pm_domain_detach(domain->power_dev, true); 706 + goto cleanup_pds; 707 + } 708 + 709 domain->genpd.name = data->name; 710 domain->genpd.power_on = imx8mp_blk_ctrl_power_on; 711 domain->genpd.power_off = imx8mp_blk_ctrl_power_off; 712 + domain->genpd.flags = data->flags; 713 domain->bc = bc; 714 domain->id = i; 715 716 ret = pm_genpd_init(&domain->genpd, NULL, true); 717 if (ret) { 718 dev_err_probe(dev, ret, "failed to init power domain\n"); 719 + dev_pm_genpd_remove_notifier(domain->power_dev); 720 dev_pm_domain_detach(domain->power_dev, true); 721 goto cleanup_pds; 722 } ··· 755 cleanup_pds: 756 for (i--; i >= 0; i--) { 757 pm_genpd_remove(&bc->domains[i].genpd); 758 + dev_pm_genpd_remove_notifier(bc->domains[i].power_dev); 759 dev_pm_domain_detach(bc->domains[i].power_dev, true); 760 } 761 ··· 774 struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; 775 776 pm_genpd_remove(&domain->genpd); 777 + dev_pm_genpd_remove_notifier(domain->power_dev); 778 dev_pm_domain_detach(domain->power_dev, true); 779 } 780
+1 -1
drivers/pmdomain/qcom/rpmpd.c
··· 1001 1002 /* Clamp to the highest corner/level if sync_state isn't done yet */ 1003 if (!pd->state_synced) 1004 - this_active_corner = this_sleep_corner = pd->max_state - 1; 1005 else 1006 to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner); 1007
··· 1001 1002 /* Clamp to the highest corner/level if sync_state isn't done yet */ 1003 if (!pd->state_synced) 1004 + this_active_corner = this_sleep_corner = pd->max_state; 1005 else 1006 to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner); 1007