From 9aaa74908b2117bcd560ab3ea8a9d6a491a77c28 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:17 +0000 Subject: sh: Runtime PM pdev hwblk These patches extend struct platform device data for a bunch of SuperH Mobile processors and embedded boards. The patches simply add hardware block ids to on-chip platform devices. Platform devices off chip (such as external ethernet controllers or flash chips) are left out which gives them a special case hardware block id of zero. Upcoming Runtime PM code will make use of the hardware block id to group devices together. The hardware block id can also be used to extend the SuperH Mobile clock framework implementation. This series of patches depend on the following: "Driver Core: Add platform device arch data V3". This patch adds a hwblk_id member to struct pdev_archdata. This member should be used to point out on-chip hardware block id. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/device.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h index 8688a88303ee..783ecdc64e25 100644 --- a/arch/sh/include/asm/device.h +++ b/arch/sh/include/asm/device.h @@ -3,7 +3,9 @@ * * This file is released under the GPLv2 */ -#include + +struct dev_archdata { +}; struct platform_device; /* allocate contiguous memory chunk and fill in struct resource */ @@ -12,3 +14,6 @@ int platform_resource_setup_memory(struct platform_device *pdev, void plat_early_device_setup(void); +struct pdev_archdata { + int hwblk_id; +}; -- cgit v1.2.3-59-g8ed1b From f69d5782742e57d5f047ed13440bcf1b320cb074 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:27 +0000 Subject: sh: Runtime PM pdev hwblk - sh7722 Add hwblk_id to on-chip sh7722 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 67b0d87fcb27..35097753456c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -17,6 +17,7 @@ #include #include #include +#include static struct resource rtc_resources[] = { [0] = { @@ -46,6 +47,9 @@ static struct platform_device rtc_device = { .id = -1, .num_resources = ARRAY_SIZE(rtc_resources), .resource = rtc_resources, + .archdata = { + .hwblk_id = HWBLK_RTC, + }, }; static struct m66592_platdata usbf_platdata = { @@ -76,6 +80,9 @@ static struct platform_device usbf_device = { }, .num_resources = ARRAY_SIZE(usbf_resources), .resource = usbf_resources, + .archdata = { + .hwblk_id = HWBLK_USBF, + }, }; static struct resource iic_resources[] = { @@ -97,6 +104,9 @@ static struct platform_device iic_device = { .id = 0, /* "i2c0" clock */ .num_resources = ARRAY_SIZE(iic_resources), .resource = iic_resources, + .archdata = { + .hwblk_id = HWBLK_IIC, + }, }; static struct uio_info vpu_platform_data = { @@ -125,6 +135,9 @@ static struct platform_device vpu_device = { }, .resource = vpu_resources, .num_resources = ARRAY_SIZE(vpu_resources), + .archdata = { + .hwblk_id = HWBLK_VPU, + }, }; static struct uio_info veu_platform_data = { @@ -153,6 +166,9 @@ static struct platform_device veu_device = { }, .resource = veu_resources, .num_resources = ARRAY_SIZE(veu_resources), + .archdata = { + .hwblk_id = HWBLK_VEU, + }, }; static struct uio_info jpu_platform_data = { @@ -181,6 +197,9 @@ static struct platform_device jpu_device = { }, .resource = jpu_resources, .num_resources = ARRAY_SIZE(jpu_resources), + .archdata = { + .hwblk_id = HWBLK_JPU, + }, }; static struct sh_timer_config cmt_platform_data = { @@ -213,6 +232,9 @@ static struct platform_device cmt_device = { }, .resource = cmt_resources, .num_resources = ARRAY_SIZE(cmt_resources), + .archdata = { + .hwblk_id = HWBLK_CMT, + }, }; static struct sh_timer_config tmu0_platform_data = { @@ -244,6 +266,9 @@ static struct platform_device tmu0_device = { }, .resource = tmu0_resources, .num_resources = ARRAY_SIZE(tmu0_resources), + .archdata = { + .hwblk_id = HWBLK_TMU, + }, }; static struct sh_timer_config tmu1_platform_data = { @@ -275,6 +300,9 @@ static struct platform_device tmu1_device = { }, .resource = tmu1_resources, .num_resources = ARRAY_SIZE(tmu1_resources), + .archdata = { + .hwblk_id = HWBLK_TMU, + }, }; static struct sh_timer_config tmu2_platform_data = { @@ -305,6 +333,9 @@ static struct platform_device tmu2_device = { }, .resource = tmu2_resources, .num_resources = ARRAY_SIZE(tmu2_resources), + .archdata = { + .hwblk_id = HWBLK_TMU, + }, }; static struct plat_sci_port sci_platform_data[] = { -- cgit v1.2.3-59-g8ed1b From 2de63cf376585508f6942aaa7337848f8c4cdd7d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:35 +0000 Subject: sh: Runtime PM pdev hwblk - Migo-R Add hwblk_id to Migo-R board specific on-chip sh7722 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-migor/setup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index f70f4644deb4..a508a0fa7315 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -98,6 +98,9 @@ static struct platform_device sh_keysc_device = { .dev = { .platform_data = &sh_keysc_info, }, + .archdata = { + .hwblk_id = HWBLK_KEYSC, + }, }; static struct mtd_partition migor_nor_flash_partitions[] = @@ -292,6 +295,9 @@ static struct platform_device migor_lcdc_device = { .dev = { .platform_data = &sh_mobile_lcdc_info, }, + .archdata = { + .hwblk_id = HWBLK_LCDC, + }, }; static struct clk *camera_clk; @@ -379,6 +385,9 @@ static struct platform_device migor_ceu_device = { .dev = { .platform_data = &sh_mobile_ceu_info, }, + .archdata = { + .hwblk_id = HWBLK_CEU, + }, }; struct spi_gpio_platform_data sdcard_cn9_platform_data = { -- cgit v1.2.3-59-g8ed1b From 66d9c51ac434615b0f0e864c0c9a81d7264ca3ef Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:44 +0000 Subject: sh: Runtime PM pdev hwblk - Solution Engine 7722 Add hwblk_id to Solution Engine 7722 board specific on-chip sh7722 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7722/setup.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c index af84904ed86f..36374078e521 100644 --- a/arch/sh/boards/mach-se/7722/setup.c +++ b/arch/sh/boards/mach-se/7722/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include /* Heartbeat */ static struct heartbeat_data heartbeat_data = { @@ -137,6 +138,9 @@ static struct platform_device sh_keysc_device = { .dev = { .platform_data = &sh_keysc_info, }, + .archdata = { + .hwblk_id = HWBLK_KEYSC, + }, }; static struct platform_device *se7722_devices[] __initdata = { -- cgit v1.2.3-59-g8ed1b From 09d21f9c83c49afd04850b8701772c09954054e0 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:47:53 +0000 Subject: sh: Runtime PM pdev hwblk - sh7723 Add hwblk_id to on-chip sh7723 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 26dc4d323252..4caa5a7ca86e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -18,6 +18,7 @@ #include #include #include +#include static struct uio_info vpu_platform_data = { .name = "VPU5", @@ -45,6 +46,9 @@ static struct platform_device vpu_device = { }, .resource = vpu_resources, .num_resources = ARRAY_SIZE(vpu_resources), + .archdata = { + .hwblk_id = HWBLK_VPU, + }, }; static struct uio_info veu0_platform_data = { @@ -73,6 +77,9 @@ static struct platform_device veu0_device = { }, .resource = veu0_resources, .num_resources = ARRAY_SIZE(veu0_resources), + .archdata = { + .hwblk_id = HWBLK_VEU2H0, + }, }; static struct uio_info veu1_platform_data = { @@ -101,6 +108,9 @@ static struct platform_device veu1_device = { }, .resource = veu1_resources, .num_resources = ARRAY_SIZE(veu1_resources), + .archdata = { + .hwblk_id = HWBLK_VEU2H1, + }, }; static struct sh_timer_config cmt_platform_data = { @@ -133,6 +143,9 @@ static struct platform_device cmt_device = { }, .resource = cmt_resources, .num_resources = ARRAY_SIZE(cmt_resources), + .archdata = { + .hwblk_id = HWBLK_CMT, + }, }; static struct sh_timer_config tmu0_platform_data = { @@ -164,6 +177,9 @@ static struct platform_device tmu0_device = { }, .resource = tmu0_resources, .num_resources = ARRAY_SIZE(tmu0_resources), + .archdata = { + .hwblk_id = HWBLK_TMU0, + }, }; static struct sh_timer_config tmu1_platform_data = { @@ -195,6 +211,9 @@ static struct platform_device tmu1_device = { }, .resource = tmu1_resources, .num_resources = ARRAY_SIZE(tmu1_resources), + .archdata = { + .hwblk_id = HWBLK_TMU0, + }, }; static struct sh_timer_config tmu2_platform_data = { @@ -225,6 +244,9 @@ static struct platform_device tmu2_device = { }, .resource = tmu2_resources, .num_resources = ARRAY_SIZE(tmu2_resources), + .archdata = { + .hwblk_id = HWBLK_TMU0, + }, }; static struct sh_timer_config tmu3_platform_data = { @@ -255,6 +277,9 @@ static struct platform_device tmu3_device = { }, .resource = tmu3_resources, .num_resources = ARRAY_SIZE(tmu3_resources), + .archdata = { + .hwblk_id = HWBLK_TMU1, + }, }; static struct sh_timer_config tmu4_platform_data = { @@ -285,6 +310,9 @@ static struct platform_device tmu4_device = { }, .resource = tmu4_resources, .num_resources = ARRAY_SIZE(tmu4_resources), + .archdata = { + .hwblk_id = HWBLK_TMU1, + }, }; static struct sh_timer_config tmu5_platform_data = { @@ -315,6 +343,9 @@ static struct platform_device tmu5_device = { }, .resource = tmu5_resources, .num_resources = ARRAY_SIZE(tmu5_resources), + .archdata = { + .hwblk_id = HWBLK_TMU1, + }, }; static struct plat_sci_port sci_platform_data[] = { @@ -395,6 +426,9 @@ static struct platform_device rtc_device = { .id = -1, .num_resources = ARRAY_SIZE(rtc_resources), .resource = rtc_resources, + .archdata = { + .hwblk_id = HWBLK_RTC, + }, }; static struct r8a66597_platdata r8a66597_data = { @@ -424,6 +458,9 @@ static struct platform_device sh7723_usb_host_device = { }, .num_resources = ARRAY_SIZE(sh7723_usb_host_resources), .resource = sh7723_usb_host_resources, + .archdata = { + .hwblk_id = HWBLK_USB, + }, }; static struct resource iic_resources[] = { @@ -445,6 +482,9 @@ static struct platform_device iic_device = { .id = 0, /* "i2c0" clock */ .num_resources = ARRAY_SIZE(iic_resources), .resource = iic_resources, + .archdata = { + .hwblk_id = HWBLK_IIC, + }, }; static struct platform_device *sh7723_devices[] __initdata = { -- cgit v1.2.3-59-g8ed1b From d3a6f6260a3fecd9a8e301fcf37d87ee70edca12 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:48:02 +0000 Subject: sh: Runtime PM pdev hwblk - AP325RXA Add hwblk_id to AP325RXA board specific on-chip sh7723 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/board-ap325rxa.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c index 7ffd1b4315bd..07a54740d43e 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/board-ap325rxa.c @@ -227,6 +227,9 @@ static struct platform_device lcdc_device = { .dev = { .platform_data = &lcdc_info, }, + .archdata = { + .hwblk_id = HWBLK_LCDC, + }, }; static void camera_power(int val) @@ -377,6 +380,9 @@ static struct platform_device ceu_device = { .dev = { .platform_data = &sh_mobile_ceu_info, }, + .archdata = { + .hwblk_id = HWBLK_CEU, + }, }; struct spi_gpio_platform_data sdcard_cn3_platform_data = { -- cgit v1.2.3-59-g8ed1b From 593a0c898ac2f09f001d536f699966ec4bc1d25f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:48:11 +0000 Subject: sh: Runtime PM pdev hwblk - sh7724 Add hwblk_id to on-chip sh7724 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index a04edaab9a29..f3851fd757ec 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -22,6 +22,7 @@ #include #include #include +#include /* Serial */ static struct plat_sci_port sci_platform_data[] = { @@ -103,6 +104,9 @@ static struct platform_device rtc_device = { .id = -1, .num_resources = ARRAY_SIZE(rtc_resources), .resource = rtc_resources, + .archdata = { + .hwblk_id = HWBLK_RTC, + }, }; /* I2C0 */ @@ -125,6 +129,9 @@ static struct platform_device iic0_device = { .id = 0, /* "i2c0" clock */ .num_resources = ARRAY_SIZE(iic0_resources), .resource = iic0_resources, + .archdata = { + .hwblk_id = HWBLK_IIC0, + }, }; /* I2C1 */ @@ -147,6 +154,9 @@ static struct platform_device iic1_device = { .id = 1, /* "i2c1" clock */ .num_resources = ARRAY_SIZE(iic1_resources), .resource = iic1_resources, + .archdata = { + .hwblk_id = HWBLK_IIC1, + }, }; /* VPU */ @@ -176,6 +186,9 @@ static struct platform_device vpu_device = { }, .resource = vpu_resources, .num_resources = ARRAY_SIZE(vpu_resources), + .archdata = { + .hwblk_id = HWBLK_VPU, + }, }; /* VEU0 */ @@ -205,6 +218,9 @@ static struct platform_device veu0_device = { }, .resource = veu0_resources, .num_resources = ARRAY_SIZE(veu0_resources), + .archdata = { + .hwblk_id = HWBLK_VEU0, + }, }; /* VEU1 */ @@ -234,6 +250,9 @@ static struct platform_device veu1_device = { }, .resource = veu1_resources, .num_resources = ARRAY_SIZE(veu1_resources), + .archdata = { + .hwblk_id = HWBLK_VEU1, + }, }; static struct sh_timer_config cmt_platform_data = { @@ -266,6 +285,9 @@ static struct platform_device cmt_device = { }, .resource = cmt_resources, .num_resources = ARRAY_SIZE(cmt_resources), + .archdata = { + .hwblk_id = HWBLK_CMT, + }, }; static struct sh_timer_config tmu0_platform_data = { @@ -297,6 +319,9 @@ static struct platform_device tmu0_device = { }, .resource = tmu0_resources, .num_resources = ARRAY_SIZE(tmu0_resources), + .archdata = { + .hwblk_id = HWBLK_TMU0, + }, }; static struct sh_timer_config tmu1_platform_data = { @@ -328,6 +353,9 @@ static struct platform_device tmu1_device = { }, .resource = tmu1_resources, .num_resources = ARRAY_SIZE(tmu1_resources), + .archdata = { + .hwblk_id = HWBLK_TMU0, + }, }; static struct sh_timer_config tmu2_platform_data = { @@ -358,6 +386,9 @@ static struct platform_device tmu2_device = { }, .resource = tmu2_resources, .num_resources = ARRAY_SIZE(tmu2_resources), + .archdata = { + .hwblk_id = HWBLK_TMU0, + }, }; @@ -389,6 +420,9 @@ static struct platform_device tmu3_device = { }, .resource = tmu3_resources, .num_resources = ARRAY_SIZE(tmu3_resources), + .archdata = { + .hwblk_id = HWBLK_TMU1, + }, }; static struct sh_timer_config tmu4_platform_data = { @@ -419,6 +453,9 @@ static struct platform_device tmu4_device = { }, .resource = tmu4_resources, .num_resources = ARRAY_SIZE(tmu4_resources), + .archdata = { + .hwblk_id = HWBLK_TMU1, + }, }; static struct sh_timer_config tmu5_platform_data = { @@ -449,6 +486,9 @@ static struct platform_device tmu5_device = { }, .resource = tmu5_resources, .num_resources = ARRAY_SIZE(tmu5_resources), + .archdata = { + .hwblk_id = HWBLK_TMU1, + }, }; /* JPU */ @@ -478,6 +518,9 @@ static struct platform_device jpu_device = { }, .resource = jpu_resources, .num_resources = ARRAY_SIZE(jpu_resources), + .archdata = { + .hwblk_id = HWBLK_JPU, + }, }; static struct platform_device *sh7724_devices[] __initdata = { -- cgit v1.2.3-59-g8ed1b From 442c37534c6a46d8ed27144fb09818833edbd049 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:48:21 +0000 Subject: sh: Runtime PM pdev hwblk - kfr2r09 Add hwblk_id to kfr2r09 board specific on-chip sh7724 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/setup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index bf5f8f8d3b5f..0e9b39034df3 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -95,6 +95,9 @@ static struct platform_device kfr2r09_sh_keysc_device = { .dev = { .platform_data = &kfr2r09_sh_keysc_info, }, + .archdata = { + .hwblk_id = HWBLK_KEYSC, + }, }; static struct platform_device *kfr2r09_devices[] __initdata = { -- cgit v1.2.3-59-g8ed1b From df47cd096c8f54a5242e3a2ffb4525c804567eda Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Jul 2009 07:48:29 +0000 Subject: sh: Runtime PM pdev hwblk - Solution Engine 7724 Add hwblk_id to Solution Engine 7724 board specific on-chip sh7724 platform devices. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 4fb7e48e2843..8de5ebc36b67 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -174,6 +174,9 @@ static struct platform_device lcdc_device = { .dev = { .platform_data = &lcdc_info, }, + .archdata = { + .hwblk_id = HWBLK_LCDC, + }, }; /* CEU0 */ @@ -205,6 +208,9 @@ static struct platform_device ceu0_device = { .dev = { .platform_data = &sh_mobile_ceu0_info, }, + .archdata = { + .hwblk_id = HWBLK_CEU0, + }, }; /* CEU1 */ @@ -236,6 +242,9 @@ static struct platform_device ceu1_device = { .dev = { .platform_data = &sh_mobile_ceu1_info, }, + .archdata = { + .hwblk_id = HWBLK_CEU1, + }, }; /* KEYSC */ @@ -273,6 +282,9 @@ static struct platform_device keysc_device = { .dev = { .platform_data = &keysc_info, }, + .archdata = { + .hwblk_id = HWBLK_KEYSC, + }, }; /* SH Eth */ @@ -301,6 +313,9 @@ static struct platform_device sh_eth_device = { }, .num_resources = ARRAY_SIZE(sh_eth_resources), .resource = sh_eth_resources, + .archdata = { + .hwblk_id = HWBLK_ETHER, + }, }; static struct r8a66597_platdata sh7724_usb0_host_data = { @@ -330,6 +345,9 @@ static struct platform_device sh7724_usb0_host_device = { }, .num_resources = ARRAY_SIZE(sh7724_usb0_host_resources), .resource = sh7724_usb0_host_resources, + .archdata = { + .hwblk_id = HWBLK_USB0, + }, }; static struct platform_device *ms7724se_devices[] __initdata = { -- cgit v1.2.3-59-g8ed1b From 963e04cafbf001ec431025a46ec246ae6d89daba Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Sat, 15 Aug 2009 03:02:08 +0000 Subject: sh: Runtime PM pdev hwblk - kfr2r09 LCDC This patch simply adds LCDC hwblk_id data for the kfr2r09 board. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/setup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index c96533794c26..f9ba43635dc1 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -176,6 +176,9 @@ static struct platform_device kfr2r09_sh_lcdc_device = { .dev = { .platform_data = &kfr2r09_sh_lcdc_info, }, + .archdata = { + .hwblk_id = HWBLK_LCDC, + }, }; static struct platform_device *kfr2r09_devices[] __initdata = { -- cgit v1.2.3-59-g8ed1b From 6a93dde1e8216f7af9b2551a60fb1a5eeac4a89f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 14 Aug 2009 10:48:16 +0000 Subject: sh: Runtime PM for SuperH Mobile platform bus devices This patch is V3 of the SuperH Mobile Runtime PM platform bus implentation matching Rafael's Runtime PM v16. The code gets invoked from the SuperH specific Runtime PM platform bus functions that override the weak symbols for: - platform_pm_runtime_suspend() - platform_pm_runtime_resume() - platform_pm_runtime_idle() This Runtime PM implementation performs two levels of power management. At the time of platform bus runtime suspend the clock to the device is stopped instantly. Later on if all devices within the power domain has their clocks stopped then the device driver ->runtime_suspend() callbacks are used to save hardware register state for each device. Device driver ->runtime_suspend() calls are scheduled from cpuidle context using platform_pm_runtime_suspend_idle(). When all devices have been fully suspended the processor is allowed to enter deep sleep from cpuidle. The runtime resume operation turns on clocks and also restores registers if needed. It is worth noting that the devices start in a suspended state and the device driver is responsible for calling runtime resume before accessing the actual hardware. In this particular platform bus implementation runtime resume is not allowed from interrupt context. Runtime suspend is however allowed from interrupt context as long as the synchronous functions are avoided. [ updated for v17 -- PFM. ] Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/device.h | 9 + arch/sh/include/asm/hwblk.h | 4 +- arch/sh/kernel/cpu/shmobile/Makefile | 1 + arch/sh/kernel/cpu/shmobile/pm_runtime.c | 304 +++++++++++++++++++++++++++++++ 4 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 arch/sh/kernel/cpu/shmobile/pm_runtime.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h index 783ecdc64e25..b16debfe8c1e 100644 --- a/arch/sh/include/asm/device.h +++ b/arch/sh/include/asm/device.h @@ -14,6 +14,15 @@ int platform_resource_setup_memory(struct platform_device *pdev, void plat_early_device_setup(void); +#define PDEV_ARCHDATA_FLAG_INIT 0 +#define PDEV_ARCHDATA_FLAG_IDLE 1 +#define PDEV_ARCHDATA_FLAG_SUSP 2 + struct pdev_archdata { int hwblk_id; +#ifdef CONFIG_PM_RUNTIME + unsigned long flags; + struct list_head entry; + struct mutex mutex; +#endif }; diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h index c01d72cb6757..5d3ccae4202b 100644 --- a/arch/sh/include/asm/hwblk.h +++ b/arch/sh/include/asm/hwblk.h @@ -5,7 +5,9 @@ #include #define HWBLK_CNT_USAGE 0 -#define HWBLK_CNT_NR 1 +#define HWBLK_CNT_IDLE 1 +#define HWBLK_CNT_DEVICES 2 +#define HWBLK_CNT_NR 3 #define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */ diff --git a/arch/sh/kernel/cpu/shmobile/Makefile b/arch/sh/kernel/cpu/shmobile/Makefile index e8a5111e848a..a39f88ea1a85 100644 --- a/arch/sh/kernel/cpu/shmobile/Makefile +++ b/arch/sh/kernel/cpu/shmobile/Makefile @@ -5,3 +5,4 @@ # Power Management & Sleep mode obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o +obj-$(CONFIG_PM_RUNTIME) += pm_runtime.o diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c new file mode 100644 index 000000000000..d5f5285a2253 --- /dev/null +++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c @@ -0,0 +1,304 @@ +/* + * arch/sh/kernel/cpu/shmobile/pm_runtime.c + * + * Runtime PM support code for SuperH Mobile + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(hwblk_lock); +static LIST_HEAD(hwblk_idle_list); +static struct work_struct hwblk_work; + +extern struct hwblk_info *hwblk_info; + +static void platform_pm_runtime_not_idle(struct platform_device *pdev) +{ + unsigned long flags; + + /* remove device from idle list */ + spin_lock_irqsave(&hwblk_lock, flags); + if (test_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags)) { + list_del(&pdev->archdata.entry); + __clear_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags); + } + spin_unlock_irqrestore(&hwblk_lock, flags); +} + +static int __platform_pm_runtime_resume(struct platform_device *pdev) +{ + struct device *d = &pdev->dev; + struct pdev_archdata *ad = &pdev->archdata; + int hwblk = ad->hwblk_id; + int ret = -ENOSYS; + + dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk); + + if (d->driver && d->driver->pm && d->driver->pm->runtime_resume) { + hwblk_enable(hwblk_info, hwblk); + ret = 0; + + if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) { + ret = d->driver->pm->runtime_resume(d); + if (!ret) + clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags); + else + hwblk_disable(hwblk_info, hwblk); + } + } + + dev_dbg(d, "__platform_pm_runtime_resume() [%d] - returns %d\n", + hwblk, ret); + + return ret; +} + +static int __platform_pm_runtime_suspend(struct platform_device *pdev) +{ + struct device *d = &pdev->dev; + struct pdev_archdata *ad = &pdev->archdata; + int hwblk = ad->hwblk_id; + int ret = -ENOSYS; + + dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk); + + if (d->driver && d->driver->pm && d->driver->pm->runtime_suspend) { + BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags)); + + hwblk_enable(hwblk_info, hwblk); + ret = d->driver->pm->runtime_suspend(d); + hwblk_disable(hwblk_info, hwblk); + + if (!ret) { + set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags); + platform_pm_runtime_not_idle(pdev); + hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE); + } + } + + dev_dbg(d, "__platform_pm_runtime_suspend() [%d] - returns %d\n", + hwblk, ret); + + return ret; +} + +static void platform_pm_runtime_work(struct work_struct *work) +{ + struct platform_device *pdev; + unsigned long flags; + int ret; + + /* go through the idle list and suspend one device at a time */ + do { + spin_lock_irqsave(&hwblk_lock, flags); + if (list_empty(&hwblk_idle_list)) + pdev = NULL; + else + pdev = list_first_entry(&hwblk_idle_list, + struct platform_device, + archdata.entry); + spin_unlock_irqrestore(&hwblk_lock, flags); + + if (pdev) { + mutex_lock(&pdev->archdata.mutex); + ret = __platform_pm_runtime_suspend(pdev); + + /* at this point the platform device may be: + * suspended: ret = 0, FLAG_SUSP set, clock stopped + * failed: ret < 0, FLAG_IDLE set, clock stopped + */ + mutex_unlock(&pdev->archdata.mutex); + } else { + ret = -ENODEV; + } + } while (!ret); +} + +/* this function gets called from cpuidle context when all devices in the + * main power domain are unused but some are counted as idle, ie the hwblk + * counter values are (HWBLK_CNT_USAGE == 0) && (HWBLK_CNT_IDLE != 0) + */ +void platform_pm_runtime_suspend_idle(void) +{ + queue_work(pm_wq, &hwblk_work); +} + +int platform_pm_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct pdev_archdata *ad = &pdev->archdata; + unsigned long flags; + int hwblk = ad->hwblk_id; + int ret = 0; + + dev_dbg(dev, "platform_pm_runtime_suspend() [%d]\n", hwblk); + + /* ignore off-chip platform devices */ + if (!hwblk) + goto out; + + /* interrupt context not allowed */ + might_sleep(); + + /* catch misconfigured drivers not starting with resume */ + if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags)) { + ret = -EINVAL; + goto out; + } + + /* serialize */ + mutex_lock(&ad->mutex); + + /* disable clock */ + hwblk_disable(hwblk_info, hwblk); + + /* put device on idle list */ + spin_lock_irqsave(&hwblk_lock, flags); + list_add_tail(&pdev->archdata.entry, &hwblk_idle_list); + __set_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags); + spin_unlock_irqrestore(&hwblk_lock, flags); + + /* increase idle count */ + hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_IDLE); + + /* at this point the platform device is: + * idle: ret = 0, FLAG_IDLE set, clock stopped + */ + mutex_unlock(&ad->mutex); + +out: + dev_dbg(dev, "platform_pm_runtime_suspend() [%d] returns %d\n", + hwblk, ret); + + return ret; +} + +int platform_pm_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct pdev_archdata *ad = &pdev->archdata; + int hwblk = ad->hwblk_id; + int ret = 0; + + dev_dbg(dev, "platform_pm_runtime_resume() [%d]\n", hwblk); + + /* ignore off-chip platform devices */ + if (!hwblk) + goto out; + + /* interrupt context not allowed */ + might_sleep(); + + /* serialize */ + mutex_lock(&ad->mutex); + + /* make sure device is removed from idle list */ + platform_pm_runtime_not_idle(pdev); + + /* decrease idle count */ + if (!test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags) && + !test_bit(PDEV_ARCHDATA_FLAG_SUSP, &pdev->archdata.flags)) + hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE); + + /* resume the device if needed */ + ret = __platform_pm_runtime_resume(pdev); + + /* the driver has been initialized now, so clear the init flag */ + clear_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags); + + /* at this point the platform device may be: + * resumed: ret = 0, flags = 0, clock started + * failed: ret < 0, FLAG_SUSP set, clock stopped + */ + mutex_unlock(&ad->mutex); +out: + dev_dbg(dev, "platform_pm_runtime_resume() [%d] returns %d\n", + hwblk, ret); + + return ret; +} + +int platform_pm_runtime_idle(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + int hwblk = pdev->archdata.hwblk_id; + int ret = 0; + + dev_dbg(dev, "platform_pm_runtime_idle() [%d]\n", hwblk); + + /* ignore off-chip platform devices */ + if (!hwblk) + goto out; + + /* interrupt context not allowed, use pm_runtime_put()! */ + might_sleep(); + + /* suspend synchronously to disable clocks immediately */ + ret = pm_runtime_suspend(dev); +out: + dev_dbg(dev, "platform_pm_runtime_idle() [%d] done!\n", hwblk); + return ret; +} + +static int __devinit platform_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + struct platform_device *pdev = to_platform_device(dev); + int hwblk = pdev->archdata.hwblk_id; + + /* ignore off-chip platform devices */ + if (!hwblk) + return 0; + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + INIT_LIST_HEAD(&pdev->archdata.entry); + mutex_init(&pdev->archdata.mutex); + /* platform devices without drivers should be disabled */ + hwblk_enable(hwblk_info, hwblk); + hwblk_disable(hwblk_info, hwblk); + /* make sure driver re-inits itself once */ + __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags); + break; + /* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */ + case BUS_NOTIFY_BOUND_DRIVER: + /* keep track of number of devices in use per hwblk */ + hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_DEVICES); + break; + case BUS_NOTIFY_UNBOUND_DRIVER: + /* keep track of number of devices in use per hwblk */ + hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_DEVICES); + /* make sure driver re-inits itself once */ + __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags); + break; + case BUS_NOTIFY_DEL_DEVICE: + break; + } + return 0; +} + +static struct notifier_block platform_bus_notifier = { + .notifier_call = platform_bus_notify +}; + +static int __init sh_pm_runtime_init(void) +{ + INIT_WORK(&hwblk_work, platform_pm_runtime_work); + + bus_register_notifier(&platform_bus_type, &platform_bus_notifier); + return 0; +} + +core_initcall(sh_pm_runtime_init); -- cgit v1.2.3-59-g8ed1b From a62926fe4b76d539b77ee53197040153d43916f6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 18 Aug 2009 10:41:06 +0900 Subject: sh: Fix section mismatch in platform bus notifier. The runtime PM for SH-Mobile code had platform_bus_notify() as __devinit, which is rather bogus. Kill off the annotation, which subsequently silences the section mismatch warnings. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/shmobile/pm_runtime.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c index d5f5285a2253..7c615b17e209 100644 --- a/arch/sh/kernel/cpu/shmobile/pm_runtime.c +++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c @@ -251,8 +251,8 @@ out: return ret; } -static int __devinit platform_bus_notify(struct notifier_block *nb, - unsigned long action, void *data) +static int platform_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) { struct device *dev = data; struct platform_device *pdev = to_platform_device(dev); @@ -300,5 +300,4 @@ static int __init sh_pm_runtime_init(void) bus_register_notifier(&platform_bus_type, &platform_bus_notifier); return 0; } - core_initcall(sh_pm_runtime_init); -- cgit v1.2.3-59-g8ed1b From ac2c596b572d08dab64dde3ac1f2de934d781c9f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 19 Aug 2009 10:31:53 +0000 Subject: sh: let ARCH_SHMOBILE select PM and PM_RUNTIME With the Runtime PM driver changes in place, we must have Runtime PM support in place. Otherwise there is no way to enable clocks to the Runtime PM enabled hardware blocks. This patch makes Runtime PM mandatory on SuperH Mobile. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index c4a955d25451..2a16014d9de3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -219,6 +219,8 @@ config CPU_SHX3 config ARCH_SHMOBILE bool select ARCH_SUSPEND_POSSIBLE + select PM + select PM_RUNTIME if SUPERH32 -- cgit v1.2.3-59-g8ed1b From cc58f597afc63a57bb55ed97c2a72f7405320c93 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 19 Aug 2009 10:39:05 +0000 Subject: sh: drop static UIO clocks for sh7722, sh7723 and sh7724 The Runtime PM patch for UIO driver implements coarse grained dynamic power management for UIO devices. With that patch in place we can get rid of the static clock configuration. Which in turn makes it possible for cpuidle to enter deeper sleep. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 6 +++--- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 6 +++--- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 5b1bbbe63b1b..ea38b554dc05 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -164,11 +164,11 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0), SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0), SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0), - SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0), SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0), SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0), - SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU, 0), + SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0), SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0), }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index e5c63911403c..20a31c2255a8 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -190,12 +190,12 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB, 0), SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0), SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0), - SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU2H1, CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU2H1, 0), SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0), SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0), SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0), - SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU2H0, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU2H0, 0), + SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0), SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0), }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 34611d97378e..a0c4ec25bcbc 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -204,17 +204,17 @@ static struct clk mstp_clks[] = { SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0), SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0), SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0), - SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU1, CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU1, 0), SH_HWBLK_CLK("ceu1", -1, B_CLK, HWBLK_CEU1, 0), SH_HWBLK_CLK("beu1", -1, B_CLK, HWBLK_BEU1, 0), SH_HWBLK_CLK("2ddmac0", -1, SH_CLK, HWBLK_2DDMAC, 0), SH_HWBLK_CLK("spu0", -1, B_CLK, HWBLK_SPU, 0), - SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0), SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0), SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU0, 0), SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU0, 0), - SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU0, CLK_ENABLE_ON_INIT), - SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, CLK_ENABLE_ON_INIT), + SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU0, 0), + SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0), SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0), }; -- cgit v1.2.3-59-g8ed1b