From 5dc06b7ea31a41707ab67e3caad5127bd45069b6 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Fri, 20 Jan 2012 18:14:00 +0100 Subject: ARM: OMAP2+: omap_device: Replace dev_warn by dev_dbg in omap_device_build_from_dt This warning becomes a little bit too verbose with the increase of device nodes in some DTS files. Change it to debug only. Signed-off-by: Benoit Cousson Acked-by: Kevin Hilman --- arch/arm/plat-omap/omap_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/plat-omap/omap_device.c') diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index e8d98693d2d..69fde03729c 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -348,7 +348,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) oh_cnt = of_property_count_strings(node, "ti,hwmods"); if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { - dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n"); + dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); return -ENODEV; } -- cgit v1.2.3-70-g09d2 From 993e4fbd7822cdf874fcf9f1b054a323d67ccf97 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Mon, 20 Feb 2012 09:43:29 -0800 Subject: ARM: OMAP: omap_device: Expose omap_device_{alloc, delete, register} Expose omap_device_{alloc, delete, register} so we can use them outside of omap_device.c. This approach allows users, which need to manipulate an archdata member of a device before it is registered, to do so. This is also useful for users who have their devices created very early so they can be used at ->reserve() time to reserve CMA memory. The immediate use case for this is to set the private iommu archdata member, which binds a device to its associated iommu controller. This way, generic code will be able to attach omap devices to their iommus, without calling any omap-specific API. With this in hand, we can further clean the existing mainline OMAP iommu driver and its mainline users, and focus on generic IOMMU approaches for future users (rpmsg/remoteproc and the upcoming generic DMA API). This patch is still considered an interim solution until DT fully materializes for omap; at that point, this functionality will be removed as DT will take care of creating the devices and configuring them correctly. Tested on OMAP4 with a generic rpmsg/remoteproc that doesn't use any omap-specific IOMMU API anymore. Signed-off-by: Ohad Ben-Cohen Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/include/plat/omap_device.h | 7 +++++++ arch/arm/plat-omap/omap_device.c | 13 +++---------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/arm/plat-omap/omap_device.c') diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index 51423d2727a..05f7615b61f 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -100,6 +100,13 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, struct omap_device_pm_latency *pm_lats, int pm_lats_cnt, int is_early_device); +struct omap_device *omap_device_alloc(struct platform_device *pdev, + struct omap_hwmod **ohs, int oh_cnt, + struct omap_device_pm_latency *pm_lats, + int pm_lats_cnt); +void omap_device_delete(struct omap_device *od); +int omap_device_register(struct platform_device *pdev); + void __iomem *omap_device_get_rt_va(struct omap_device *od); struct device *omap_device_get_by_hwmod_name(const char *oh_name); diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index e8d98693d2d..f72fafc9e9f 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -97,14 +97,7 @@ #define USE_WAKEUP_LAT 0 #define IGNORE_WAKEUP_LAT 1 -static int omap_device_register(struct platform_device *pdev); static int omap_early_device_register(struct platform_device *pdev); -static struct omap_device *omap_device_alloc(struct platform_device *pdev, - struct omap_hwmod **ohs, int oh_cnt, - struct omap_device_pm_latency *pm_lats, - int pm_lats_cnt); -static void omap_device_delete(struct omap_device *od); - static struct omap_device_pm_latency omap_default_latency[] = { { @@ -509,7 +502,7 @@ static int omap_device_fill_resources(struct omap_device *od, * * Returns an struct omap_device pointer or ERR_PTR() on error; */ -static struct omap_device *omap_device_alloc(struct platform_device *pdev, +struct omap_device *omap_device_alloc(struct platform_device *pdev, struct omap_hwmod **ohs, int oh_cnt, struct omap_device_pm_latency *pm_lats, int pm_lats_cnt) @@ -591,7 +584,7 @@ oda_exit1: return ERR_PTR(ret); } -static void omap_device_delete(struct omap_device *od) +void omap_device_delete(struct omap_device *od) { if (!od) return; @@ -817,7 +810,7 @@ static struct dev_pm_domain omap_device_pm_domain = { * platform_device_register() on the underlying platform_device. * Returns the return value of platform_device_register(). */ -static int omap_device_register(struct platform_device *pdev) +int omap_device_register(struct platform_device *pdev) { pr_debug("omap_device: %s: registering\n", pdev->name); -- cgit v1.2.3-70-g09d2 From 9cf793f9b8b1ba9414e2a7591b2e911885f85a27 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 20 Feb 2012 09:43:30 -0800 Subject: ARM: OMAP: convert omap_device_build() and callers to __init Building omap_devices should only be done at init time, and since omap_device_build() is using early_platform calls which are also __init, this ensures that omap_device isn't trying to use functions that disappear. Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 8 ++++---- arch/arm/mach-omap2/gpio.c | 2 +- arch/arm/mach-omap2/mcbsp.c | 2 +- arch/arm/mach-omap2/pm.c | 2 +- arch/arm/mach-omap2/sr_device.c | 2 +- arch/arm/plat-omap/omap_device.c | 7 ++++--- 6 files changed, 12 insertions(+), 11 deletions(-) (limited to 'arch/arm/plat-omap/omap_device.c') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 283d11eae69..01cffcea936 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -276,7 +276,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data } #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) -static inline void omap_init_mbox(void) +static inline void __init omap_init_mbox(void) { struct omap_hwmod *oh; struct platform_device *pdev; @@ -337,7 +337,7 @@ static inline void omap_init_audio(void) {} #if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \ defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE) -static void omap_init_mcpdm(void) +static void __init omap_init_mcpdm(void) { struct omap_hwmod *oh; struct platform_device *pdev; @@ -358,7 +358,7 @@ static inline void omap_init_mcpdm(void) {} #if defined(CONFIG_SND_OMAP_SOC_DMIC) || \ defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE) -static void omap_init_dmic(void) +static void __init omap_init_dmic(void) { struct omap_hwmod *oh; struct platform_device *pdev; @@ -380,7 +380,7 @@ static inline void omap_init_dmic(void) {} #include -static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) +static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) { struct platform_device *pdev; char *name = "omap2_mcspi"; diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 8cbfbc2918c..64c0caed951 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -24,7 +24,7 @@ #include #include -static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) +static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) { struct platform_device *pdev; struct omap_gpio_platform_data *pdata; diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index fb4bcf81a18..5f8a876e4fd 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -122,7 +122,7 @@ static int omap3_enable_st_clock(unsigned int id, bool enable) return 0; } -static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) +static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) { int id, count = 1; char *name = "omap-mcbsp"; diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 1881fe91514..fb9b85bfc30 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -28,7 +28,7 @@ static struct omap_device_pm_latency *pm_lats; -static int _init_omap_device(char *name) +static int __init _init_omap_device(char *name) { struct omap_hwmod *oh; struct platform_device *pdev; diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index 9f43fcc05d3..78c9437913c 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -69,7 +69,7 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, sr_data->nvalue_count = count; } -static int sr_dev_init(struct omap_hwmod *oh, void *user) +static int __init sr_dev_init(struct omap_hwmod *oh, void *user) { struct omap_sr_data *sr_data; struct platform_device *pdev; diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index f72fafc9e9f..2d00ab01d15 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -1,3 +1,4 @@ + /* * omap_device implementation * @@ -612,7 +613,7 @@ void omap_device_delete(struct omap_device *od) * information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise, * passes along the return value of omap_device_build_ss(). */ -struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, +struct platform_device __init *omap_device_build(const char *pdev_name, int pdev_id, struct omap_hwmod *oh, void *pdata, int pdata_len, struct omap_device_pm_latency *pm_lats, @@ -645,7 +646,7 @@ struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, * platform_device record. Returns an ERR_PTR() on error, or passes * along the return value of omap_device_register(). */ -struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, +struct platform_device __init *omap_device_build_ss(const char *pdev_name, int pdev_id, struct omap_hwmod **ohs, int oh_cnt, void *pdata, int pdata_len, struct omap_device_pm_latency *pm_lats, @@ -710,7 +711,7 @@ odbs_exit: * platform_early_add_device() on the underlying platform_device. * Returns 0 by default. */ -static int omap_early_device_register(struct platform_device *pdev) +static int __init omap_early_device_register(struct platform_device *pdev) { struct platform_device *devices[1]; -- cgit v1.2.3-70-g09d2 From 3ec2decbb6dfcdbbb6e6a8ddf5adc7edbc429ed7 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 15 Feb 2012 11:47:45 -0800 Subject: ARM: OMAP: omap_device: remove omap_device_parent Currently all omap_devices are forced to have the dummy device 'omap_device_parent' as a parent. This was used to distinguish omap_devices from "normal" platform_devices in the OMAP PM core code. Now that we implement the PM core using PM domains, this is no longer needed, and is removed. This also frees up omap_devices to have a more complex parent/child relationships that model actual device relationships. The only in-tree user of omap_device_parent was the OMAP PM layer to handle lost-context count for omap_devices. That is now converted to use the presence of the omap_device_pm_domain instead. Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/include/plat/omap_device.h | 2 +- arch/arm/plat-omap/omap-pm-noop.c | 2 +- arch/arm/plat-omap/omap_device.c | 12 ++---------- 3 files changed, 4 insertions(+), 12 deletions(-) (limited to 'arch/arm/plat-omap/omap_device.c') diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index 05f7615b61f..4327b2c90c3 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -36,7 +36,7 @@ #include -extern struct device omap_device_parent; +extern struct dev_pm_domain omap_device_pm_domain; /* omap_device._state values */ #define OMAP_DEVICE_STATE_UNKNOWN 0 diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c index 3dc3801aace..5a97b4d98d4 100644 --- a/arch/arm/plat-omap/omap-pm-noop.c +++ b/arch/arm/plat-omap/omap-pm-noop.c @@ -319,7 +319,7 @@ int omap_pm_get_dev_context_loss_count(struct device *dev) if (WARN_ON(!dev)) return -ENODEV; - if (dev->parent == &omap_device_parent) { + if (dev->pm_domain == &omap_device_pm_domain) { count = omap_device_get_context_loss_count(pdev); } else { WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device", diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 2d00ab01d15..1ae9d6f653a 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -314,8 +314,6 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od, } -static struct dev_pm_domain omap_device_pm_domain; - /** * omap_device_build_from_dt - build an omap_device with multiple hwmods * @pdev_name: name of the platform_device driver to use @@ -793,7 +791,7 @@ static int _od_resume_noirq(struct device *dev) #define _od_resume_noirq NULL #endif -static struct dev_pm_domain omap_device_pm_domain = { +struct dev_pm_domain omap_device_pm_domain = { .ops = { SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, _od_runtime_idle) @@ -815,7 +813,6 @@ int omap_device_register(struct platform_device *pdev) { pr_debug("omap_device: %s: registering\n", pdev->name); - pdev->dev.parent = &omap_device_parent; pdev->dev.pm_domain = &omap_device_pm_domain; return platform_device_add(pdev); } @@ -1124,11 +1121,6 @@ int omap_device_enable_clocks(struct omap_device *od) return 0; } -struct device omap_device_parent = { - .init_name = "omap", - .parent = &platform_bus, -}; - static struct notifier_block platform_nb = { .notifier_call = _omap_device_notifier_call, }; @@ -1136,6 +1128,6 @@ static struct notifier_block platform_nb = { static int __init omap_device_init(void) { bus_register_notifier(&platform_bus_type, &platform_nb); - return device_register(&omap_device_parent); + return 0; } core_initcall(omap_device_init); -- cgit v1.2.3-70-g09d2 From b7c39a3f59ae55aa49ebf670e9329bc7da6d3c65 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sat, 3 Mar 2012 13:15:33 -0700 Subject: ARM: OMAP2+: omap_device: call all suspend, resume callbacks when OMAP_DEVICE_NO_IDLE_ON_SUSPEND is set During system suspend, when OMAP_DEVICE_NO_IDLE_ON_SUSPEND is set on an omap_device, call the corresponding driver's ->suspend() and ->suspend_noirq() callbacks (if present). Similarly, during resume, the driver's ->resume() and ->resume_noirq() callbacks must both be called, if present. (The previous code only called ->suspend_noirq() and ->resume_noirq().) If all of these callbacks aren't called, some important driver suspend/resume code may not get executed. In current mainline, the bug fixed by this patch is only a problem under the following conditions: - the kernel is running on an OMAP4 - an OMAP UART is used as a console - the kernel command line parameter 'no_console_suspend' is specified - and the system enters suspend ("echo mem > /sys/power/state"). Under this combined circumstance, the system cannot be awakened via the serial port after commit be4b0281956c5cae4f63f31f11d07625a6988766c ("tty: serial: OMAP: block idle while the UART is transferring data in PIO mode"). This is because the OMAP UART driver's ->suspend() callback is never called. The ->suspend() callback would have called uart_suspend_port() which in turn would call enable_irq_wake(). Since enable_irq_wake() isn't called for the UART's IRQ, check_wakeup_irqs() would mask off the UART IRQ in the GIC. On v3.3 kernels prior to the above commit, serial resume from suspend presumably occurred via the PRCM interrupt. The UART was in smart-idle mode, so it was able to send a PRCM wakeup which in turn would be converted into a PRCM interrupt to the GIC, waking up the kernel. But after the above commit, when the system is suspended in the middle of a UART transmit, the UART IP block would be in no-idle mode. In no-idle mode, the UART won't generate wakeups to the PRCM when incoming characters are received; only GIC interrupts. But since the UART driver's ->suspend() callback is never called, uart_suspend_port() and enable_irq_wake() is never called; so the UART interrupt is masked by check_wakeup_irqs() and the UART can't wake up the MPU. The remaining mechanism that could have awakened the system would have been I/O chain wakeups. These wouldn't be active because the console UART's clocks are never disabled when no_console_suspend is used, preventing the full chip from idling. Also, current mainline doesn't yet support full chip idle states for OMAP4, so I/O chain wakeups are not enabled. This patch is the result of a collaboration. John Stultz and Andy Green reported the serial wakeup problem that led to the discovery of this problem. Kevin Hilman narrowed the problem down to the use of no_console_suspend. Signed-off-by: Paul Walmsley Cc: John Stultz Cc: Andy Green Reviewed-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/omap_device.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'arch/arm/plat-omap/omap_device.c') diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 1ae9d6f653a..6de28ea3cd6 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -754,14 +754,12 @@ static int _od_suspend_noirq(struct device *dev) struct omap_device *od = to_omap_device(pdev); int ret; - if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND) - return pm_generic_suspend_noirq(dev); - ret = pm_generic_suspend_noirq(dev); if (!ret && !pm_runtime_status_suspended(dev)) { if (pm_generic_runtime_suspend(dev) == 0) { - omap_device_idle(pdev); + if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)) + omap_device_idle(pdev); od->flags |= OMAP_DEVICE_SUSPENDED; } } @@ -774,13 +772,11 @@ static int _od_resume_noirq(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct omap_device *od = to_omap_device(pdev); - if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND) - return pm_generic_resume_noirq(dev); - if ((od->flags & OMAP_DEVICE_SUSPENDED) && !pm_runtime_status_suspended(dev)) { od->flags &= ~OMAP_DEVICE_SUSPENDED; - omap_device_enable(pdev); + if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)) + omap_device_enable(pdev); pm_generic_runtime_resume(dev); } -- cgit v1.2.3-70-g09d2