From 8bdd94689ef528738a0f14c44e069596a465d622 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 7 Aug 2012 01:07:01 +0200 Subject: ARM: shmobile: Use names of power domains for adding devices to them Make the power management code under arch/arm/mach-shmobile/ use names of power domains instead of pointers to domain objects for adding devices to the domains. This will allow us to put the domain objects into tables and register them all in one shot going forward. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/board-ap4evb.c | 16 ++++---- arch/arm/mach-shmobile/board-armadillo800eva.c | 6 +-- arch/arm/mach-shmobile/board-mackerel.c | 24 ++++++------ arch/arm/mach-shmobile/include/mach/pm-rmobile.h | 4 +- arch/arm/mach-shmobile/pm-rmobile.c | 4 +- arch/arm/mach-shmobile/setup-r8a7740.c | 20 +++++----- arch/arm/mach-shmobile/setup-sh7372.c | 48 ++++++++++++------------ 7 files changed, 61 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index f172ca85905c..b85957ad948b 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -1461,14 +1461,14 @@ static void __init ap4evb_init(void) platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc1_device); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device); - rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device); - - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device); + rmobile_add_device_to_domain("A4LC", &lcdc1_device); + rmobile_add_device_to_domain("A4LC", &lcdc_device); + rmobile_add_device_to_domain("A4MP", &fsi_device); + + rmobile_add_device_to_domain("A3SP", &sh_mmcif_device); + rmobile_add_device_to_domain("A3SP", &sdhi0_device); + rmobile_add_device_to_domain("A3SP", &sdhi1_device); + rmobile_add_device_to_domain("A4R", &ceu_device); hdmi_init_pm_clock(); fsi_init_pm_clock(); diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index cf10f92856dc..28e6e1d0d511 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -1181,10 +1181,10 @@ static void __init eva_init(void) eva_clock_init(); - rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device); - rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device); + rmobile_add_device_to_domain("A4LC", &lcdc0_device); + rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device); if (usb) - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, usb); + rmobile_add_device_to_domain("A3SP", usb); } static void __init eva_earlytimer_init(void) diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 7ea2b31e3199..954b02e3bb18 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1623,20 +1623,20 @@ static void __init mackerel_init(void) platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &hdmi_lcdc_device); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &meram_device); - rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &nand_flash_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device); + rmobile_add_device_to_domain("A4LC", &lcdc_device); + rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device); + rmobile_add_device_to_domain("A4LC", &meram_device); + rmobile_add_device_to_domain("A4MP", &fsi_device); + rmobile_add_device_to_domain("A3SP", &usbhs0_device); + rmobile_add_device_to_domain("A3SP", &usbhs1_device); + rmobile_add_device_to_domain("A3SP", &nand_flash_device); + rmobile_add_device_to_domain("A3SP", &sh_mmcif_device); + rmobile_add_device_to_domain("A3SP", &sdhi0_device); #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device); + rmobile_add_device_to_domain("A3SP", &sdhi1_device); #endif - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi2_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device); + rmobile_add_device_to_domain("A3SP", &sdhi2_device); + rmobile_add_device_to_domain("A4R", &ceu_device); hdmi_init_pm_clock(); sh7372_pm_init(); diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h index 5a402840fe28..0c25fc982686 100644 --- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h +++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h @@ -31,13 +31,13 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d) #ifdef CONFIG_PM extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd); -extern void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd, +extern void rmobile_add_device_to_domain(const char *domain_name, struct platform_device *pdev); extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, struct rmobile_pm_domain *rmobile_sd); #else #define rmobile_init_pm_domain(pd) do { } while (0) -#define rmobile_add_device_to_domain(pd, pdev) do { } while (0) +#define rmobile_add_device_to_domain(name, pdev) do { } while (0) #define rmobile_pm_add_subdomain(pd, sd) do { } while (0) #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index a8562540f1d6..c94056d6a029 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -149,12 +149,12 @@ void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) __rmobile_pd_power_up(rmobile_pd, false); } -void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd, +void rmobile_add_device_to_domain(const char *domain_name, struct platform_device *pdev) { struct device *dev = &pdev->dev; - pm_genpd_add_device(&rmobile_pd->genpd, dev); + pm_genpd_name_add_device(domain_name, dev); if (pm_clk_no_clocks(dev)) pm_clk_add(dev, NULL); } diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 78948a9dba0e..db7af5685540 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -688,16 +688,16 @@ void __init r8a7740_add_standard_devices(void) /* add devices to PM domain */ - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif0_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif1_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif2_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif3_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif4_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif5_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif6_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif7_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scifb_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &i2c1_device); + rmobile_add_device_to_domain("A3SP", &scif0_device); + rmobile_add_device_to_domain("A3SP", &scif1_device); + rmobile_add_device_to_domain("A3SP", &scif2_device); + rmobile_add_device_to_domain("A3SP", &scif3_device); + rmobile_add_device_to_domain("A3SP", &scif4_device); + rmobile_add_device_to_domain("A3SP", &scif5_device); + rmobile_add_device_to_domain("A3SP", &scif6_device); + rmobile_add_device_to_domain("A3SP", &scif7_device); + rmobile_add_device_to_domain("A3SP", &scifb_device); + rmobile_add_device_to_domain("A3SP", &i2c1_device); } static void __init r8a7740_earlytimer_init(void) diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 838a87be1d5c..95f06c8fb855 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -1023,30 +1023,30 @@ void __init sh7372_add_standard_devices(void) platform_add_devices(sh7372_late_devices, ARRAY_SIZE(sh7372_late_devices)); - rmobile_add_device_to_domain(&sh7372_pd_a3rv, &vpu_device); - rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu0_device); - rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif2_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif3_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif4_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif5_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif6_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &iic1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma2_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma1_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &iic0_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu0_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu1_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu2_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu3_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &jpu_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu00_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu01_device); + rmobile_add_device_to_domain("A3RV", &vpu_device); + rmobile_add_device_to_domain("A4MP", &spu0_device); + rmobile_add_device_to_domain("A4MP", &spu1_device); + rmobile_add_device_to_domain("A3SP", &scif0_device); + rmobile_add_device_to_domain("A3SP", &scif1_device); + rmobile_add_device_to_domain("A3SP", &scif2_device); + rmobile_add_device_to_domain("A3SP", &scif3_device); + rmobile_add_device_to_domain("A3SP", &scif4_device); + rmobile_add_device_to_domain("A3SP", &scif5_device); + rmobile_add_device_to_domain("A3SP", &scif6_device); + rmobile_add_device_to_domain("A3SP", &iic1_device); + rmobile_add_device_to_domain("A3SP", &dma0_device); + rmobile_add_device_to_domain("A3SP", &dma1_device); + rmobile_add_device_to_domain("A3SP", &dma2_device); + rmobile_add_device_to_domain("A3SP", &usb_dma0_device); + rmobile_add_device_to_domain("A3SP", &usb_dma1_device); + rmobile_add_device_to_domain("A4R", &iic0_device); + rmobile_add_device_to_domain("A4R", &veu0_device); + rmobile_add_device_to_domain("A4R", &veu1_device); + rmobile_add_device_to_domain("A4R", &veu2_device); + rmobile_add_device_to_domain("A4R", &veu3_device); + rmobile_add_device_to_domain("A4R", &jpu_device); + rmobile_add_device_to_domain("A4R", &tmu00_device); + rmobile_add_device_to_domain("A4R", &tmu01_device); } static void __init sh7372_earlytimer_init(void) -- cgit v1.2.3 From 8e0e7aaef3c98c52e85f5640b73ffa82058abcfd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 7 Aug 2012 01:07:46 +0200 Subject: ARM: shmobile: Drop r8a7779_add_device_to_domain() If the r8a7779's PM domains are given names, this SoC and its boards will be able to use rmobile_add_device_to_domain() for adding devices to those domains and r8a7779_add_device_to_domain(), which is not used anywhere at the moment anyway, may be dopped. Accordingly, give names to the r8a7779's PM domains and drop r8a7779_add_device_to_domain(). Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/include/mach/r8a7779.h | 3 --- arch/arm/mach-shmobile/pm-r8a7779.c | 14 ++++---------- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index b07ad318eb2e..e0dcef0aa4c4 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -353,11 +353,8 @@ extern struct r8a7779_pm_domain r8a7779_vdp1; extern struct r8a7779_pm_domain r8a7779_impx3; extern void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd); -extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd, - struct platform_device *pdev); #else #define r8a7779_init_pm_domain(pd) do { } while (0) -#define r8a7779_add_device_to_domain(pd, pdev) do { } while (0) #endif /* CONFIG_PM */ #endif /* __ASM_R8A7779_H__ */ diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c index a18a4ae16d2b..b2a98cca66d3 100644 --- a/arch/arm/mach-shmobile/pm-r8a7779.c +++ b/arch/arm/mach-shmobile/pm-r8a7779.c @@ -199,17 +199,8 @@ void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd) pd_power_up(&r8a7779_pd->genpd); } -void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd, - struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - pm_genpd_add_device(&r8a7779_pd->genpd, dev); - if (pm_clk_no_clocks(dev)) - pm_clk_add(dev, NULL); -} - struct r8a7779_pm_domain r8a7779_sh4a = { + .genpd.name = "SH4A", .ch = { .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */ .isr_bit = 16, /* SH4A */ @@ -217,6 +208,7 @@ struct r8a7779_pm_domain r8a7779_sh4a = { }; struct r8a7779_pm_domain r8a7779_sgx = { + .genpd.name = "SGX", .ch = { .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */ .isr_bit = 20, /* SGX */ @@ -224,6 +216,7 @@ struct r8a7779_pm_domain r8a7779_sgx = { }; struct r8a7779_pm_domain r8a7779_vdp1 = { + .genpd.name = "VDP1", .ch = { .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */ .isr_bit = 21, /* VDP */ @@ -231,6 +224,7 @@ struct r8a7779_pm_domain r8a7779_vdp1 = { }; struct r8a7779_pm_domain r8a7779_impx3 = { + .genpd.name = "IMPX3", .ch = { .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */ .isr_bit = 24, /* IMP */ -- cgit v1.2.3 From 7fcb304792649e763e460c47abc4c53085bffaee Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 7 Aug 2012 01:09:31 +0200 Subject: ARM: shmobile: Use domain names when adding subdomains to power domains Make the power management code under arch/arm/mach-shmobile/ use pm_genpd_add_subdomain_names() for adding subdomains to power domains, which makes it possible to drop rmobile_pm_add_subdomain() and will allow us to carry out those operations for domain objects stored in tables in a straightforward way. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/include/mach/pm-rmobile.h | 3 --- arch/arm/mach-shmobile/pm-rmobile.c | 6 ------ arch/arm/mach-shmobile/setup-r8a7740.c | 2 +- arch/arm/mach-shmobile/setup-sh7372.c | 8 ++++---- 4 files changed, 5 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h index 0c25fc982686..7e2487790122 100644 --- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h +++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h @@ -33,12 +33,9 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d) extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd); extern void rmobile_add_device_to_domain(const char *domain_name, struct platform_device *pdev); -extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, - struct rmobile_pm_domain *rmobile_sd); #else #define rmobile_init_pm_domain(pd) do { } while (0) #define rmobile_add_device_to_domain(name, pdev) do { } while (0) -#define rmobile_pm_add_subdomain(pd, sd) do { } while (0) #endif /* CONFIG_PM */ #endif /* PM_RMOBILE_H */ diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index c94056d6a029..6c47843c511b 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -158,10 +158,4 @@ void rmobile_add_device_to_domain(const char *domain_name, if (pm_clk_no_clocks(dev)) pm_clk_add(dev, NULL); } - -void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, - struct rmobile_pm_domain *rmobile_sd) -{ - pm_genpd_add_subdomain(&rmobile_pd->genpd, &rmobile_sd->genpd); -} #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index db7af5685540..a18892d4d985 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -678,7 +678,7 @@ void __init r8a7740_add_standard_devices(void) rmobile_init_pm_domain(&r8a7740_pd_a3sp); rmobile_init_pm_domain(&r8a7740_pd_a4lc); - rmobile_pm_add_subdomain(&r8a7740_pd_a4s, &r8a7740_pd_a3sp); + pm_genpd_add_subdomain_names("A4S", "A3SP"); /* add devices */ platform_add_devices(r8a7740_early_devices, diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 95f06c8fb855..a2e1eeafd1a1 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -1011,11 +1011,11 @@ void __init sh7372_add_standard_devices(void) rmobile_init_pm_domain(&sh7372_pd_a3sp); rmobile_init_pm_domain(&sh7372_pd_a3sg); - rmobile_pm_add_subdomain(&sh7372_pd_a4lc, &sh7372_pd_a3rv); - rmobile_pm_add_subdomain(&sh7372_pd_a4r, &sh7372_pd_a4lc); + pm_genpd_add_subdomain_names("A4LC", "A3RV"); + pm_genpd_add_subdomain_names("A4R", "A4LC"); - rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sg); - rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sp); + pm_genpd_add_subdomain_names("A4S", "A3SG"); + pm_genpd_add_subdomain_names("A4S", "A3SP"); platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); -- cgit v1.2.3 From 0d09f450b6ee2065436df9fd4e0f83f9b6d71eaa Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 7 Aug 2012 01:10:22 +0200 Subject: ARM: shmobile: Add routine for automatic PM domains initialization Add a new routine, rmobile_init_domains(), allowing the caller to initialize all generic PM objects stored in a table in one operation. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/include/mach/pm-rmobile.h | 2 ++ arch/arm/mach-shmobile/pm-rmobile.c | 8 ++++++++ 2 files changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h index 7e2487790122..4c264c74760f 100644 --- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h +++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h @@ -31,10 +31,12 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d) #ifdef CONFIG_PM extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd); +extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num); extern void rmobile_add_device_to_domain(const char *domain_name, struct platform_device *pdev); #else #define rmobile_init_pm_domain(pd) do { } while (0) +#define rmobile_init_domains(domains, num) do { } while (0) #define rmobile_add_device_to_domain(name, pdev) do { } while (0) #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 6c47843c511b..4b6f2ea3169f 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -149,6 +149,14 @@ void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) __rmobile_pd_power_up(rmobile_pd, false); } +void rmobile_init_domains(struct rmobile_pm_domain domains[], int num) +{ + int j; + + for (j = 0; j < num; j++) + rmobile_init_pm_domain(&domains[j]); +} + void rmobile_add_device_to_domain(const char *domain_name, struct platform_device *pdev) { -- cgit v1.2.3 From 70fe7b24672a988f8aab77a04329d6331a1f10a8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Aug 2012 20:54:15 +0200 Subject: ARM: shmobile: Do not access sh7372 A4S domain internals directly The sh7372_enter_suspend() routine checks the status field of the generic PM domain object corresponding to the A4S domain in order to check if it can turn that domain off when entering system sleep. However, it shouldn't rely on the specific values of the generic data structures this way, so make it use its own mechanism to recognize when it is safe to turn that domain off. For this purpos, introduce a boolean variable a4s_suspend_ready that will be set by the A4S' suspend routine and unset by its resume routine executed by rmobile_pd_power_down() and __rmobile_pd_power_up(), respectively. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/pm-sh7372.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 792037069226..0a4804694dee 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -110,21 +110,33 @@ struct rmobile_pm_domain sh7372_pd_a3ri = { .bit_shift = 8, }; +static bool a4s_suspend_ready; + static int sh7372_pd_a4s_suspend(void) { /* * The A4S domain contains the CPU core and therefore it should - * only be turned off if the CPU is in use. + * only be turned off if the CPU is not in use. This may happen + * during system suspend, when SYSC is going to be used for generating + * resume signals and a4s_suspend_ready is set to let + * sh7372_enter_suspend() know that it can turn A4S off. */ + a4s_suspend_ready = true; return -EBUSY; } +static void sh7372_pd_a4s_resume(void) +{ + a4s_suspend_ready = false; +} + struct rmobile_pm_domain sh7372_pd_a4s = { .genpd.name = "A4S", .bit_shift = 10, .gov = &pm_domain_always_on_gov, .no_debug = true, .suspend = sh7372_pd_a4s_suspend, + .resume = sh7372_pd_a4s_resume, }; static int sh7372_a3sp_pd_suspend(void) @@ -390,8 +402,7 @@ static int sh7372_enter_suspend(suspend_state_t suspend_state) /* check active clocks to determine potential wakeup sources */ if (sh7372_sysc_valid(&msk, &msk2)) { - if (!console_suspend_enabled && - sh7372_pd_a4s.genpd.status == GPD_STATE_POWER_OFF) { + if (!console_suspend_enabled && a4s_suspend_ready) { /* convert INTC mask/sense to SYSC mask/sense */ sh7372_setup_sysc(msk, msk2); -- cgit v1.2.3 From e7e59a4b55706b0bbaba1cd8af46495553b6e876 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 7 Aug 2012 01:12:56 +0200 Subject: ARM: shmobile: Move sh7372's PM domain objects to a table Instead of giving a name to every sh7372's PM domain object, put them all into a table and use rmobile_init_domains(), introduced by a previous patch, for initializing them all altogether. Also, use pm_genpd_add_subdomain_names() for adding subdomains to the PM domains and pm_genpd_poweron_name() for turning on the A4S domain when preparing for system suspend. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/include/mach/sh7372.h | 18 ++--- arch/arm/mach-shmobile/pm-sh7372.c | 111 ++++++++++++++------------- arch/arm/mach-shmobile/setup-sh7372.c | 16 +--- 3 files changed, 64 insertions(+), 81 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index b59048e6d8fd..40beb796d020 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -478,21 +478,15 @@ extern struct clk sh7372_fsibck_clk; extern struct clk sh7372_fsidiva_clk; extern struct clk sh7372_fsidivb_clk; -#ifdef CONFIG_PM -extern struct rmobile_pm_domain sh7372_pd_a4lc; -extern struct rmobile_pm_domain sh7372_pd_a4mp; -extern struct rmobile_pm_domain sh7372_pd_d4; -extern struct rmobile_pm_domain sh7372_pd_a4r; -extern struct rmobile_pm_domain sh7372_pd_a3rv; -extern struct rmobile_pm_domain sh7372_pd_a3ri; -extern struct rmobile_pm_domain sh7372_pd_a4s; -extern struct rmobile_pm_domain sh7372_pd_a3sp; -extern struct rmobile_pm_domain sh7372_pd_a3sg; -#endif /* CONFIG_PM */ - extern void sh7372_intcs_suspend(void); extern void sh7372_intcs_resume(void); extern void sh7372_intca_suspend(void); extern void sh7372_intca_resume(void); +#ifdef CONFIG_PM +extern void __init sh7372_init_pm_domains(void); +#else +static inline void sh7372_init_pm_domains(void) {} +#endif + #endif /* __ASM_SH7372_H__ */ diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 0a4804694dee..0d722b5b5219 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -71,21 +71,6 @@ #ifdef CONFIG_PM -struct rmobile_pm_domain sh7372_pd_a4lc = { - .genpd.name = "A4LC", - .bit_shift = 1, -}; - -struct rmobile_pm_domain sh7372_pd_a4mp = { - .genpd.name = "A4MP", - .bit_shift = 2, -}; - -struct rmobile_pm_domain sh7372_pd_d4 = { - .genpd.name = "D4", - .bit_shift = 3, -}; - static int sh7372_a4r_pd_suspend(void) { sh7372_intcs_suspend(); @@ -93,26 +78,9 @@ static int sh7372_a4r_pd_suspend(void) return 0; } -struct rmobile_pm_domain sh7372_pd_a4r = { - .genpd.name = "A4R", - .bit_shift = 5, - .suspend = sh7372_a4r_pd_suspend, - .resume = sh7372_intcs_resume, -}; - -struct rmobile_pm_domain sh7372_pd_a3rv = { - .genpd.name = "A3RV", - .bit_shift = 6, -}; - -struct rmobile_pm_domain sh7372_pd_a3ri = { - .genpd.name = "A3RI", - .bit_shift = 8, -}; - static bool a4s_suspend_ready; -static int sh7372_pd_a4s_suspend(void) +static int sh7372_a4s_pd_suspend(void) { /* * The A4S domain contains the CPU core and therefore it should @@ -125,20 +93,11 @@ static int sh7372_pd_a4s_suspend(void) return -EBUSY; } -static void sh7372_pd_a4s_resume(void) +static void sh7372_a4s_pd_resume(void) { a4s_suspend_ready = false; } -struct rmobile_pm_domain sh7372_pd_a4s = { - .genpd.name = "A4S", - .bit_shift = 10, - .gov = &pm_domain_always_on_gov, - .no_debug = true, - .suspend = sh7372_pd_a4s_suspend, - .resume = sh7372_pd_a4s_resume, -}; - static int sh7372_a3sp_pd_suspend(void) { /* @@ -148,18 +107,62 @@ static int sh7372_a3sp_pd_suspend(void) return console_suspend_enabled ? 0 : -EBUSY; } -struct rmobile_pm_domain sh7372_pd_a3sp = { - .genpd.name = "A3SP", - .bit_shift = 11, - .gov = &pm_domain_always_on_gov, - .no_debug = true, - .suspend = sh7372_a3sp_pd_suspend, +static struct rmobile_pm_domain sh7372_pm_domains[] = { + { + .genpd.name = "A4LC", + .bit_shift = 1, + }, + { + .genpd.name = "A4MP", + .bit_shift = 2, + }, + { + .genpd.name = "D4", + .bit_shift = 3, + }, + { + .genpd.name = "A4R", + .bit_shift = 5, + .suspend = sh7372_a4r_pd_suspend, + .resume = sh7372_intcs_resume, + }, + { + .genpd.name = "A3RV", + .bit_shift = 6, + }, + { + .genpd.name = "A3RI", + .bit_shift = 8, + }, + { + .genpd.name = "A4S", + .bit_shift = 10, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = sh7372_a4s_pd_suspend, + .resume = sh7372_a4s_pd_resume, + }, + { + .genpd.name = "A3SP", + .bit_shift = 11, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = sh7372_a3sp_pd_suspend, + }, + { + .genpd.name = "A3SG", + .bit_shift = 13, + }, }; -struct rmobile_pm_domain sh7372_pd_a3sg = { - .genpd.name = "A3SG", - .bit_shift = 13, -}; +void __init sh7372_init_pm_domains(void) +{ + rmobile_init_domains(sh7372_pm_domains, ARRAY_SIZE(sh7372_pm_domains)); + pm_genpd_add_subdomain_names("A4LC", "A3RV"); + pm_genpd_add_subdomain_names("A4R", "A4LC"); + pm_genpd_add_subdomain_names("A4S", "A3SG"); + pm_genpd_add_subdomain_names("A4S", "A3SP"); +} #endif /* CONFIG_PM */ @@ -436,7 +439,7 @@ static int sh7372_pm_notifier_fn(struct notifier_block *notifier, * executed during system suspend and resume, respectively, so * that those functions don't crash while accessing the INTCS. */ - pm_genpd_poweron(&sh7372_pd_a4r.genpd); + pm_genpd_name_poweron("A4R"); break; case PM_POST_SUSPEND: pm_genpd_poweroff_unused(); diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index a2e1eeafd1a1..c1f698f2b469 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -1001,21 +1001,7 @@ static struct platform_device *sh7372_late_devices[] __initdata = { void __init sh7372_add_standard_devices(void) { - rmobile_init_pm_domain(&sh7372_pd_a4lc); - rmobile_init_pm_domain(&sh7372_pd_a4mp); - rmobile_init_pm_domain(&sh7372_pd_d4); - rmobile_init_pm_domain(&sh7372_pd_a4r); - rmobile_init_pm_domain(&sh7372_pd_a3rv); - rmobile_init_pm_domain(&sh7372_pd_a3ri); - rmobile_init_pm_domain(&sh7372_pd_a4s); - rmobile_init_pm_domain(&sh7372_pd_a3sp); - rmobile_init_pm_domain(&sh7372_pd_a3sg); - - pm_genpd_add_subdomain_names("A4LC", "A3RV"); - pm_genpd_add_subdomain_names("A4R", "A4LC"); - - pm_genpd_add_subdomain_names("A4S", "A3SG"); - pm_genpd_add_subdomain_names("A4S", "A3SP"); + sh7372_init_pm_domains(); platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); -- cgit v1.2.3 From 7b5674075b7c7ddb0c4da18b1f104e1db774ce82 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 7 Aug 2012 01:13:37 +0200 Subject: ARM: shmobile: Move r8a7740's PM domain objects to a table Instead of giving a name to every r8a7740's PM domain object, put them all into a table and use rmobile_init_domains(), introduced by a previous patch, for initializing them all altogether. Also, use pm_genpd_add_subdomain_names() for adding A3SP as a subdomain of A4S. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/include/mach/r8a7740.h | 6 ++-- arch/arm/mach-shmobile/pm-r8a7740.c | 42 +++++++++++++++------------ arch/arm/mach-shmobile/setup-r8a7740.c | 7 +---- 3 files changed, 28 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h index 7143147780df..59d252f4cf97 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7740.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h @@ -607,9 +607,9 @@ enum { }; #ifdef CONFIG_PM -extern struct rmobile_pm_domain r8a7740_pd_a4s; -extern struct rmobile_pm_domain r8a7740_pd_a3sp; -extern struct rmobile_pm_domain r8a7740_pd_a4lc; +extern void __init r8a7740_init_pm_domains(void); +#else +static inline void r8a7740_init_pm_domains(void) {} #endif /* CONFIG_PM */ #endif /* __ASM_R8A7740_H__ */ diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c index 893504d012a6..21e5316d2d88 100644 --- a/arch/arm/mach-shmobile/pm-r8a7740.c +++ b/arch/arm/mach-shmobile/pm-r8a7740.c @@ -21,14 +21,6 @@ static int r8a7740_pd_a4s_suspend(void) return -EBUSY; } -struct rmobile_pm_domain r8a7740_pd_a4s = { - .genpd.name = "A4S", - .bit_shift = 10, - .gov = &pm_domain_always_on_gov, - .no_debug = true, - .suspend = r8a7740_pd_a4s_suspend, -}; - static int r8a7740_pd_a3sp_suspend(void) { /* @@ -38,17 +30,31 @@ static int r8a7740_pd_a3sp_suspend(void) return console_suspend_enabled ? 0 : -EBUSY; } -struct rmobile_pm_domain r8a7740_pd_a3sp = { - .genpd.name = "A3SP", - .bit_shift = 11, - .gov = &pm_domain_always_on_gov, - .no_debug = true, - .suspend = r8a7740_pd_a3sp_suspend, +static struct rmobile_pm_domain r8a7740_pm_domains[] = { + { + .genpd.name = "A4S", + .bit_shift = 10, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = r8a7740_pd_a4s_suspend, + }, + { + .genpd.name = "A3SP", + .bit_shift = 11, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = r8a7740_pd_a3sp_suspend, + }, + { + .genpd.name = "A4LC", + .bit_shift = 1, + }, }; -struct rmobile_pm_domain r8a7740_pd_a4lc = { - .genpd.name = "A4LC", - .bit_shift = 1, -}; +void __init r8a7740_init_pm_domains(void) +{ + rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains)); + pm_genpd_add_subdomain_names("A4S", "A3SP"); +} #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index a18892d4d985..11bb1d984197 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -673,12 +673,7 @@ void __init r8a7740_add_standard_devices(void) r8a7740_i2c_workaround(&i2c0_device); r8a7740_i2c_workaround(&i2c1_device); - /* PM domain */ - rmobile_init_pm_domain(&r8a7740_pd_a4s); - rmobile_init_pm_domain(&r8a7740_pd_a3sp); - rmobile_init_pm_domain(&r8a7740_pd_a4lc); - - pm_genpd_add_subdomain_names("A4S", "A3SP"); + r8a7740_init_pm_domains(); /* add devices */ platform_add_devices(r8a7740_early_devices, -- cgit v1.2.3 From 45e5ca575647ebbca932f34a1ed915ae7a581cbb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 7 Aug 2012 01:14:14 +0200 Subject: ARM: shmobile: Move r8a7779's PM domain objects to a table Instead of giving a name to every r8a7779's PM domain object, put them all into a table and initialize them all together in a loop. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/include/mach/r8a7779.h | 9 +--- arch/arm/mach-shmobile/pm-r8a7779.c | 65 +++++++++++++++------------ arch/arm/mach-shmobile/setup-r8a7779.c | 5 +-- 3 files changed, 39 insertions(+), 40 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index e0dcef0aa4c4..7ad47977d2e7 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -347,14 +347,9 @@ extern int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch); extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch); #ifdef CONFIG_PM -extern struct r8a7779_pm_domain r8a7779_sh4a; -extern struct r8a7779_pm_domain r8a7779_sgx; -extern struct r8a7779_pm_domain r8a7779_vdp1; -extern struct r8a7779_pm_domain r8a7779_impx3; - -extern void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd); +extern void __init r8a7779_init_pm_domains(void); #else -#define r8a7779_init_pm_domain(pd) do { } while (0) +static inline void r8a7779_init_pm_domains(void) {} #endif /* CONFIG_PM */ #endif /* __ASM_R8A7779_H__ */ diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c index b2a98cca66d3..d50a8e9b94a4 100644 --- a/arch/arm/mach-shmobile/pm-r8a7779.c +++ b/arch/arm/mach-shmobile/pm-r8a7779.c @@ -183,7 +183,7 @@ static bool pd_active_wakeup(struct device *dev) return true; } -void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd) +static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd) { struct generic_pm_domain *genpd = &r8a7779_pd->genpd; @@ -199,37 +199,44 @@ void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd) pd_power_up(&r8a7779_pd->genpd); } -struct r8a7779_pm_domain r8a7779_sh4a = { - .genpd.name = "SH4A", - .ch = { - .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */ - .isr_bit = 16, /* SH4A */ - } +static struct r8a7779_pm_domain r8a7779_pm_domains[] = { + { + .genpd.name = "SH4A", + .ch = { + .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */ + .isr_bit = 16, /* SH4A */ + }, + }, + { + .genpd.name = "SGX", + .ch = { + .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */ + .isr_bit = 20, /* SGX */ + }, + }, + { + .genpd.name = "VDP1", + .ch = { + .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */ + .isr_bit = 21, /* VDP */ + }, + }, + { + .genpd.name = "IMPX3", + .ch = { + .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */ + .isr_bit = 24, /* IMP */ + }, + }, }; -struct r8a7779_pm_domain r8a7779_sgx = { - .genpd.name = "SGX", - .ch = { - .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */ - .isr_bit = 20, /* SGX */ - } -}; - -struct r8a7779_pm_domain r8a7779_vdp1 = { - .genpd.name = "VDP1", - .ch = { - .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */ - .isr_bit = 21, /* VDP */ - } -}; +void __init r8a7779_init_pm_domains(void) +{ + int j; -struct r8a7779_pm_domain r8a7779_impx3 = { - .genpd.name = "IMPX3", - .ch = { - .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */ - .isr_bit = 24, /* IMP */ - } -}; + for (j = 0; j < ARRAY_SIZE(r8a7779_pm_domains); j++) + r8a7779_init_pm_domain(&r8a7779_pm_domains[j]); +} #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index e98e46f6cf55..2917668f0091 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -251,10 +251,7 @@ void __init r8a7779_add_standard_devices(void) #endif r8a7779_pm_init(); - r8a7779_init_pm_domain(&r8a7779_sh4a); - r8a7779_init_pm_domain(&r8a7779_sgx); - r8a7779_init_pm_domain(&r8a7779_vdp1); - r8a7779_init_pm_domain(&r8a7779_impx3); + r8a7779_init_pm_domains(); platform_add_devices(r8a7779_early_devices, ARRAY_SIZE(r8a7779_early_devices)); -- cgit v1.2.3 From a62595d359ba8ca0f25b93c06eab84ba97ca516f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 7 Aug 2012 01:15:02 +0200 Subject: ARM: shmobile: Make rmobile_init_pm_domain() static Since rmobile_init_pm_domain() is not called anywhere outside of arch/arm/mach-shmobile/pm-rmobile.c any more, it can be made static and its header may be removed from pm-rmobile.h. Modify the code accordingly. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/include/mach/pm-rmobile.h | 2 -- arch/arm/mach-shmobile/pm-rmobile.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h index 4c264c74760f..7fd9ad1fefe4 100644 --- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h +++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h @@ -30,12 +30,10 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d) } #ifdef CONFIG_PM -extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd); extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num); extern void rmobile_add_device_to_domain(const char *domain_name, struct platform_device *pdev); #else -#define rmobile_init_pm_domain(pd) do { } while (0) #define rmobile_init_domains(domains, num) do { } while (0) #define rmobile_add_device_to_domain(name, pdev) do { } while (0) #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 4b6f2ea3169f..63f35665df31 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -134,7 +134,7 @@ static int rmobile_pd_start_dev(struct device *dev) return ret; } -void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) +static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) { struct generic_pm_domain *genpd = &rmobile_pd->genpd; struct dev_power_governor *gov = rmobile_pd->gov; -- cgit v1.2.3 From 8ae28ecb8726db5904f0f703f100315377b0172b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 8 Aug 2012 00:27:10 +0200 Subject: ARM: shmobile: Set PM domain on/off latencies directly The results of adaptive latency computations in __pm_genpd_poweron() and pm_genpd_poweroff() show that the power on/power off latencies of all power domains in SH7372 are a little below 250 us. Therefore, if 250 us is used as the common initial value of the latency fields in struct generic_pm_domain for all domains, the latency values will never have to change at run time and there won't be any overhead related to re-computation of the corresponding PM QoS data. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/pm-sh7372.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 0d722b5b5219..9d055a9f27c8 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -71,6 +71,8 @@ #ifdef CONFIG_PM +#define PM_DOMAIN_ON_OFF_LATENCY_NS 250000 + static int sh7372_a4r_pd_suspend(void) { sh7372_intcs_suspend(); @@ -110,32 +112,46 @@ static int sh7372_a3sp_pd_suspend(void) static struct rmobile_pm_domain sh7372_pm_domains[] = { { .genpd.name = "A4LC", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 1, }, { .genpd.name = "A4MP", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 2, }, { .genpd.name = "D4", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 3, }, { .genpd.name = "A4R", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 5, .suspend = sh7372_a4r_pd_suspend, .resume = sh7372_intcs_resume, }, { .genpd.name = "A3RV", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 6, }, { .genpd.name = "A3RI", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 8, }, { .genpd.name = "A4S", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 10, .gov = &pm_domain_always_on_gov, .no_debug = true, @@ -144,6 +160,8 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = { }, { .genpd.name = "A3SP", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 11, .gov = &pm_domain_always_on_gov, .no_debug = true, @@ -151,6 +169,8 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = { }, { .genpd.name = "A3SG", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, .bit_shift = 13, }, }; -- cgit v1.2.3 From 455ae3a5d4191e60f50cd9faf72f9dc9f233242d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 8 Aug 2012 00:27:52 +0200 Subject: ARM: shmobile: Allow device latencies to be specified directly Make it possible to specify device start/stop and save/restore state latencies directy when adding devices to PM domains. For this purpose, introduce rmobile_add_device_to_domain_td() whose third argument is a pointer to a struct gpd_timing_data object containing device latency data. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/include/mach/pm-rmobile.h | 14 ++++++++++++-- arch/arm/mach-shmobile/pm-rmobile.c | 7 ++++--- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h index 7fd9ad1fefe4..4d02f7488dde 100644 --- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h +++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h @@ -31,10 +31,20 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d) #ifdef CONFIG_PM extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num); -extern void rmobile_add_device_to_domain(const char *domain_name, - struct platform_device *pdev); +extern void rmobile_add_device_to_domain_td(const char *domain_name, + struct platform_device *pdev, + struct gpd_timing_data *td); + +static inline void rmobile_add_device_to_domain(const char *domain_name, + struct platform_device *pdev) +{ + rmobile_add_device_to_domain_td(domain_name, pdev, NULL); +} + #else + #define rmobile_init_domains(domains, num) do { } while (0) +#define rmobile_add_device_to_domain_td(name, pdev, td) do { } while (0) #define rmobile_add_device_to_domain(name, pdev) do { } while (0) #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 63f35665df31..682575a2243c 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -157,12 +157,13 @@ void rmobile_init_domains(struct rmobile_pm_domain domains[], int num) rmobile_init_pm_domain(&domains[j]); } -void rmobile_add_device_to_domain(const char *domain_name, - struct platform_device *pdev) +void rmobile_add_device_to_domain_td(const char *domain_name, + struct platform_device *pdev, + struct gpd_timing_data *td) { struct device *dev = &pdev->dev; - pm_genpd_name_add_device(domain_name, dev); + __pm_genpd_name_add_device(domain_name, dev, td); if (pm_clk_no_clocks(dev)) pm_clk_add(dev, NULL); } -- cgit v1.2.3 From c37b7a7b3454ea6e6b457ab458c694fe4d81cf9e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 8 Aug 2012 00:28:36 +0200 Subject: ARM: shmobile: Specify device latencies for SH7372 devices directly The results of adaptive latency computations in GENPD_DEV_TIMED_CALLBACK() show that the start/stop and save/restore state latencies of all devices on SH7372 I have tried are a little below 250 us. Therefore, if the 250 us is used as the common initial value of the latency fields in struct gpd_timing_data for all devices on SH7372, the latency values will never have to change at run time and there won't be any overhead related to re-computation of the corresponding PM QoS data. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/setup-sh7372.c | 57 ++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index c1f698f2b469..5bcde8a79c53 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -999,8 +999,17 @@ static struct platform_device *sh7372_late_devices[] __initdata = { &spu1_device, }; +#define DEV_LATENCY_NS 250000 + void __init sh7372_add_standard_devices(void) { + struct gpd_timing_data latencies = { + .stop_latency_ns = DEV_LATENCY_NS, + .start_latency_ns = DEV_LATENCY_NS, + .save_state_latency_ns = DEV_LATENCY_NS, + .restore_state_latency_ns = DEV_LATENCY_NS, + }; + sh7372_init_pm_domains(); platform_add_devices(sh7372_early_devices, @@ -1009,30 +1018,30 @@ void __init sh7372_add_standard_devices(void) platform_add_devices(sh7372_late_devices, ARRAY_SIZE(sh7372_late_devices)); - rmobile_add_device_to_domain("A3RV", &vpu_device); - rmobile_add_device_to_domain("A4MP", &spu0_device); - rmobile_add_device_to_domain("A4MP", &spu1_device); - rmobile_add_device_to_domain("A3SP", &scif0_device); - rmobile_add_device_to_domain("A3SP", &scif1_device); - rmobile_add_device_to_domain("A3SP", &scif2_device); - rmobile_add_device_to_domain("A3SP", &scif3_device); - rmobile_add_device_to_domain("A3SP", &scif4_device); - rmobile_add_device_to_domain("A3SP", &scif5_device); - rmobile_add_device_to_domain("A3SP", &scif6_device); - rmobile_add_device_to_domain("A3SP", &iic1_device); - rmobile_add_device_to_domain("A3SP", &dma0_device); - rmobile_add_device_to_domain("A3SP", &dma1_device); - rmobile_add_device_to_domain("A3SP", &dma2_device); - rmobile_add_device_to_domain("A3SP", &usb_dma0_device); - rmobile_add_device_to_domain("A3SP", &usb_dma1_device); - rmobile_add_device_to_domain("A4R", &iic0_device); - rmobile_add_device_to_domain("A4R", &veu0_device); - rmobile_add_device_to_domain("A4R", &veu1_device); - rmobile_add_device_to_domain("A4R", &veu2_device); - rmobile_add_device_to_domain("A4R", &veu3_device); - rmobile_add_device_to_domain("A4R", &jpu_device); - rmobile_add_device_to_domain("A4R", &tmu00_device); - rmobile_add_device_to_domain("A4R", &tmu01_device); + rmobile_add_device_to_domain_td("A3RV", &vpu_device, &latencies); + rmobile_add_device_to_domain_td("A4MP", &spu0_device, &latencies); + rmobile_add_device_to_domain_td("A4MP", &spu1_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &scif0_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &scif1_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &scif2_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &scif3_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &scif4_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &scif5_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &scif6_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &iic1_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &dma0_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &dma1_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &dma2_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &usb_dma0_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &usb_dma1_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &iic0_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &veu0_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &veu1_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &veu2_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &veu3_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &jpu_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &tmu00_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &tmu01_device, &latencies); } static void __init sh7372_earlytimer_init(void) -- cgit v1.2.3 From b42879e2e9b130e9ea0df3f076a0742df46e143a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 8 Aug 2012 00:29:16 +0200 Subject: ARM: shmobile: Specify device latencies for Mackerel devices directly The results of adaptive latency computations in GENPD_DEV_TIMED_CALLBACK() show that the start/stop and save/restore state latencies of all devices on the Mackerel board I have tried are a little below 250 us. Therefore, if the 250 us is used as the common initial value of the latency fields in struct gpd_timing_data for all devices on Mackerel, the latency values will never have to change at run time and there won't be any overhead related to re-computation of the corresponding PM QoS data. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/board-mackerel.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 954b02e3bb18..c64fc40351da 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1407,8 +1407,15 @@ static struct i2c_board_info i2c1_devices[] = { #define GPIO_PORT168CR 0xE60520A8 #define SRCR4 0xe61580bc #define USCCR1 0xE6058144 +#define DEV_LATENCY_NS 250000 static void __init mackerel_init(void) { + struct gpd_timing_data latencies = { + .stop_latency_ns = DEV_LATENCY_NS, + .start_latency_ns = DEV_LATENCY_NS, + .save_state_latency_ns = DEV_LATENCY_NS, + .restore_state_latency_ns = DEV_LATENCY_NS, + }; u32 srcr4; struct clk *clk; @@ -1623,20 +1630,20 @@ static void __init mackerel_init(void) platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); - rmobile_add_device_to_domain("A4LC", &lcdc_device); - rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device); - rmobile_add_device_to_domain("A4LC", &meram_device); - rmobile_add_device_to_domain("A4MP", &fsi_device); - rmobile_add_device_to_domain("A3SP", &usbhs0_device); - rmobile_add_device_to_domain("A3SP", &usbhs1_device); - rmobile_add_device_to_domain("A3SP", &nand_flash_device); - rmobile_add_device_to_domain("A3SP", &sh_mmcif_device); - rmobile_add_device_to_domain("A3SP", &sdhi0_device); + rmobile_add_device_to_domain_td("A4LC", &lcdc_device, &latencies); + rmobile_add_device_to_domain_td("A4LC", &hdmi_lcdc_device, &latencies); + rmobile_add_device_to_domain_td("A4LC", &meram_device, &latencies); + rmobile_add_device_to_domain_td("A4MP", &fsi_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &usbhs0_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &usbhs1_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &nand_flash_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &sh_mmcif_device, &latencies); + rmobile_add_device_to_domain_td("A3SP", &sdhi0_device, &latencies); #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) - rmobile_add_device_to_domain("A3SP", &sdhi1_device); + rmobile_add_device_to_domain_td("A3SP", &sdhi1_device, &latencies); #endif - rmobile_add_device_to_domain("A3SP", &sdhi2_device); - rmobile_add_device_to_domain("A4R", &ceu_device); + rmobile_add_device_to_domain_td("A3SP", &sdhi2_device, &latencies); + rmobile_add_device_to_domain_td("A4R", &ceu_device, &latencies); hdmi_init_pm_clock(); sh7372_pm_init(); -- cgit v1.2.3 From ac18e02dc022a5413219f41d000bc637c7c5d957 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Aug 2012 20:56:26 +0200 Subject: ARM: shmobile: Rework adding devices to PM domains on Mackerel On SH7372 and Mackerel devices are added to PM domains through a series of rmobile_add_device_to_domain_td() calls where the last argument is always the same. This is quite inefficient, so add a common function for adding devices to PM domains that reads the domain-device pairs information from a table and use it during SH7372 and Mackerel initialization. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/board-mackerel.c | 37 +++++++-------- arch/arm/mach-shmobile/include/mach/pm-rmobile.h | 12 +++++ arch/arm/mach-shmobile/pm-rmobile.c | 16 +++++++ arch/arm/mach-shmobile/setup-sh7372.c | 58 +++++++++++------------- 4 files changed, 72 insertions(+), 51 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index c64fc40351da..d1e8fe83588c 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1407,14 +1407,23 @@ static struct i2c_board_info i2c1_devices[] = { #define GPIO_PORT168CR 0xE60520A8 #define SRCR4 0xe61580bc #define USCCR1 0xE6058144 -#define DEV_LATENCY_NS 250000 static void __init mackerel_init(void) { - struct gpd_timing_data latencies = { - .stop_latency_ns = DEV_LATENCY_NS, - .start_latency_ns = DEV_LATENCY_NS, - .save_state_latency_ns = DEV_LATENCY_NS, - .restore_state_latency_ns = DEV_LATENCY_NS, + struct pm_domain_device domain_devices[] = { + { "A4LC", &lcdc_device, }, + { "A4LC", &hdmi_lcdc_device, }, + { "A4LC", &meram_device, }, + { "A4MP", &fsi_device, }, + { "A3SP", &usbhs0_device, }, + { "A3SP", &usbhs1_device, }, + { "A3SP", &nand_flash_device, }, + { "A3SP", &sh_mmcif_device, }, + { "A3SP", &sdhi0_device, }, +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) + { "A3SP", &sdhi1_device, }, +#endif + { "A3SP", &sdhi2_device, }, + { "A4R", &ceu_device, }, }; u32 srcr4; struct clk *clk; @@ -1630,20 +1639,8 @@ static void __init mackerel_init(void) platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); - rmobile_add_device_to_domain_td("A4LC", &lcdc_device, &latencies); - rmobile_add_device_to_domain_td("A4LC", &hdmi_lcdc_device, &latencies); - rmobile_add_device_to_domain_td("A4LC", &meram_device, &latencies); - rmobile_add_device_to_domain_td("A4MP", &fsi_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &usbhs0_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &usbhs1_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &nand_flash_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &sh_mmcif_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &sdhi0_device, &latencies); -#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) - rmobile_add_device_to_domain_td("A3SP", &sdhi1_device, &latencies); -#endif - rmobile_add_device_to_domain_td("A3SP", &sdhi2_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &ceu_device, &latencies); + rmobile_add_devices_to_domains(domain_devices, + ARRAY_SIZE(domain_devices)); hdmi_init_pm_clock(); sh7372_pm_init(); diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h index 4d02f7488dde..690553a06887 100644 --- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h +++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h @@ -12,6 +12,8 @@ #include +#define DEFAULT_DEV_LATENCY_NS 250000 + struct platform_device; struct rmobile_pm_domain { @@ -29,6 +31,11 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d) return container_of(d, struct rmobile_pm_domain, genpd); } +struct pm_domain_device { + const char *domain_name; + struct platform_device *pdev; +}; + #ifdef CONFIG_PM extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num); extern void rmobile_add_device_to_domain_td(const char *domain_name, @@ -41,11 +48,16 @@ static inline void rmobile_add_device_to_domain(const char *domain_name, rmobile_add_device_to_domain_td(domain_name, pdev, NULL); } +extern void rmobile_add_devices_to_domains(struct pm_domain_device data[], + int size); #else #define rmobile_init_domains(domains, num) do { } while (0) #define rmobile_add_device_to_domain_td(name, pdev, td) do { } while (0) #define rmobile_add_device_to_domain(name, pdev) do { } while (0) + +static inline void rmobile_add_devices_to_domains(struct pm_domain_device d[], + int size) {} #endif /* CONFIG_PM */ #endif /* PM_RMOBILE_H */ diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 682575a2243c..d37d368434da 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -167,4 +167,20 @@ void rmobile_add_device_to_domain_td(const char *domain_name, if (pm_clk_no_clocks(dev)) pm_clk_add(dev, NULL); } + +void rmobile_add_devices_to_domains(struct pm_domain_device data[], + int size) +{ + struct gpd_timing_data latencies = { + .stop_latency_ns = DEFAULT_DEV_LATENCY_NS, + .start_latency_ns = DEFAULT_DEV_LATENCY_NS, + .save_state_latency_ns = DEFAULT_DEV_LATENCY_NS, + .restore_state_latency_ns = DEFAULT_DEV_LATENCY_NS, + }; + int j; + + for (j = 0; j < size; j++) + rmobile_add_device_to_domain_td(data[j].domain_name, + data[j].pdev, &latencies); +} #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 5bcde8a79c53..a07954fbcd22 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -999,15 +999,33 @@ static struct platform_device *sh7372_late_devices[] __initdata = { &spu1_device, }; -#define DEV_LATENCY_NS 250000 - void __init sh7372_add_standard_devices(void) { - struct gpd_timing_data latencies = { - .stop_latency_ns = DEV_LATENCY_NS, - .start_latency_ns = DEV_LATENCY_NS, - .save_state_latency_ns = DEV_LATENCY_NS, - .restore_state_latency_ns = DEV_LATENCY_NS, + struct pm_domain_device domain_devices[] = { + { "A3RV", &vpu_device, }, + { "A4MP", &spu0_device, }, + { "A4MP", &spu1_device, }, + { "A3SP", &scif0_device, }, + { "A3SP", &scif1_device, }, + { "A3SP", &scif2_device, }, + { "A3SP", &scif3_device, }, + { "A3SP", &scif4_device, }, + { "A3SP", &scif5_device, }, + { "A3SP", &scif6_device, }, + { "A3SP", &iic1_device, }, + { "A3SP", &dma0_device, }, + { "A3SP", &dma1_device, }, + { "A3SP", &dma2_device, }, + { "A3SP", &usb_dma0_device, }, + { "A3SP", &usb_dma1_device, }, + { "A4R", &iic0_device, }, + { "A4R", &veu0_device, }, + { "A4R", &veu1_device, }, + { "A4R", &veu2_device, }, + { "A4R", &veu3_device, }, + { "A4R", &jpu_device, }, + { "A4R", &tmu00_device, }, + { "A4R", &tmu01_device, }, }; sh7372_init_pm_domains(); @@ -1018,30 +1036,8 @@ void __init sh7372_add_standard_devices(void) platform_add_devices(sh7372_late_devices, ARRAY_SIZE(sh7372_late_devices)); - rmobile_add_device_to_domain_td("A3RV", &vpu_device, &latencies); - rmobile_add_device_to_domain_td("A4MP", &spu0_device, &latencies); - rmobile_add_device_to_domain_td("A4MP", &spu1_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &scif0_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &scif1_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &scif2_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &scif3_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &scif4_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &scif5_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &scif6_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &iic1_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &dma0_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &dma1_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &dma2_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &usb_dma0_device, &latencies); - rmobile_add_device_to_domain_td("A3SP", &usb_dma1_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &iic0_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &veu0_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &veu1_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &veu2_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &veu3_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &jpu_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &tmu00_device, &latencies); - rmobile_add_device_to_domain_td("A4R", &tmu01_device, &latencies); + rmobile_add_devices_to_domains(domain_devices, + ARRAY_SIZE(domain_devices)); } static void __init sh7372_earlytimer_init(void) -- cgit v1.2.3 From 201dbd8110164d817e73c5602dd4d358d7fc535a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Aug 2012 20:56:41 +0200 Subject: ARM: shmobile: Rework adding devices to PM domains on AP4EVB Use the function rmobile_add_devices_to_domains() introduced previously for adding devices to PM domains during the AP4EVB initialization instead of a series of rmobile_add_device_to_domain*() calls. This also causes the default device PM QoS latencies to be used on that board in analogy with Mackerel. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/board-ap4evb.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index b85957ad948b..5168a0338cf4 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -1229,6 +1229,15 @@ static struct i2c_board_info i2c1_devices[] = { #define USCCR1 0xE6058144 static void __init ap4evb_init(void) { + struct pm_domain_device domain_devices[] = { + { "A4LC", &lcdc1_device, }, + { "A4LC", &lcdc_device, }, + { "A4MP", &fsi_device, }, + { "A3SP", &sh_mmcif_device, }, + { "A3SP", &sdhi0_device, }, + { "A3SP", &sdhi1_device, }, + { "A4R", &ceu_device, }, + }; u32 srcr4; struct clk *clk; @@ -1461,14 +1470,8 @@ static void __init ap4evb_init(void) platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); - rmobile_add_device_to_domain("A4LC", &lcdc1_device); - rmobile_add_device_to_domain("A4LC", &lcdc_device); - rmobile_add_device_to_domain("A4MP", &fsi_device); - - rmobile_add_device_to_domain("A3SP", &sh_mmcif_device); - rmobile_add_device_to_domain("A3SP", &sdhi0_device); - rmobile_add_device_to_domain("A3SP", &sdhi1_device); - rmobile_add_device_to_domain("A4R", &ceu_device); + rmobile_add_devices_to_domains(domain_devices, + ARRAY_SIZE(domain_devices)); hdmi_init_pm_clock(); fsi_init_pm_clock(); -- cgit v1.2.3 From 18c081e27666c5db33075bf7ae4694e091cf1d20 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Aug 2012 20:57:06 +0200 Subject: ARM: shmobile: Remove the console check from sh7372_enter_suspend() The !console_suspend_enabled check in sh7372_enter_suspend() seems to be reversed and the condition it is supposed to catch (console clock enabled) should be detected by the sh7372_sysc_valid() check anyway, so remove it. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/pm-sh7372.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 9d055a9f27c8..d01122c0d9be 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -424,16 +424,14 @@ static int sh7372_enter_suspend(suspend_state_t suspend_state) unsigned long msk, msk2; /* check active clocks to determine potential wakeup sources */ - if (sh7372_sysc_valid(&msk, &msk2)) { - if (!console_suspend_enabled && a4s_suspend_ready) { - /* convert INTC mask/sense to SYSC mask/sense */ - sh7372_setup_sysc(msk, msk2); - - /* enter A4S sleep with PLLC0 off */ - pr_debug("entering A4S\n"); - sh7372_enter_a4s_common(0); - return 0; - } + if (sh7372_sysc_valid(&msk, &msk2) && a4s_suspend_ready) { + /* convert INTC mask/sense to SYSC mask/sense */ + sh7372_setup_sysc(msk, msk2); + + /* enter A4S sleep with PLLC0 off */ + pr_debug("entering A4S\n"); + sh7372_enter_a4s_common(0); + return 0; } /* default to enter A3SM sleep with PLLC0 off */ -- cgit v1.2.3 From 35f2b0bd5911dc0eef3f5352b6acb79c69420111 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Aug 2012 20:57:27 +0200 Subject: ARM: shmobile: Move definition of shmobile_init_late() to header The role of the only function in the common.c file in arch/arm/mach-shmobile, shmobile_init_late(), is to call two initializers whose definitions depend on kernel configuration options. Those initializers may very well be called from a static inline function in arm/mach-shmobile/include/mach/common.h, though, in which makes the code a bit easier to read. Moreover, the common.c may be dropped entirely then. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/Makefile | 2 +- arch/arm/mach-shmobile/common.c | 24 ------------------------ arch/arm/mach-shmobile/include/mach/common.h | 8 ++++++-- 3 files changed, 7 insertions(+), 27 deletions(-) delete mode 100644 arch/arm/mach-shmobile/common.c (limited to 'arch') diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 0df5ae6740c6..fe2c97c179d1 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -3,7 +3,7 @@ # # Common objects -obj-y := timer.o console.o clock.o common.o +obj-y := timer.o console.o clock.o # CPU objects obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o diff --git a/arch/arm/mach-shmobile/common.c b/arch/arm/mach-shmobile/common.c deleted file mode 100644 index 608aba9d60d7..000000000000 --- a/arch/arm/mach-shmobile/common.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#include -#include -#include - -void __init shmobile_init_late(void) -{ - shmobile_suspend_init(); - shmobile_cpuidle_init(); -} diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 45e61dada030..9175c183ba7a 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -86,8 +86,6 @@ extern int r8a7779_boot_secondary(unsigned int cpu); extern void r8a7779_smp_prepare_cpus(void); extern void r8a7779_register_twd(void); -extern void shmobile_init_late(void); - #ifdef CONFIG_SUSPEND int shmobile_suspend_init(void); #else @@ -100,4 +98,10 @@ int shmobile_cpuidle_init(void); static inline int shmobile_cpuidle_init(void) { return 0; } #endif +static inline void shmobile_init_late(void) +{ + shmobile_suspend_init(); + shmobile_cpuidle_init(); +} + #endif /* __ARCH_MACH_COMMON_H */ -- cgit v1.2.3 From 5b41147ceae44350f43f9b8124687d22bed2bbb9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Aug 2012 20:58:19 +0200 Subject: ARM: shmobile: Make sh7372 cpuidle handling more straightforward The sh7372 cpuidle code uses the same artificially designed routine shmobile_cpuidle_enter() as the .enter() callback for all of its cpuidle states. However, shmobile_cpuidle_enter() calls a different "enter" function for each state using an array of function pointers populated by the sh7372 PM initialization code. Moreover, the states[] array of the shmobile cpuidle driver is populated by that code as well, although in principle it just might have been filled with static data. All of that complexity goes away if the sh7372 cpuidle code is allowed to define its own cpuidle driver structure that can be passed for registration to the common shmobile cpuidle initialization routine, so modify the code accordingly. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/cpuidle.c | 39 +++++--------- arch/arm/mach-shmobile/include/mach/common.h | 6 ++- arch/arm/mach-shmobile/pm-sh7372.c | 79 ++++++++++++++++------------ 3 files changed, 62 insertions(+), 62 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c index 7b541e911ab4..9e050268cde4 100644 --- a/arch/arm/mach-shmobile/cpuidle.c +++ b/arch/arm/mach-shmobile/cpuidle.c @@ -16,51 +16,38 @@ #include #include -static void shmobile_enter_wfi(void) +int shmobile_enter_wfi(struct cpuidle_device *dev, struct cpuidle_driver *drv, + int index) { cpu_do_idle(); -} - -void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = { - shmobile_enter_wfi, /* regular sleep mode */ -}; - -static int shmobile_cpuidle_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - shmobile_cpuidle_modes[index](); - - return index; + return 0; } static struct cpuidle_device shmobile_cpuidle_dev; -static struct cpuidle_driver shmobile_cpuidle_driver = { +static struct cpuidle_driver shmobile_cpuidle_default_driver = { .name = "shmobile_cpuidle", .owner = THIS_MODULE, .en_core_tk_irqen = 1, .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[0].enter = shmobile_enter_wfi, .safe_state_index = 0, /* C1 */ .state_count = 1, }; -void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); +static struct cpuidle_driver *cpuidle_drv = &shmobile_cpuidle_default_driver; + +void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv) +{ + cpuidle_drv = drv; +} int shmobile_cpuidle_init(void) { struct cpuidle_device *dev = &shmobile_cpuidle_dev; - struct cpuidle_driver *drv = &shmobile_cpuidle_driver; - int i; - - for (i = 0; i < CPUIDLE_STATE_MAX; i++) - drv->states[i].enter = shmobile_cpuidle_enter; - - if (shmobile_cpuidle_setup) - shmobile_cpuidle_setup(drv); - cpuidle_register_driver(drv); + cpuidle_register_driver(cpuidle_drv); - dev->state_count = drv->state_count; + dev->state_count = cpuidle_drv->state_count; cpuidle_register_device(dev); return 0; diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 9175c183ba7a..eb89293fff4d 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -14,8 +14,10 @@ extern int shmobile_clk_init(void); extern void shmobile_handle_irq_intc(struct pt_regs *); extern struct platform_suspend_ops shmobile_suspend_ops; struct cpuidle_driver; -extern void (*shmobile_cpuidle_modes[])(void); -extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); +struct cpuidle_device; +extern int shmobile_enter_wfi(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index); +extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv); extern void sh7367_init_irq(void); extern void sh7367_map_io(void); diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index d01122c0d9be..5cafd35cc411 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -347,7 +348,8 @@ static int sh7372_do_idle_core_standby(unsigned long unused) return 0; } -static void sh7372_enter_core_standby(void) +static int sh7372_enter_core_standby(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); @@ -358,52 +360,61 @@ static void sh7372_enter_core_standby(void) /* disable reset vector translation */ __raw_writel(0, SBAR); + + return 1; } -static void sh7372_enter_a3sm_pll_on(void) +static int sh7372_enter_a3sm_pll_on(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { sh7372_enter_a3sm_common(1); + return 2; } -static void sh7372_enter_a3sm_pll_off(void) +static int sh7372_enter_a3sm_pll_off(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { sh7372_enter_a3sm_common(0); + return 3; } -static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) -{ - struct cpuidle_state *state = &drv->states[drv->state_count]; - - snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); - strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN); - state->exit_latency = 10; - state->target_residency = 20 + 10; - state->flags = CPUIDLE_FLAG_TIME_VALID; - shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby; - drv->state_count++; - - state = &drv->states[drv->state_count]; - snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); - strncpy(state->desc, "A3SM PLL ON", CPUIDLE_DESC_LEN); - state->exit_latency = 20; - state->target_residency = 30 + 20; - state->flags = CPUIDLE_FLAG_TIME_VALID; - shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_on; - drv->state_count++; - - state = &drv->states[drv->state_count]; - snprintf(state->name, CPUIDLE_NAME_LEN, "C4"); - strncpy(state->desc, "A3SM PLL OFF", CPUIDLE_DESC_LEN); - state->exit_latency = 120; - state->target_residency = 30 + 120; - state->flags = CPUIDLE_FLAG_TIME_VALID; - shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_off; - drv->state_count++; -} +static struct cpuidle_driver sh7372_cpuidle_driver = { + .name = "sh7372_cpuidle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .state_count = 4, + .safe_state_index = 0, /* C1 */ + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[0].enter = shmobile_enter_wfi, + .states[1] = { + .name = "C2", + .desc = "Core Standby Mode", + .exit_latency = 10, + .target_residency = 20 + 10, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = sh7372_enter_core_standby, + }, + .states[2] = { + .name = "C3", + .desc = "A3SM PLL ON", + .exit_latency = 20, + .target_residency = 30 + 20, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = sh7372_enter_a3sm_pll_on, + }, + .states[3] = { + .name = "C4", + .desc = "A3SM PLL OFF", + .exit_latency = 120, + .target_residency = 30 + 120, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = sh7372_enter_a3sm_pll_off, + }, +}; static void sh7372_cpuidle_init(void) { - shmobile_cpuidle_setup = sh7372_cpuidle_setup; + shmobile_cpuidle_set_driver(&sh7372_cpuidle_driver); } #else static void sh7372_cpuidle_init(void) {} -- cgit v1.2.3 From caaca999d335872a53b3fff8fa5af2de794d16a1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 22 Aug 2012 12:27:24 +0200 Subject: ARM: shmobile: Add A4S cpuidle state on sh7372 Add a "C5" cpuidle state to the SH7372 SoC connected to the A4S power domain in such a way that A4S may be turned off by cpuidle if all I/O devices in that domain have been suspended (or do not have attached drivers). This requires some reorganization of the initialization of SH7372 power management which affects the the boards based on it, Mackerel and AP4EVB. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- arch/arm/mach-shmobile/board-ap4evb.c | 2 +- arch/arm/mach-shmobile/board-mackerel.c | 2 +- arch/arm/mach-shmobile/include/mach/sh7372.h | 2 + arch/arm/mach-shmobile/pm-sh7372.c | 56 +++++++++++++++++++++++----- 4 files changed, 50 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 5168a0338cf4..264340a60f65 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -1486,6 +1486,6 @@ MACHINE_START(AP4EVB, "ap4evb") .init_irq = sh7372_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = ap4evb_init, - .init_late = shmobile_init_late, + .init_late = sh7372_pm_init_late, .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index d1e8fe83588c..f96e41557d65 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1654,6 +1654,6 @@ MACHINE_START(MACKEREL, "mackerel") .init_irq = sh7372_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = mackerel_init, - .init_late = shmobile_init_late, + .init_late = sh7372_pm_init_late, .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index 40beb796d020..eb98b45c5089 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -489,4 +489,6 @@ extern void __init sh7372_init_pm_domains(void); static inline void sh7372_init_pm_domains(void) {} #endif +extern void __init sh7372_pm_init_late(void); + #endif /* __ASM_SH7372_H__ */ diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 5cafd35cc411..a7a5e20ae9a0 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -339,6 +339,21 @@ static void sh7372_enter_a3sm_common(int pllc0_on) sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); sh7372_enter_sysc(pllc0_on, 1 << 12); } + +static void sh7372_enter_a4s_common(int pllc0_on) +{ + sh7372_intca_suspend(); + sh7372_set_reset_vector(SMFRAM); + sh7372_enter_sysc(pllc0_on, 1 << 10); + sh7372_intca_resume(); +} + +static void sh7372_pm_setup_smfram(void) +{ + memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); +} +#else +static inline void sh7372_pm_setup_smfram(void) {} #endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */ #ifdef CONFIG_CPU_IDLE @@ -378,11 +393,24 @@ static int sh7372_enter_a3sm_pll_off(struct cpuidle_device *dev, return 3; } +static int sh7372_enter_a4s(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + unsigned long msk, msk2; + + if (!sh7372_sysc_valid(&msk, &msk2)) + return sh7372_enter_a3sm_pll_off(dev, drv, index); + + sh7372_setup_sysc(msk, msk2); + sh7372_enter_a4s_common(0); + return 4; +} + static struct cpuidle_driver sh7372_cpuidle_driver = { .name = "sh7372_cpuidle", .owner = THIS_MODULE, .en_core_tk_irqen = 1, - .state_count = 4, + .state_count = 5, .safe_state_index = 0, /* C1 */ .states[0] = ARM_CPUIDLE_WFI_STATE, .states[0].enter = shmobile_enter_wfi, @@ -410,6 +438,15 @@ static struct cpuidle_driver sh7372_cpuidle_driver = { .flags = CPUIDLE_FLAG_TIME_VALID, .enter = sh7372_enter_a3sm_pll_off, }, + .states[4] = { + .name = "C5", + .desc = "A4S PLL OFF", + .exit_latency = 240, + .target_residency = 30 + 240, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = sh7372_enter_a4s, + .disabled = true, + }, }; static void sh7372_cpuidle_init(void) @@ -421,15 +458,6 @@ static void sh7372_cpuidle_init(void) {} #endif #ifdef CONFIG_SUSPEND -static void sh7372_enter_a4s_common(int pllc0_on) -{ - sh7372_intca_suspend(); - memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); - sh7372_set_reset_vector(SMFRAM); - sh7372_enter_sysc(pllc0_on, 1 << 10); - sh7372_intca_resume(); -} - static int sh7372_enter_suspend(suspend_state_t suspend_state) { unsigned long msk, msk2; @@ -497,6 +525,14 @@ void __init sh7372_pm_init(void) /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */ __raw_writel(0, PDNSEL); + sh7372_pm_setup_smfram(); + sh7372_suspend_init(); sh7372_cpuidle_init(); } + +void __init sh7372_pm_init_late(void) +{ + shmobile_init_late(); + pm_genpd_name_attach_cpuidle("A4S", 4); +} -- cgit v1.2.3 From 3dc9a633f8a65b39c5897874138027328bfb0a94 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 4 Sep 2012 08:28:02 +0000 Subject: acpi-cpufreq: Add support for modern AMD CPUs The programming model for P-states on modern AMD CPUs is very similar to that of Intel and VIA. It makes sense to consolidate this support into one driver rather than duplicating functionality between two of them. This patch adds support for AMDs with hardware P-state control to acpi-cpufreq. Signed-off-by: Matthew Garrett Signed-off-by: Andre Przywara Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/msr-index.h | 2 ++ drivers/cpufreq/Kconfig.x86 | 3 ++- drivers/cpufreq/acpi-cpufreq.c | 43 ++++++++++++++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 957ec87385af..1e1f3eb58638 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -248,6 +248,8 @@ #define MSR_IA32_PERF_STATUS 0x00000198 #define MSR_IA32_PERF_CTL 0x00000199 +#define MSR_AMD_PERF_STATUS 0xc0010063 +#define MSR_AMD_PERF_CTL 0xc0010062 #define MSR_IA32_MPERF 0x000000e7 #define MSR_IA32_APERF 0x000000e8 diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index 78ff7ee48951..8d12e378a7ef 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 @@ -23,7 +23,8 @@ config X86_ACPI_CPUFREQ help This driver adds a CPUFreq driver which utilizes the ACPI Processor Performance States. - This driver also supports Intel Enhanced Speedstep. + This driver also supports Intel Enhanced Speedstep and newer + AMD CPUs. To compile this driver as a module, choose M here: the module will be called acpi-cpufreq. diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 56c6c6b4eb4d..067a61f06bb5 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -54,10 +54,12 @@ MODULE_LICENSE("GPL"); enum { UNDEFINED_CAPABLE = 0, SYSTEM_INTEL_MSR_CAPABLE, + SYSTEM_AMD_MSR_CAPABLE, SYSTEM_IO_CAPABLE, }; #define INTEL_MSR_RANGE (0xffff) +#define AMD_MSR_RANGE (0x7) struct acpi_cpufreq_data { struct acpi_processor_performance *acpi_data; @@ -82,6 +84,13 @@ static int check_est_cpu(unsigned int cpuid) return cpu_has(cpu, X86_FEATURE_EST); } +static int check_amd_hwpstate_cpu(unsigned int cpuid) +{ + struct cpuinfo_x86 *cpu = &cpu_data(cpuid); + + return cpu_has(cpu, X86_FEATURE_HW_PSTATE); +} + static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data) { struct acpi_processor_performance *perf; @@ -101,7 +110,11 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data) int i; struct acpi_processor_performance *perf; - msr &= INTEL_MSR_RANGE; + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + msr &= AMD_MSR_RANGE; + else + msr &= INTEL_MSR_RANGE; + perf = data->acpi_data; for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { @@ -115,6 +128,7 @@ static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data) { switch (data->cpu_feature) { case SYSTEM_INTEL_MSR_CAPABLE: + case SYSTEM_AMD_MSR_CAPABLE: return extract_msr(val, data); case SYSTEM_IO_CAPABLE: return extract_io(val, data); @@ -150,6 +164,7 @@ static void do_drv_read(void *_cmd) switch (cmd->type) { case SYSTEM_INTEL_MSR_CAPABLE: + case SYSTEM_AMD_MSR_CAPABLE: rdmsr(cmd->addr.msr.reg, cmd->val, h); break; case SYSTEM_IO_CAPABLE: @@ -174,6 +189,9 @@ static void do_drv_write(void *_cmd) lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE); wrmsr(cmd->addr.msr.reg, lo, hi); break; + case SYSTEM_AMD_MSR_CAPABLE: + wrmsr(cmd->addr.msr.reg, cmd->val, 0); + break; case SYSTEM_IO_CAPABLE: acpi_os_write_port((acpi_io_address)cmd->addr.io.port, cmd->val, @@ -217,6 +235,10 @@ static u32 get_cur_val(const struct cpumask *mask) cmd.type = SYSTEM_INTEL_MSR_CAPABLE; cmd.addr.msr.reg = MSR_IA32_PERF_STATUS; break; + case SYSTEM_AMD_MSR_CAPABLE: + cmd.type = SYSTEM_AMD_MSR_CAPABLE; + cmd.addr.msr.reg = MSR_AMD_PERF_STATUS; + break; case SYSTEM_IO_CAPABLE: cmd.type = SYSTEM_IO_CAPABLE; perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data; @@ -326,6 +348,11 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, cmd.addr.msr.reg = MSR_IA32_PERF_CTL; cmd.val = (u32) perf->states[next_perf_state].control; break; + case SYSTEM_AMD_MSR_CAPABLE: + cmd.type = SYSTEM_AMD_MSR_CAPABLE; + cmd.addr.msr.reg = MSR_AMD_PERF_CTL; + cmd.val = (u32) perf->states[next_perf_state].control; + break; case SYSTEM_IO_CAPABLE: cmd.type = SYSTEM_IO_CAPABLE; cmd.addr.io.port = perf->control_register.address; @@ -580,12 +607,16 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) break; case ACPI_ADR_SPACE_FIXED_HARDWARE: pr_debug("HARDWARE addr space\n"); - if (!check_est_cpu(cpu)) { - result = -ENODEV; - goto err_unreg; + if (check_est_cpu(cpu)) { + data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE; + break; } - data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE; - break; + if (check_amd_hwpstate_cpu(cpu)) { + data->cpu_feature = SYSTEM_AMD_MSR_CAPABLE; + break; + } + result = -ENODEV; + goto err_unreg; default: pr_debug("Unknown addr space %d\n", (u32) (perf->control_register.space_id)); -- cgit v1.2.3 From f594065faf4f9067c2283a34619fc0714e79a98d Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 4 Sep 2012 08:28:06 +0000 Subject: ACPI: Add fixups for AMD P-state figures Some AMD systems may round the frequencies in ACPI tables to 100MHz boundaries. We can obtain the real frequencies from MSRs, so add a quirk to fix these frequencies up on AMD systems. Signed-off-by: Matthew Garrett Signed-off-by: Andre Przywara Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/msr-index.h | 1 + drivers/acpi/processor_perflib.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'arch') diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 1e1f3eb58638..fbee9714d9ab 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -248,6 +248,7 @@ #define MSR_IA32_PERF_STATUS 0x00000198 #define MSR_IA32_PERF_CTL 0x00000199 +#define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 #define MSR_AMD_PERF_STATUS 0xc0010063 #define MSR_AMD_PERF_CTL 0xc0010062 diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index a093dc163a42..836bfe069042 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -324,6 +324,34 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr) return result; } +#ifdef CONFIG_X86 +/* + * Some AMDs have 50MHz frequency multiples, but only provide 100MHz rounding + * in their ACPI data. Calculate the real values and fix up the _PSS data. + */ +static void amd_fixup_frequency(struct acpi_processor_px *px, int i) +{ + u32 hi, lo, fid, did; + int index = px->control & 0x00000007; + + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + return; + + if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) + || boot_cpu_data.x86 == 0x11) { + rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi); + fid = lo & 0x3f; + did = (lo >> 6) & 7; + if (boot_cpu_data.x86 == 0x10) + px->core_frequency = (100 * (fid + 0x10)) >> did; + else + px->core_frequency = (100 * (fid + 8)) >> did; + } +} +#else +static void amd_fixup_frequency(struct acpi_processor_px *px, int i) {}; +#endif + static int acpi_processor_get_performance_states(struct acpi_processor *pr) { int result = 0; @@ -379,6 +407,8 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) goto end; } + amd_fixup_frequency(px, i); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", i, -- cgit v1.2.3 From ec971ea5f2426a0bf9d5cca9a103743918c12978 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Wed, 5 Sep 2012 01:08:59 +0200 Subject: ARM: add cpufreq transiton notifier to adjust loops_per_jiffy for smp If CONFIG_SMP, cpufreq skips loops_per_jiffy update, because different arch has different per-cpu loops_per_jiffy definition. Signed-off-by: Richard Zhao Acked-by: Russell King Acked-by: Santosh Shilimkar Signed-off-by: Shawn Guo Signed-off-by: Rafael J. Wysocki --- arch/arm/kernel/smp.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'arch') diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index ebd8ad274d76..8e03567c9583 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -584,3 +585,56 @@ int setup_profiling_timer(unsigned int multiplier) { return -EINVAL; } + +#ifdef CONFIG_CPU_FREQ + +static DEFINE_PER_CPU(unsigned long, l_p_j_ref); +static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq); +static unsigned long global_l_p_j_ref; +static unsigned long global_l_p_j_ref_freq; + +static int cpufreq_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct cpufreq_freqs *freq = data; + int cpu = freq->cpu; + + if (freq->flags & CPUFREQ_CONST_LOOPS) + return NOTIFY_OK; + + if (!per_cpu(l_p_j_ref, cpu)) { + per_cpu(l_p_j_ref, cpu) = + per_cpu(cpu_data, cpu).loops_per_jiffy; + per_cpu(l_p_j_ref_freq, cpu) = freq->old; + if (!global_l_p_j_ref) { + global_l_p_j_ref = loops_per_jiffy; + global_l_p_j_ref_freq = freq->old; + } + } + + if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || + (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { + loops_per_jiffy = cpufreq_scale(global_l_p_j_ref, + global_l_p_j_ref_freq, + freq->new); + per_cpu(cpu_data, cpu).loops_per_jiffy = + cpufreq_scale(per_cpu(l_p_j_ref, cpu), + per_cpu(l_p_j_ref_freq, cpu), + freq->new); + } + return NOTIFY_OK; +} + +static struct notifier_block cpufreq_notifier = { + .notifier_call = cpufreq_callback, +}; + +static int __init register_cpufreq_notifier(void) +{ + return cpufreq_register_notifier(&cpufreq_notifier, + CPUFREQ_TRANSITION_NOTIFIER); +} +core_initcall(register_cpufreq_notifier); + +#endif -- cgit v1.2.3