summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-10-20 01:52:41 +0400
committerRafael J. Wysocki <rjw@sisk.pl>2011-10-22 02:19:58 +0400
commitd93f5cdea968284f05aa9905ee9752874885a6fa (patch)
tree11d4eebb5a887aaab37f592f23ac8ca60fbc7e6a /arch/arm
parent4ca46ff3e0d8c234cb40ebb6457653b59584426c (diff)
downloadlinux-d93f5cdea968284f05aa9905ee9752874885a6fa.tar.xz
ARM: mach-shmobile: sh7372 A3SP support (v4)
This change adds support for the sh7372 A3SP power domain. The sh7372 A3SP hardware power domain contains a wide range of I/O devices. The list of I/O devices include SCIF serial ports, DMA Engine hardware, SD and MMC controller hardware, USB controllers and I2C master controllers. This patch adds the A3SP low level code which powers the hardware power domain on and off. It also ties in platform devices to the pm domain support code. It is worth noting that the serial console is hooked up to SCIFA0 on most sh7372 boards, and the SCIFA0 port is included in the A3SP hardware power domain. For this reason we cannot output debug messages from the low level power control code in the case of A3SP. QoS support is needed in drivers before we can enable the A3SP power control on the fly. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c4
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c8
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h3
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c30
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c14
5 files changed, 54 insertions, 5 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index d6c8ae813175..bf4f6372dcf4 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1409,6 +1409,10 @@ static void __init ap4evb_init(void)
sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device);
sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device);
+
hdmi_init_pm_clock();
fsi_init_pm_clock();
sh7372_pm_init();
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 19f5d4922e2c..fdb1ca31dfe1 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1588,6 +1588,14 @@ static void __init mackerel_init(void)
sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device);
sh7372_add_device_to_domain(&sh7372_a4lc, &hdmi_lcdc_device);
sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs0_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs1_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device);
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
+ sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device);
+#endif
+ sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi2_device);
hdmi_init_pm_clock();
sh7372_pm_init();
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index efc984c4cef3..8542f2d31a56 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -479,7 +479,9 @@ struct platform_device;
struct sh7372_pm_domain {
struct generic_pm_domain genpd;
+ struct dev_power_governor *gov;
unsigned int bit_shift;
+ bool no_debug;
};
static inline struct sh7372_pm_domain *to_sh7372_pd(struct generic_pm_domain *d)
@@ -493,6 +495,7 @@ extern struct sh7372_pm_domain sh7372_a4mp;
extern struct sh7372_pm_domain sh7372_d4;
extern struct sh7372_pm_domain sh7372_a3rv;
extern struct sh7372_pm_domain sh7372_a3ri;
+extern struct sh7372_pm_domain sh7372_a3sp;
extern struct sh7372_pm_domain sh7372_a3sg;
extern void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd);
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 8e0944f96ba1..fde619dd4c05 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -92,8 +92,9 @@ static int pd_power_down(struct generic_pm_domain *genpd)
}
}
- pr_debug("sh7372 power domain down 0x%08x -> PSTR = 0x%08x\n",
- mask, __raw_readl(PSTR));
+ if (!sh7372_pd->no_debug)
+ pr_debug("sh7372 power domain down 0x%08x -> PSTR = 0x%08x\n",
+ mask, __raw_readl(PSTR));
return 0;
}
@@ -122,8 +123,9 @@ static int pd_power_up(struct generic_pm_domain *genpd)
ret = -EIO;
out:
- pr_debug("sh7372 power domain up 0x%08x -> PSTR = 0x%08x\n",
- mask, __raw_readl(PSTR));
+ if (!sh7372_pd->no_debug)
+ pr_debug("sh7372 power domain up 0x%08x -> PSTR = 0x%08x\n",
+ mask, __raw_readl(PSTR));
return ret;
}
@@ -133,11 +135,20 @@ static bool pd_active_wakeup(struct device *dev)
return true;
}
+static bool sh7372_power_down_forbidden(struct dev_pm_domain *domain)
+{
+ return false;
+}
+
+struct dev_power_governor sh7372_always_on_gov = {
+ .power_down_ok = sh7372_power_down_forbidden,
+};
+
void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
{
struct generic_pm_domain *genpd = &sh7372_pd->genpd;
- pm_genpd_init(genpd, NULL, false);
+ pm_genpd_init(genpd, sh7372_pd->gov, false);
genpd->stop_device = pm_clk_suspend;
genpd->start_device = pm_clk_resume;
genpd->dev_irq_safe = true;
@@ -183,6 +194,12 @@ struct sh7372_pm_domain sh7372_a3ri = {
.bit_shift = 8,
};
+struct sh7372_pm_domain sh7372_a3sp = {
+ .bit_shift = 11,
+ .gov = &sh7372_always_on_gov,
+ .no_debug = true,
+};
+
struct sh7372_pm_domain sh7372_a3sg = {
.bit_shift = 13,
};
@@ -422,6 +439,9 @@ void __init sh7372_pm_init(void)
__raw_writel(0x0000a501, DBGREG9);
__raw_writel(0x00000000, DBGREG1);
+ /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */
+ __raw_writel(0, PDNSEL);
+
sh7372_suspend_init();
sh7372_cpuidle_init();
}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index d317c224ed63..5f1afcc4de6e 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -994,6 +994,7 @@ void __init sh7372_add_standard_devices(void)
sh7372_init_pm_domain(&sh7372_a3rv);
sh7372_init_pm_domain(&sh7372_a3ri);
sh7372_init_pm_domain(&sh7372_a3sg);
+ sh7372_init_pm_domain(&sh7372_a3sp);
sh7372_pm_add_subdomain(&sh7372_a4lc, &sh7372_a3rv);
@@ -1006,6 +1007,19 @@ void __init sh7372_add_standard_devices(void)
sh7372_add_device_to_domain(&sh7372_a3rv, &vpu_device);
sh7372_add_device_to_domain(&sh7372_a4mp, &spu0_device);
sh7372_add_device_to_domain(&sh7372_a4mp, &spu1_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &scif0_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &scif1_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &scif2_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &scif3_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &scif4_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &scif5_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &scif6_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &iic1_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &dma0_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &dma1_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &dma2_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &usb_dma0_device);
+ sh7372_add_device_to_domain(&sh7372_a3sp, &usb_dma1_device);
}
void __init sh7372_add_early_devices(void)