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