From 006c7f18449a06027b0165e938c67b3a029813c9 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 4 Jul 2012 05:22:53 -0600 Subject: ARM: OMAP2+: hwmod code/clockdomain data: fix 32K sync timer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kevin discovered that commit c8d82ff68fb6873691536cf33021977efbf5593c ("ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod database") broke CORE idle on OMAP3. This prevents device low power states. The root cause is that the 32K sync timer IP block does not support smart-idle mode[1], and so the hwmod code keeps the IP block in no-idle mode while it is active. This in turn prevents the WKUP clockdomain from transitioning to idle. There is a hardcoded sleep dependency that prevents the CORE_L3 and CORE_CM clockdomains from transitioning to idle when the WKUP clockdomain is active[2], so the chip cannot enter any device low power states. It turns out that there is no need to take the 32k sync timer out of idle. The IP block itself probably does not have any native idle handling at all, due to its simplicity. Furthermore, the PRCM will never request target idle for this IP block while the kernel is running, due to the sleep dependency that prevents the WKUP clockdomain from idling while the CORE_L3 clockdomain is active. So we can safely leave the 32k sync timer in target-force-idle mode, even while we continue to access it. This workaround is implemented by defining a new clockdomain flag, CLKDM_ACTIVE_WITH_MPU, that indicates that the clockdomain is guaranteed to be active whenever the MPU is inactive. If an IP block's main functional clock exists inside this clockdomain, and the IP block does not support smart-idle modes, then the hwmod code will place the IP block into target force-idle mode even when enabled. The WKUP clockdomains on OMAP3/4 are marked with this flag. (On OMAP2xxx, no OCP header existed on the 32k sync timer.) Other clockdomains also should be marked with this flag, but those changes are deferred until a later merge window, to create a minimal fix. Another theoretically clean fix for this problem would be to implement PM runtime-based control for 32k sync timer accesses. These PM runtime calls would need to located in a custom clocksource, since the 32k sync timer is currently used as an MMIO clocksource. But in practice, there would be little benefit to doing so; and there would be some cost, due to the addition of unnecessary lines of code and the additional CPU overhead of the PM runtime and hwmod code - unnecessary in this case. Another possible fix would have been to modify the pm34xx.c code to force the IP block idle before entering WFI. But this would not have been an acceptable approach: we are trying to remove this type of centralized IP block idle control from the PM code. This patch is a collaboration between Kevin Hilman and Paul Walmsley . Thanks to Vaibhav Hiremath for providing comments on an earlier version of this patch. Thanks to Tero Kristo for identifying a bug in an earlier version of this patch. Thanks to Benoît Cousson for identifying some bugs in several versions of this patch and for implementation comments. References: 1. Table 16-96 "REG_32KSYNCNT_SYSCONFIG" of the OMAP34xx TRM Rev. ZU (SWPU223U), available from: http://www.ti.com/pdfs/wtbu/OMAP34x_ES3.1.x_PUBLIC_TRM_vzU.zip 2. Table 4-72 "Sleep Dependencies" of the OMAP34xx TRM Rev. ZU (SWPU223U) 3. ibid. Cc: Tony Lindgren Cc: Vaibhav Hiremath Cc: Benoît Cousson Cc: Tero Kristo Tested-by: Kevin Hilman Signed-off-by: Paul Walmsley Signed-off-by: Kevin Hilman diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index f7b58609..6227e95 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -31,12 +31,16 @@ * * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this * clockdomain. (Currently, this applies to OMAP3 clockdomains only.) + * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is + * active whenever the MPU is active. True for interconnects and + * the WKUP clockdomains. */ #define CLKDM_CAN_FORCE_SLEEP (1 << 0) #define CLKDM_CAN_FORCE_WAKEUP (1 << 1) #define CLKDM_CAN_ENABLE_AUTO (1 << 2) #define CLKDM_CAN_DISABLE_AUTO (1 << 3) #define CLKDM_NO_AUTODEPS (1 << 4) +#define CLKDM_ACTIVE_WITH_MPU (1 << 5) #define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) #define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c index 839145e1..4972219 100644 --- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c @@ -88,4 +88,5 @@ struct clockdomain wkup_common_clkdm = { .name = "wkup_clkdm", .pwrdm = { .name = "wkup_pwrdm" }, .dep_bit = OMAP_EN_WKUP_SHIFT, + .flags = CLKDM_ACTIVE_WITH_MPU, }; diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index c534258..7f2133a 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -381,7 +381,7 @@ static struct clockdomain l4_wkup_44xx_clkdm = { .cm_inst = OMAP4430_PRM_WKUP_CM_INST, .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS, .dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT, - .flags = CLKDM_CAN_HWSUP, + .flags = CLKDM_CAN_HWSUP | CLKDM_ACTIVE_WITH_MPU, }; static struct clockdomain emu_sys_44xx_clkdm = { diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 7731936..2d710f5 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1124,15 +1124,18 @@ static struct omap_hwmod_addr_space * __init _find_mpu_rt_addr_space(struct omap * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG * @oh: struct omap_hwmod * * - * If module is marked as SWSUP_SIDLE, force the module out of slave - * idle; otherwise, configure it for smart-idle. If module is marked - * as SWSUP_MSUSPEND, force the module out of master standby; - * otherwise, configure it for smart-standby. No return value. + * Ensure that the OCP_SYSCONFIG register for the IP block represented + * by @oh is set to indicate to the PRCM that the IP block is active. + * Usually this means placing the module into smart-idle mode and + * smart-standby, but if there is a bug in the automatic idle handling + * for the IP block, it may need to be placed into the force-idle or + * no-idle variants of these modes. No return value. */ static void _enable_sysc(struct omap_hwmod *oh) { u8 idlemode, sf; u32 v; + bool clkdm_act; if (!oh->class->sysc) return; @@ -1141,8 +1144,16 @@ static void _enable_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags; if (sf & SYSC_HAS_SIDLEMODE) { - idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? - HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; + clkdm_act = ((oh->clkdm && + oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) || + (oh->_clk && oh->_clk->clkdm && + oh->_clk->clkdm->flags & CLKDM_ACTIVE_WITH_MPU)); + if (clkdm_act && !(oh->class->sysc->idlemodes & + (SIDLE_SMART | SIDLE_SMART_WKUP))) + idlemode = HWMOD_IDLEMODE_FORCE; + else + idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? + HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; _set_slave_idlemode(oh, idlemode, &v); } @@ -1208,8 +1219,13 @@ static void _idle_sysc(struct omap_hwmod *oh) sf = oh->class->sysc->sysc_flags; if (sf & SYSC_HAS_SIDLEMODE) { - idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? - HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; + /* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ + if (oh->flags & HWMOD_SWSUP_SIDLE || + !(oh->class->sysc->idlemodes & + (SIDLE_SMART | SIDLE_SMART_WKUP))) + idlemode = HWMOD_IDLEMODE_FORCE; + else + idlemode = HWMOD_IDLEMODE_SMART; _set_slave_idlemode(oh, idlemode, &v); } -- cgit v0.10.2 From 84774e615749acfce6b2f679b95924dffb5f5de1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 5 Jul 2012 15:15:36 +0100 Subject: of: address: Don't fail a lookup just because a node has no reg property Sometimes it doesn't make any sense for a node to have an address. In this case device lookup will always be unsuccessful because we currently assume every node will have a reg property. This patch changes the semantics so that the resource address and the lookup address will only be compared if one exists. Things like AUXDATA() rely on of_dev_lookup to return the lookup entry of a particular device in order to do things like apply platform_data to a device. However, this is currently broken for nodes which do not have a reg property, meaning that platform_data can not be passed in those cases. Acked-by: Rob Herring Acked-by: Arnd Bergmann Signed-off-by: Lee Jones diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 343ad29..9600480 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -317,10 +317,9 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l for(; lookup->compatible != NULL; lookup++) { if (!of_device_is_compatible(np, lookup->compatible)) continue; - if (of_address_to_resource(np, 0, &res)) - continue; - if (res.start != lookup->phys_addr) - continue; + if (!of_address_to_resource(np, 0, &res)) + if (res.start != lookup->phys_addr) + continue; pr_debug("%s: devname=%s\n", np->full_name, lookup->name); return lookup; } -- cgit v0.10.2 From c57920e6c23350b08c1b05606aafe356ebc6d8cc Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 15 Jun 2012 09:27:54 +0100 Subject: ARM: ux500: Fix build errors/warnings when MACH_UX500_DT is not set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When MACH_UX500_DT and all related Device Tree configurations are forced off the warning and error below prevent the kernel from compiling. This simple patch fixes both issues and allows for full build and boot of ST-Ericsson's low-cost development board, Snowball. Warnings fixed: arch/arm/mach-ux500/board-mop500.c:680:32: warning: ‘snowball_of_platform_devs’ defined but not used Errors fixed: arch/arm/mach-ux500/timer.c: In function ‘ux500_timer_init’: arch/arm/mach-ux500/timer.c:66:3: error: implicit declaration of function ‘of_find_matching_node’ arch/arm/mach-ux500/timer.c:66:6: warning: assignment makes pointer from integer without a cast Cc: stable@vger.kernel.org Acked-by: Linus Walleij Signed-off-by: Lee Jones diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 1509a3c..461012a 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -625,11 +625,6 @@ static struct platform_device *snowball_platform_devs[] __initdata = { &ab8500_device, }; -static struct platform_device *snowball_of_platform_devs[] __initdata = { - &snowball_led_dev, - &snowball_key_dev, -}; - static void __init mop500_init_machine(void) { struct device *parent = NULL; @@ -769,6 +764,11 @@ MACHINE_END #ifdef CONFIG_MACH_UX500_DT +static struct platform_device *snowball_of_platform_devs[] __initdata = { + &snowball_led_dev, + &snowball_key_dev, +}; + struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { /* Requires DMA and call-back bindings. */ OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat), diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c index 741e71f..66e7f00 100644 --- a/arch/arm/mach-ux500/timer.c +++ b/arch/arm/mach-ux500/timer.c @@ -63,8 +63,10 @@ static void __init ux500_timer_init(void) /* TODO: Once MTU has been DT:ed place code above into else. */ if (of_have_populated_dt()) { +#ifdef CONFIG_OF np = of_find_matching_node(NULL, prcmu_timer_of_match); if (!np) +#endif goto dt_fail; tmp_base = of_iomap(np, 0); -- cgit v0.10.2 From 2b667a2d8005e7c8362a77365cedbcd71fa5d6c1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 6 Jul 2012 15:59:01 +0100 Subject: ARM: ux500: Over-ride the DT device naming scheme for pinctrl When pin control mapping tables are written the registered device name is supplied for use in name-based searches within the pinctrl driver. In the case of the DB8500 the string "pinctrl-db8500" is used. However, when we register the driver with Device Tree, its naming convention uses something that looks more like "pinctrl.2". To work around the device naming inconsistencies between devices registered via platform code and the ones registered by Device Tree, we use AUXDATA to over-ride the Device Tree naming scheme. Acked-by: Linus Walleij Signed-off-by: Lee Jones diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 461012a..4fd93f5 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -786,6 +786,8 @@ struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL), OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL), OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL), + /* Requires device name bindings. */ + OF_DEV_AUXDATA("stericsson,nmk_pinctrl", 0, "pinctrl-db8500", NULL), {}, }; -- cgit v0.10.2 From 873e9f7a3b8a5ca36085437da364654bfe3e5974 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 6 Jul 2012 17:20:05 +0900 Subject: ARM: shmobile: fix platsmp.c build when ARCH_SH73A0=n Fix build error in the case of SMP=y but ARCH_SH73A0=n introduced by: 9601e87 ARM: shmobile: fix smp build The use of of_machine_is_compatible() will link in the the SoC-specific symbols: "sh73a0_get_core_count", "sh73a0_smp_prepare_cpus", "sh73a0_secondary_init" and "sh73a0_boot_secondary". This patch adds an ugly #ifdef wrapper as a stop-gap solution. Signed-off-by: Magnus Damm Tested-by: Tested-by: Simon Horman Acked-by: "Rafael J. Wysocki" Signed-off-by: Arnd Bergmann diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index e859fcd..fde0d23 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -22,8 +22,13 @@ #include #include +#ifdef CONFIG_ARCH_SH73A0 #define is_sh73a0() (machine_is_ag5evm() || machine_is_kota2() || \ of_machine_is_compatible("renesas,sh73a0")) +#else +#define is_sh73a0() (0) +#endif + #define is_r8a7779() machine_is_marzen() #ifdef CONFIG_ARCH_EMEV2 -- cgit v0.10.2 From 06b4ba529528fbf9c24ce37b7618f4b0264750e2 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 6 Jul 2012 11:20:28 -0700 Subject: ARM: OMAP2+: omap2plus_defconfig: EHCI driver is not stable, disable it The EHCI driver is not stable enough to be enabled by default. In v3.5, it has at least the following problems: - warning dump during bootup - hang during suspend - prevents CORE powerdomain from entering retention during idle (even when no USB devices connected.) This demonstrates that this driver has not been thoroughly tested and therfore should not be enabled in the default defconfig. In addition, the problems above cause new PM regressions which need be addressed before this driver should be enabled in the default defconfig. Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 9854ff4..11828e6 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -176,7 +176,6 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y -CONFIG_USB_EHCI_HCD=y CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y CONFIG_USB_LIBUSUAL=y -- cgit v0.10.2