Re: [PATCHv5 1/3] OMAP: I2C: Reset support
On Wednesday 03 August 2011 04:53 AM, Kevin Hilman wrote: Shubhrajyoti Dshubhrajy...@ti.com writes: Under some error conditions the i2c driver may do a reset. ^^ minor: extra whitespace Adding a reset field and support in the platform. s/platform/device-specific code/ Yes will fix these. Signed-off-by: Shubhrajyoti Dshubhrajy...@ti.com That being said, omap_device_shutdown() should already do a clean shutdown + reset for you, and i2c-omap.h already has a pointer for -device_shutdown() so a new device_reset() should not be needed. IOW, simply adding pdata-device_shutdown = omap_device_shutdown() should work. i2C has a special reset sequence ie Disable - reset - enable - Poll on reset done. This function is implemented in omap_i2c_reset. The omap_hwmod_reset calls - _reset which calls ocp_softrest or custom reset if it is present.The latter is true for I2C. However I see that omap_device_shutdown - _assert_hardreset However for I2c there doesnt seem to be a HW reset line. Am I missing something? Kevin --- arch/arm/plat-omap/i2c.c | 18 ++ include/linux/i2c-omap.h |1 + 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 2388b8e..be36cac 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -146,6 +146,22 @@ static struct omap_device_pm_latency omap_i2c_latency[] = { .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, }, }; +/** + * omap2_i2c_reset - reset the omap i2c module. + * @dev: struct device* + */ + +static int omap2_i2c_reset(struct device *dev) +{ + int r = 0; + struct platform_device *pdev = to_platform_device(dev); + struct omap_device *odev = to_omap_device(pdev); + struct omap_hwmod *oh; + + oh = odev-hwmods[0]; + r = omap_hwmod_reset(oh); + return r; +} static inline int omap2_i2c_add_bus(int bus_id) { @@ -187,6 +203,8 @@ static inline int omap2_i2c_add_bus(int bus_id) */ if (cpu_is_omap34xx()) pdata-set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; + + pdata-device_reset = omap2_i2c_reset; od = omap_device_build(name, bus_id, oh, pdata, sizeof(struct omap_i2c_bus_platform_data), omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0); diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index 98ae49b..8aa91b6 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -38,6 +38,7 @@ struct omap_i2c_bus_platform_data { int (*device_enable) (struct platform_device *pdev); int (*device_shutdown) (struct platform_device *pdev); int (*device_idle) (struct platform_device *pdev); + int (*device_reset) (struct device *dev); }; #endif -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] OMAP: DSS2: Don't allow moving managers away from enabled displays
On Wed, 2011-08-03 at 22:10 +0200, Daniel Morsing wrote: If a manager is moved while attached to an enabled display, the DSS system will be left in an inconsistent state. This will eventually cause a kernel oops when the enabled display is disabled. Fix this by not allowing the user to move a manager away from an enabled display. Thanks, applying. Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] OMAPFB: make debug message more useful
On Wed, 2011-07-06 at 12:08 -0500, Andy Doan wrote: Make the debug message useful by printing the name of the device that no associated driver could be found for. Signed-off-by: Andy Doan andy.d...@linaro.org --- drivers/video/omap2/omapfb/omapfb-main.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 602b71a..e5a64b3 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2373,7 +2373,8 @@ static int omapfb_probe(struct platform_device *pdev) omap_dss_get_device(dssdev); if (!dssdev-driver) { - dev_err(pdev-dev, no driver for display\n); + dev_err(pdev-dev, no driver for display: %s\n, + dssdev-name); r = -ENODEV; } Thanks, applying. Tomi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Q] SW-ECC to HW-ECC (OMAP3)
While migrating from .33 to .37 kernel I found, that HW-ECC is used by default. I found that this is set in omap2.c: pdata-ecc_opt = OMAP_ECC_HAMMING_CODE_HW; Unfortunatly setting it back to pdata-ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; doesn't prevent me from getting messages like: uncorrectable error : uncorrectable error : mtd-read(0xd18 bytes from 0x7eae8) returned ECC error So what else has to be set? I couldn't found it. Other way maybe to keep it at HW-ECC. Is this significant faster than SW-ECC? But howto get nandwrite (mtd-utils) or fw_setenv (uboot) to handle HW-ECC? Do I have to use just the --noecc option? When using the fw_setenv command I get CRC errors in environment with next boot. Thanks Arno -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 09/22] gpio/omap: cleanup omap1 related macros
From: Charulatha V ch...@ti.com mpuio_init() function is defined under #ifdefs. It is required only in case of MPUIO bank type and only when PM operations are supported by it. This is applicable only in case of OMAP16xx SoC's MPUIO GPIO bank type. For all the other cases it is a dummy function. Hence clean up the same and remove all the OMAP SoC specific #ifdefs. bank_is_mpuio() is defined as a check to identify if the bank type is MPUIO. It is not required to define it separately as zero for OMAP2PLUS. Remove this. Signed-off-by: Charulatha V ch...@ti.com --- drivers/gpio/gpio-omap.c | 19 --- 1 files changed, 0 insertions(+), 19 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 996e54b..e841ac1 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -778,14 +778,8 @@ static struct irq_chip gpio_irq_chip = { /*-*/ -#ifdef CONFIG_ARCH_OMAP1 - #define bank_is_mpuio(bank)((bank)-method == METHOD_MPUIO) -#ifdef CONFIG_ARCH_OMAP16XX - -#include linux/platform_device.h - static int omap_mpuio_suspend_noirq(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -847,17 +841,6 @@ static inline void mpuio_init(struct gpio_bank *bank) (void) platform_device_register(omap_mpuio_device); } -#else -static inline void mpuio_init(struct gpio_bank *bank) {} -#endif /* 16xx */ - -#else - -#define bank_is_mpuio(bank)0 -static inline void mpuio_init(struct gpio_bank *bank) {} - -#endif - /*-*/ /* REVISIT these are stupid implementations! replace by ones that @@ -1078,10 +1061,8 @@ static void __devinit omap_gpio_chip_init(struct gpio_bank *bank) bank-chip.to_irq = gpio_2irq; if (bank_is_mpuio(bank)) { bank-chip.label = mpuio; -#ifdef CONFIG_ARCH_OMAP16XX if (bank-regs-wkup_status) bank-chip.dev = omap_mpuio_device.dev; -#endif bank-chip.base = OMAP_MPUIO(0); } else { bank-chip.label = gpio; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 11/22] gpio/omap: remove hardcoded offsets in ctxt save/restore
It is not required to use hard-coded offsets any more in context save and restore functions and instead use the generic offsets which have been correctly initialized during device registration. Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap2/gpio.c |2 + arch/arm/plat-omap/include/plat/gpio.h |1 + drivers/gpio/gpio-omap.c | 41 ++- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 8745c3a..0ee9a55 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -103,6 +103,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-regs-irqstatus = OMAP24XX_GPIO_IRQSTATUS1; pdata-regs-irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2; pdata-regs-irqenable = OMAP24XX_GPIO_IRQENABLE1; + pdata-regs-irqenable2 = OMAP24XX_GPIO_IRQENABLE2; pdata-regs-set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1; pdata-regs-clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1; pdata-regs-debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; @@ -125,6 +126,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-regs-irqstatus = OMAP4_GPIO_IRQSTATUS0; pdata-regs-irqstatus2 = OMAP4_GPIO_IRQSTATUS1; pdata-regs-irqenable = OMAP4_GPIO_IRQSTATUSSET0; + pdata-regs-irqenable2 = OMAP4_GPIO_IRQSTATUSSET1; pdata-regs-set_irqenable = OMAP4_GPIO_IRQSTATUSSET0; pdata-regs-clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0; pdata-regs-debounce = OMAP4_GPIO_DEBOUNCINGTIME; diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 7d12fe8..0ad4f49 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -184,6 +184,7 @@ struct omap_gpio_reg_offs { u16 irqstatus; u16 irqstatus2; u16 irqenable; + u16 irqenable2; u16 set_irqenable; u16 clr_irqenable; u16 debounce; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index be561be..e7c9fe5 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1348,45 +1348,42 @@ void omap2_gpio_resume_after_idle(void) static void omap_gpio_save_context(struct gpio_bank *bank) { bank-context.irqenable1 = - __raw_readl(bank-base + OMAP24XX_GPIO_IRQENABLE1); + __raw_readl(bank-base + bank-regs-irqenable); bank-context.irqenable2 = - __raw_readl(bank-base + OMAP24XX_GPIO_IRQENABLE2); + __raw_readl(bank-base + bank-regs-irqenable2); bank-context.wake_en = - __raw_readl(bank-base + OMAP24XX_GPIO_WAKE_EN); - bank-context.ctrl = __raw_readl(bank-base + OMAP24XX_GPIO_CTRL); - bank-context.oe = __raw_readl(bank-base + OMAP24XX_GPIO_OE); + __raw_readl(bank-base + bank-regs-wkup_status); + bank-context.ctrl = __raw_readl(bank-base + bank-regs-ctrl); + bank-context.oe = __raw_readl(bank-base + bank-regs-direction); bank-context.leveldetect0 = - __raw_readl(bank-base + OMAP24XX_GPIO_LEVELDETECT0); + __raw_readl(bank-base + bank-regs-leveldetect0); bank-context.leveldetect1 = - __raw_readl(bank-base + OMAP24XX_GPIO_LEVELDETECT1); + __raw_readl(bank-base + bank-regs-leveldetect1); bank-context.risingdetect = - __raw_readl(bank-base + OMAP24XX_GPIO_RISINGDETECT); + __raw_readl(bank-base + bank-regs-risingdetect); bank-context.fallingdetect = - __raw_readl(bank-base + OMAP24XX_GPIO_FALLINGDETECT); - bank-context.dataout = - __raw_readl(bank-base + OMAP24XX_GPIO_DATAOUT); + bank-context.dataout = __raw_readl(bank-base + bank-regs-dataout); } static void omap_gpio_restore_context(struct gpio_bank *bank) { __raw_writel(bank-context.irqenable1, - bank-base + OMAP24XX_GPIO_IRQENABLE1); + bank-base + bank-regs-irqenable); __raw_writel(bank-context.irqenable2, - bank-base + OMAP24XX_GPIO_IRQENABLE2); + bank-base + bank-regs-irqenable2); __raw_writel(bank-context.wake_en, - bank-base + OMAP24XX_GPIO_WAKE_EN); - __raw_writel(bank-context.ctrl, bank-base + OMAP24XX_GPIO_CTRL); - __raw_writel(bank-context.oe, bank-base + OMAP24XX_GPIO_OE); + bank-base + bank-regs-wkup_status); + __raw_writel(bank-context.ctrl, bank-base + bank-regs-ctrl); + __raw_writel(bank-context.oe, bank-base + bank-regs-direction);
[PATCH v5 17/22] gpio/omap: fix bankwidth for OMAP7xx MPUIO
From: Charulatha V ch...@ti.com In all OMAP1 SoCs, the MPUIO bank width is 16 bits. But, in OMAP7xx, it is wrongly initialised to 32. Fix this. Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap1/gpio7xx.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index 8d25052..3ca9600 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c @@ -52,8 +52,8 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { .virtual_irq_start = IH_MPUIO_BASE, - .bank_width = 32, .is_mpuio = true, + .bank_width = 16, .bank_stride= 2, .regs = omap7xx_mpuio_regs, }; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 19/22] gpio/omap: optimize suspend and resume functions
There is no need to operate on all the banks every time the function is called. Just operate on the current bank passed by the framework. Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com --- drivers/gpio/gpio-omap.c | 54 + 1 files changed, 25 insertions(+), 29 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index e71cfcc..ce93898 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1051,6 +1051,8 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) goto err_free; } + platform_set_drvdata(pdev, bank); + pm_runtime_enable(bank-dev); pm_runtime_irq_safe(bank-dev); if (IS_ERR_VALUE(pm_runtime_get_sync(bank-dev) 0)) { @@ -1088,45 +1090,39 @@ err_exit: static int omap_gpio_suspend(struct device *dev) { - struct gpio_bank *bank; - - list_for_each_entry(bank, omap_gpio_list, node) { - void __iomem *base = bank-base; - void __iomem *wake_status; - unsigned long flags; - - if (!bank-regs-wkup_status) - return 0; + struct platform_device *pdev = to_platform_device(dev); + struct gpio_bank *bank = platform_get_drvdata(pdev); + void __iomem *base = bank-base; + void __iomem *wake_status; + unsigned long flags; - wake_status = bank-base + bank-regs-wkup_status; + if (!bank-regs-wkup_status || !bank-suspend_wakeup) + return 0; - spin_lock_irqsave(bank-lock, flags); - bank-saved_wakeup = __raw_readl(wake_status); - _gpio_rmw(base, bank-regs-wkup_status, - bank-suspend_wakeup, 1); - spin_unlock_irqrestore(bank-lock, flags); - pm_runtime_put_sync(dev); - } + wake_status = bank-base + bank-regs-wkup_status; + spin_lock_irqsave(bank-lock, flags); + bank-saved_wakeup = __raw_readl(wake_status); + _gpio_rmw(base, bank-regs-wkup_status, bank-suspend_wakeup, 1); + spin_unlock_irqrestore(bank-lock, flags); + pm_runtime_put_sync(dev); return 0; } static int omap_gpio_resume(struct device *dev) { - struct gpio_bank *bank; - - list_for_each_entry(bank, omap_gpio_list, node) { - void __iomem *base = bank-base; - unsigned long flags; + struct platform_device *pdev = to_platform_device(dev); + struct gpio_bank *bank = platform_get_drvdata(pdev); + void __iomem *base = bank-base; + unsigned long flags; - if (!bank-regs-wkup_status) - return 0; + if (!bank-regs-wkup_status || !bank-saved_wakeup) + return 0; - pm_runtime_get_sync(dev); - spin_lock_irqsave(bank-lock, flags); - _gpio_rmw(base, bank-regs-wkup_status, bank-saved_wakeup, 1); - spin_unlock_irqrestore(bank-lock, flags); - } + pm_runtime_get_sync(dev); + spin_lock_irqsave(bank-lock, flags); + _gpio_rmw(base, bank-regs-wkup_status, bank-saved_wakeup, 1); + spin_unlock_irqrestore(bank-lock, flags); return 0; } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 13/22] gpio/omap: cleanup omap_gpio_mod_init function
With register offsets now defined for respective OMAP versions we can get rid of cpu_class_* checks. This function now has common initialization code for all OMAP versions. Initialization specific to OMAP16xx has been moved within omap16xx_gpio_init(). Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap1/gpio16xx.c | 34 ++- drivers/gpio/gpio-omap.c | 71 +++- 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index f619805..61b1998 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -24,6 +24,8 @@ #define OMAP1610_GPIO4_BASE0xfffbbc00 #define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE +#define SYSCONFIG_WORD 0x14 /* smart idle, enable wakeup */ + /* mpu gpio */ static struct __initdata resource omap16xx_mpu_gpio_resources[] = { { @@ -218,12 +220,42 @@ static struct __initdata platform_device * omap16xx_gpio_dev[] = { static int __init omap16xx_gpio_init(void) { int i; + void __iomem *base; + struct resource *res; + struct platform_device *pdev; + struct omap_gpio_platform_data *pdata; if (!cpu_is_omap16xx()) return -EINVAL; - for (i = 0; i ARRAY_SIZE(omap16xx_gpio_dev); i++) + for (i = 0; i ARRAY_SIZE(omap16xx_gpio_dev); i++) { + pdev = omap16xx_gpio_dev[i]; + pdata = pdev-dev.platform_data; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) { + dev_err(pdev-dev, Invalid mem resource.\n); + return -ENODEV; + } + + base = ioremap(res-start, resource_size(res)); + if (unlikely(!base)) { + dev_err(pdev-dev, ioremap failed.\n); + return -ENOMEM; + } + + __raw_writel(SYSCONFIG_WORD, base + OMAP1610_GPIO_SYSCONFIG); + iounmap(base); + + /* +* Enable system clock for GPIO module. +* The CAM_CLK_CTRL *is* really the right place. +*/ + omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, + ULPD_CAM_CLK_CTRL); + platform_device_register(omap16xx_gpio_dev[i]); + } return 0; } diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 21cb0d4..f6855e5 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -875,62 +875,24 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank) */ static struct lock_class_key gpio_lock_class; -/* TODO: Cleanup cpu_is_* checks */ static void omap_gpio_mod_init(struct gpio_bank *bank) { - if (cpu_class_is_omap2()) { - if (cpu_is_omap44xx()) { - __raw_writel(0x, bank-base + - OMAP4_GPIO_IRQSTATUSCLR0); - __raw_writel(0x, bank-base + -OMAP4_GPIO_DEBOUNCENABLE); - /* Initialize interface clk ungated, module enabled */ - __raw_writel(0, bank-base + OMAP4_GPIO_CTRL); - } else if (cpu_is_omap34xx()) { - __raw_writel(0x, bank-base + - OMAP24XX_GPIO_IRQENABLE1); - __raw_writel(0x, bank-base + - OMAP24XX_GPIO_IRQSTATUS1); - __raw_writel(0x, bank-base + - OMAP24XX_GPIO_DEBOUNCE_EN); - - /* Initialize interface clk ungated, module enabled */ - __raw_writel(0, bank-base + OMAP24XX_GPIO_CTRL); - } - } else if (cpu_class_is_omap1()) { - if (bank_is_mpuio(bank)) { - __raw_writew(0x, bank-base + - OMAP_MPUIO_GPIO_MASKIT / bank-stride); - mpuio_init(bank); - } - if (cpu_is_omap15xx() bank-method == METHOD_GPIO_1510) { - __raw_writew(0x, bank-base - + OMAP1510_GPIO_INT_MASK); - __raw_writew(0x, bank-base - + OMAP1510_GPIO_INT_STATUS); - } - if (cpu_is_omap16xx() bank-method == METHOD_GPIO_1610) { - __raw_writew(0x, bank-base - + OMAP1610_GPIO_IRQENABLE1); - __raw_writew(0x, bank-base - +
[PATCH v5 18/22] gpio/omap: use pm-runtime framework
Call runtime pm APIs pm_runtime_get_sync() and pm_runtime_put_sync() for enabling/disabling clocks appropriately. Remove syscore_ops and instead use dev_pm_ops now. Signed-off-by: Charulatha V ch...@ti.com Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com --- drivers/gpio/gpio-omap.c | 89 ++--- 1 files changed, 67 insertions(+), 22 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0545d8f..bca6dcd 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -79,6 +79,8 @@ struct gpio_bank { struct omap_gpio_reg_offs *regs; }; +static void omap_gpio_mod_init(struct gpio_bank *bank); + #define GPIO_INDEX(bank, gpio) (gpio % bank-width) #define GPIO_BIT(bank, gpio) (1 GPIO_INDEX(bank, gpio)) #define GPIO_MOD_CTRL_BIT BIT(0) @@ -481,6 +483,19 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(bank-lock, flags); + /* +* If this is the first gpio_request for the bank, +* enable the bank module. +*/ + if (!bank-mod_usage) + if (IS_ERR_VALUE(pm_runtime_get_sync(bank-dev) 0)) { + dev_err(bank-dev, %s: GPIO bank %d + pm_runtime_get_sync failed\n, + __func__, bank-id); + spin_unlock_irqrestore(bank-lock, flags); + return -EINVAL; + } + /* Set trigger to none. You need to enable the desired trigger with * request_irq() or set_irq_type(). */ @@ -535,6 +550,19 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) } _reset_gpio(bank, bank-chip.base + offset); + + /* +* If this is the last gpio to be freed in the bank, +* disable the bank module. +*/ + if (!bank-mod_usage) { + if (IS_ERR_VALUE(pm_runtime_put_sync(bank-dev) 0)) { + dev_err(bank-dev, %s: GPIO bank %d + pm_runtime_put_sync failed\n, + __func__, bank-id); + } + } + spin_unlock_irqrestore(bank-lock, flags); } @@ -561,6 +589,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) bank = irq_get_handler_data(irq); isr_reg = bank-base + bank-regs-irqstatus; + pm_runtime_get_sync(bank-dev); if (WARN_ON(!isr_reg)) goto exit; @@ -622,6 +651,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) exit: if (!unmasked) chained_irq_exit(chip, desc); + pm_runtime_put_sync_suspend(bank-dev); } static void gpio_irq_shutdown(struct irq_data *d) @@ -1023,7 +1053,13 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) } pm_runtime_enable(bank-dev); - pm_runtime_get_sync(bank-dev); + pm_runtime_irq_safe(bank-dev); + if (IS_ERR_VALUE(pm_runtime_get_sync(bank-dev) 0)) { + dev_err(bank-dev, %s: GPIO bank %d pm_runtime_get_sync + failed\n, __func__, bank-id); + iounmap(bank-base); + return -EINVAL; + } if (bank-is_mpuio) { if (bank-regs-wkup_status) @@ -1034,6 +1070,13 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) omap_gpio_chip_init(bank); omap_gpio_show_rev(bank); + if (IS_ERR_VALUE(pm_runtime_put_sync(bank-dev) 0)) { + dev_err(bank-dev, %s: GPIO bank %d pm_runtime_put_sync + failed\n, __func__, bank-id); + iounmap(bank-base); + return -EINVAL; + } + list_add_tail(bank-node, omap_gpio_list); return ret; @@ -1044,7 +1087,7 @@ err_exit: return ret; } -static int omap_gpio_suspend(void) +static int omap_gpio_suspend(struct device *dev) { struct gpio_bank *bank; @@ -1063,12 +1106,13 @@ static int omap_gpio_suspend(void) _gpio_rmw(base, bank-regs-wkup_status, bank-suspend_wakeup, 1); spin_unlock_irqrestore(bank-lock, flags); + pm_runtime_put_sync(dev); } return 0; } -static void omap_gpio_resume(void) +static int omap_gpio_resume(struct device *dev) { struct gpio_bank *bank; @@ -1077,18 +1121,16 @@ static void omap_gpio_resume(void) unsigned long flags; if (!bank-regs-wkup_status) - return; + return 0; + pm_runtime_get_sync(dev); spin_lock_irqsave(bank-lock, flags); _gpio_rmw(base, bank-regs-wkup_status, bank-saved_wakeup, 1); spin_unlock_irqrestore(bank-lock, flags);
[PATCH v5 16/22] gpio/omap: remove bank-method METHOD_* macros
From: Charulatha V ch...@ti.com The only bank-type (method) used in the OMAP GPIO driver is MPUIO type as they need to be handled separately. Identify the same using a flag and remove all METHOD_* macros. Signed-off-by: Charulatha V ch...@ti.com Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com --- arch/arm/mach-omap1/gpio15xx.c |3 +-- arch/arm/mach-omap1/gpio16xx.c |6 +- arch/arm/mach-omap1/gpio7xx.c |8 +--- arch/arm/mach-omap2/gpio.c |2 -- arch/arm/plat-omap/include/plat/gpio.h |8 +--- drivers/gpio/gpio-omap.c | 19 ++- 6 files changed, 10 insertions(+), 36 deletions(-) diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 950e467..634903e 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -47,7 +47,7 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { .virtual_irq_start = IH_MPUIO_BASE, - .bank_type = METHOD_MPUIO, + .is_mpuio = true, .bank_width = 16, .bank_stride= 1, .regs = omap15xx_mpuio_regs, @@ -90,7 +90,6 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = { static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { .virtual_irq_start = IH_GPIO_BASE, - .bank_type = METHOD_GPIO_1510, .bank_width = 16, .regs = omap15xx_gpio_regs, }; diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index 61b1998..227e0e8 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -52,7 +52,7 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { .virtual_irq_start = IH_MPUIO_BASE, - .bank_type = METHOD_MPUIO, + .is_mpuio = true, .bank_width = 16, .bank_stride= 1, .regs = omap16xx_mpuio_regs, @@ -99,7 +99,6 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { .virtual_irq_start = IH_GPIO_BASE, - .bank_type = METHOD_GPIO_1610, .bank_width = 16, .regs = omap16xx_gpio_regs, }; @@ -129,7 +128,6 @@ static struct __initdata resource omap16xx_gpio2_resources[] = { static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { .virtual_irq_start = IH_GPIO_BASE + 16, - .bank_type = METHOD_GPIO_1610, .bank_width = 16, .regs = omap16xx_gpio_regs, }; @@ -159,7 +157,6 @@ static struct __initdata resource omap16xx_gpio3_resources[] = { static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { .virtual_irq_start = IH_GPIO_BASE + 32, - .bank_type = METHOD_GPIO_1610, .bank_width = 16, .regs = omap16xx_gpio_regs, }; @@ -189,7 +186,6 @@ static struct __initdata resource omap16xx_gpio4_resources[] = { static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { .virtual_irq_start = IH_GPIO_BASE + 48, - .bank_type = METHOD_GPIO_1610, .bank_width = 16, .regs = omap16xx_gpio_regs, }; diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index cb083c5..8d25052 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c @@ -52,8 +52,8 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { .virtual_irq_start = IH_MPUIO_BASE, - .bank_type = METHOD_MPUIO, .bank_width = 32, + .is_mpuio = true, .bank_stride= 2, .regs = omap7xx_mpuio_regs, }; @@ -94,7 +94,6 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = { static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { .virtual_irq_start = IH_GPIO_BASE, - .bank_type = METHOD_GPIO_7XX, .bank_width = 32, .regs = omap7xx_gpio_regs, }; @@ -124,7 +123,6 @@ static struct __initdata resource omap7xx_gpio2_resources[] = { static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { .virtual_irq_start = IH_GPIO_BASE + 32, - .bank_type = METHOD_GPIO_7XX, .bank_width = 32, .regs = omap7xx_gpio_regs, };
[PATCH v5 22/22] gpio/omap: remove omap_gpio_save_context overhead
Context is now saved dynamically in respective functions whenever and whichever registers are modified. This avoid overhead of saving all registers context in the runtime callback. Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com --- drivers/gpio/gpio-omap.c | 66 -- 1 files changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index eae955a..ee1726d 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -97,6 +97,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) else l = ~(1 gpio); __raw_writel(l, reg); + bank-context.oe = l; } @@ -127,6 +128,7 @@ static void _set_gpio_dataout_mask(struct gpio_bank *bank, int gpio, int enable) else l = ~gpio_bit; __raw_writel(l, reg); + bank-context.dataout = l; } static int _get_gpio_datain(struct gpio_bank *bank, int gpio) @@ -216,9 +218,21 @@ static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, _gpio_rmw(base, bank-regs-fallingdetect, gpio_bit, trigger IRQ_TYPE_EDGE_FALLING); - if (likely(!(bank-non_wakeup_gpios gpio_bit))) + bank-context.leveldetect0 = + __raw_readl(bank-base + bank-regs-leveldetect0); + bank-context.leveldetect1 = + __raw_readl(bank-base + bank-regs-leveldetect1); + bank-context.risingdetect = + __raw_readl(bank-base + bank-regs-risingdetect); + bank-context.fallingdetect = + __raw_readl(bank-base + bank-regs-fallingdetect); + + if (likely(!(bank-non_wakeup_gpios gpio_bit))) { _gpio_rmw(base, bank-regs-wkup_status, gpio_bit, trigger != 0); + bank-context.wake_en = + __raw_readl(bank-base + bank-regs-wkup_status); + } /* This part needs to be executed always for OMAP34xx */ if (cpu_is_omap34xx() || (bank-non_wakeup_gpios gpio_bit)) { @@ -304,6 +318,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) l |= 1 (gpio 1); _gpio_rmw(base, bank-regs-wkup_status, 1 gpio, trigger); + bank-context.wake_en = + __raw_readl(bank-base + bank-regs-wkup_status); __raw_writel(l, reg); } @@ -398,6 +414,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) } __raw_writel(l, reg); + bank-context.irqenable1 = l; } static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) @@ -418,6 +435,7 @@ static void _disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) } __raw_writel(l, reg); + bank-context.irqenable1 = l; } static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) @@ -515,6 +533,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) /* Module is enabled, clocks are not gated */ ctrl = ~GPIO_MOD_CTRL_BIT; __raw_writel(ctrl, reg); + bank-context.ctrl = ctrl; } bank-mod_usage |= 1 offset; @@ -532,9 +551,12 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(bank-lock, flags); - if (bank-regs-wkup_status) + if (bank-regs-wkup_status) { /* Disable wake-up during idle for dynamic tick */ _gpio_rmw(base, bank-regs-wkup_status, 1 offset, 0); + bank-context.wake_en = + __raw_readl(bank-base + bank-regs-wkup_status); + } bank-mod_usage = ~(1 offset); @@ -546,6 +568,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) /* Module is disabled, clocks are gated */ ctrl |= GPIO_MOD_CTRL_BIT; __raw_writel(ctrl, reg); + bank-context.ctrl = ctrl; } _reset_gpio(bank, bank-chip.base + offset); @@ -912,6 +935,9 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) bank-regs-irqenable_inv == false); _gpio_rmw(base, bank-regs-irqenable, l, bank-regs-debounce_en != 0); _gpio_rmw(base, bank-regs-irqenable, l, bank-regs-ctrl != 0); + + bank-context.irqenable1 = + __raw_readl(bank-base + bank-regs-irqenable); } static __init void @@ -1104,6 +1130,8 @@ static int omap_gpio_suspend(struct device *dev) spin_lock_irqsave(bank-lock, flags); bank-saved_wakeup = __raw_readl(wake_status); _gpio_rmw(base, bank-regs-wkup_status, bank-suspend_wakeup, 1); + bank-context.wake_en = + __raw_readl(bank-base + bank-regs-wkup_status);
[PATCH v5 08/22] gpio/omap: further cleanup using wakeup_status register
Wakeup istatus register offset initialized according to OMAP versions during device registration. Use this to avoid version checks. Starting with OMAP4, legacy registers should not be used in combination with the updated regsiters. Use wkup_status register consistently for all SoCs wherever applicable. Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap1/gpio16xx.c |1 + arch/arm/mach-omap2/gpio.c |2 + arch/arm/plat-omap/include/plat/gpio.h |1 + drivers/gpio/gpio-omap.c | 109 ++-- 4 files changed, 24 insertions(+), 89 deletions(-) diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index df4bb44..ed9f285 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -89,6 +89,7 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { .irqenable = OMAP1610_GPIO_IRQENABLE1, .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, + .wkup_status= OMAP1610_GPIO_WAKEUPENABLE, }; static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index cdbc728..fd05cea 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -108,6 +108,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-regs-debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; pdata-regs-debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; pdata-regs-ctrl = OMAP24XX_GPIO_CTRL; + pdata-regs-wkup_status = OMAP24XX_GPIO_WAKE_EN; break; case 2: pdata-bank_type = METHOD_GPIO_44XX; @@ -125,6 +126,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-regs-debounce = OMAP4_GPIO_DEBOUNCINGTIME; pdata-regs-debounce_en = OMAP4_GPIO_DEBOUNCENABLE; pdata-regs-ctrl = OMAP4_GPIO_CTRL; + pdata-regs-wkup_status = OMAP4_GPIO_IRQWAKEN0; break; default: WARN(1, Invalid gpio bank_type\n); diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index cf41743..817997d 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -189,6 +189,7 @@ struct omap_gpio_reg_offs { u16 debounce; u16 debounce_en; u16 ctrl; + u16 wkup_status; bool irqenable_inv; }; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 4d26ba7..996e54b 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -50,10 +50,8 @@ struct gpio_bank { u16 irq; u16 virtual_irq_start; int method; -#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) u32 suspend_wakeup; u32 saved_wakeup; -#endif u32 non_wakeup_gpios; u32 enabled_non_wakeup_gpios; struct gpio_regs context; @@ -598,30 +596,15 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) { struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); + void __iomem *base = bank-base; unsigned long flags; spin_lock_irqsave(bank-lock, flags); -#ifdef CONFIG_ARCH_OMAP16XX - if (bank-method == METHOD_GPIO_1610) { - /* Disable wake-up during idle for dynamic tick */ - void __iomem *reg = bank-base + OMAP1610_GPIO_CLEAR_WAKEUPENA; - __raw_writel(1 offset, reg); - } -#endif -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) - if (bank-method == METHOD_GPIO_24XX) { - /* Disable wake-up during idle for dynamic tick */ - void __iomem *reg = bank-base + OMAP24XX_GPIO_CLEARWKUENA; - __raw_writel(1 offset, reg); - } -#endif -#ifdef CONFIG_ARCH_OMAP4 - if (bank-method == METHOD_GPIO_44XX) { + + if (bank-regs-wkup_status) /* Disable wake-up during idle for dynamic tick */ - void __iomem *reg = bank-base + OMAP4_GPIO_IRQWAKEN0; - __raw_writel(1 offset, reg); - } -#endif + _gpio_rmw(base, bank-regs-wkup_status, 1 offset, 0); + bank-mod_usage = ~(1 offset); if (bank-regs-ctrl !bank-mod_usage) { @@ -1066,8 +1049,8 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, ct-chip.irq_mask = irq_gc_mask_set_bit; ct-chip.irq_unmask = irq_gc_mask_clr_bit; ct-chip.irq_set_type = gpio_irq_type; - /* REVISIT: assuming only 16xx supports MPUIO wake events */ - if (cpu_is_omap16xx()) + + if (bank-regs-wkup_status) ct-chip.irq_set_wake =
[PATCH v5 10/22] gpio/omap: use level/edge detect reg offsets
By adding level and edge detection register offsets and then initializing them correctly according to OMAP versions during device registrations we can now remove lot of revision checks in these functions. Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap2/gpio.c |8 ++ arch/arm/plat-omap/include/plat/gpio.h |4 + drivers/gpio/gpio-omap.c | 118 ++-- 3 files changed, 48 insertions(+), 82 deletions(-) diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index fd05cea..8745c3a 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -109,6 +109,10 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-regs-debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; pdata-regs-ctrl = OMAP24XX_GPIO_CTRL; pdata-regs-wkup_status = OMAP24XX_GPIO_WAKE_EN; + pdata-regs-leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0; + pdata-regs-leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1; + pdata-regs-risingdetect = OMAP24XX_GPIO_RISINGDETECT; + pdata-regs-fallingdetect = OMAP24XX_GPIO_FALLINGDETECT; break; case 2: pdata-bank_type = METHOD_GPIO_44XX; @@ -127,6 +131,10 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-regs-debounce_en = OMAP4_GPIO_DEBOUNCENABLE; pdata-regs-ctrl = OMAP4_GPIO_CTRL; pdata-regs-wkup_status = OMAP4_GPIO_IRQWAKEN0; + pdata-regs-leveldetect0 = OMAP4_GPIO_LEVELDETECT0; + pdata-regs-leveldetect1 = OMAP4_GPIO_LEVELDETECT1; + pdata-regs-risingdetect = OMAP4_GPIO_RISINGDETECT; + pdata-regs-fallingdetect = OMAP4_GPIO_FALLINGDETECT; break; default: WARN(1, Invalid gpio bank_type\n); diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 817997d..7d12fe8 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -190,6 +190,10 @@ struct omap_gpio_reg_offs { u16 debounce_en; u16 ctrl; u16 wkup_status; + u16 leveldetect0; + u16 leveldetect1; + u16 risingdetect; + u16 fallingdetect; bool irqenable_inv; }; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index e841ac1..be561be 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -257,15 +257,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, bank-enabled_non_wakeup_gpios = ~gpio_bit; } - if (cpu_is_omap44xx()) { - bank-level_mask = - __raw_readl(bank-base + OMAP4_GPIO_LEVELDETECT0) | - __raw_readl(bank-base + OMAP4_GPIO_LEVELDETECT1); - } else { - bank-level_mask = - __raw_readl(bank-base + OMAP24XX_GPIO_LEVELDETECT0) | - __raw_readl(bank-base + OMAP24XX_GPIO_LEVELDETECT1); - } + bank-level_mask = + __raw_readl(bank-base + bank-regs-leveldetect0) | + __raw_readl(bank-base + bank-regs-leveldetect1); } #endif @@ -405,12 +399,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) if (type ~IRQ_TYPE_SENSE_MASK) return -EINVAL; - /* OMAP1 allows only only edge triggering */ - if (!cpu_class_is_omap2() -(type (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) + bank = irq_data_get_irq_chip_data(d); + + if (!bank-regs-leveldetect0 + (type (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) return -EINVAL; - bank = irq_data_get_irq_chip_data(d); spin_lock_irqsave(bank-lock, flags); retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type); spin_unlock_irqrestore(bank-lock, flags); @@ -658,9 +652,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) if (cpu_is_omap15xx() (bank-method == METHOD_MPUIO)) isr = 0x; - if (cpu_class_is_omap2()) { + if (bank-level_mask) level_mask = bank-level_mask enabled; - } /* clear edge sensitive interrupts before handler(s) are called so that we don't miss any interrupt occurred while @@ -1246,40 +1239,18 @@ void omap2_gpio_prepare_for_idle(int off_mode) if (!(bank-enabled_non_wakeup_gpios)) goto save_gpio_ctx; - if (cpu_is_omap24xx() || cpu_is_omap34xx()) { - bank-saved_datain = __raw_readl(bank-base + - OMAP24XX_GPIO_DATAIN); -
[PATCH v5 02/22] gpio/omap: use flag to identify wakeup domain
From: Charulatha V ch...@ti.com In omap3, save/restore context is implemented for GPIO banks 2-6 as GPIO bank1 is in wakeup domain. Instead of identifying bank's power domain by bank id, use 'loses_context' flag which is filled by pwrdm_can_ever_lose_context() during dev_init. For getting the powerdomain pointer, omap_hwmod_get_pwrdm() is used. omap_device_get_pwrdm() could not be used as the pwrdm information needs to be filled in pdata, whereas omap_device_get_pwrdm() could be used only after omap_device_build() call. Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap2/gpio.c |6 ++ arch/arm/plat-omap/include/plat/gpio.h |1 + drivers/gpio/gpio-omap.c | 13 ++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index f805cda..95195a8 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -24,6 +24,8 @@ #include plat/omap_hwmod.h #include plat/omap_device.h +#include powerdomain.h + static struct omap_device_pm_latency omap_gpio_latency[] = { [0] = { .deactivate_func = omap_device_idle_hwmods, @@ -39,6 +41,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) struct omap_gpio_dev_attr *dev_attr; char *name = omap_gpio; int id; + struct powerdomain *pwrdm; /* * extract the device id from name field available in the @@ -107,6 +110,9 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) return -EINVAL; } + pwrdm = omap_hwmod_get_pwrdm(oh); + pdata-loses_context = pwrdm_can_ever_lose_context(pwrdm); + od = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata), omap_gpio_latency, ARRAY_SIZE(omap_gpio_latency), diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index dd330ed..58d0bf2 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -198,6 +198,7 @@ struct omap_gpio_platform_data { int bank_width; /* GPIO bank width */ int bank_stride;/* Only needed for omap1 MPUIO */ bool dbck_flag; /* dbck required or not - True for OMAP34 */ + bool loses_context; /* whether the bank would ever lose context */ struct omap_gpio_reg_offs *regs; }; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 13d5ca4..aaf07b8 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -56,6 +56,7 @@ struct gpio_bank { u32 dbck_enable_mask; struct device *dev; bool dbck_flag; + bool loses_context; int stride; u32 width; u16 id; @@ -1176,7 +1177,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank-dbck_flag = pdata-dbck_flag; bank-stride = pdata-bank_stride; bank-width = pdata-bank_width; - + bank-loses_context = pdata-loses_context; bank-regs = pdata-regs; if (bank-regs-set_dataout bank-regs-clr_dataout) @@ -1332,8 +1333,7 @@ void omap2_gpio_prepare_for_idle(int off_mode) u32 l1 = 0, l2 = 0; int j; - /* TODO: Do not use cpu_is_omap34xx */ - if ((cpu_is_omap34xx()) (bank-id == 0)) + if (!bank-loses_context) continue; for (j = 0; j hweight_long(bank-dbck_enable_mask); j++) @@ -1400,8 +1400,7 @@ void omap2_gpio_resume_after_idle(void) u32 l = 0, gen, gen0, gen1; int j; - /* TODO: Do not use cpu_is_omap34xx */ - if ((cpu_is_omap34xx()) (bank-id == 0)) + if (!bank-loses_context) continue; for (j = 0; j hweight_long(bank-dbck_enable_mask); j++) @@ -1500,7 +1499,7 @@ void omap_gpio_save_context(void) list_for_each_entry(bank, omap_gpio_list, node) { i++; - if (bank-id == 0) + if (!bank-loses_context) continue; gpio_context[i].irqenable1 = @@ -1534,7 +1533,7 @@ void omap_gpio_restore_context(void) list_for_each_entry(bank, omap_gpio_list, node) { i++; - if (bank-id == 0) + if (!bank-loses_context) continue; __raw_writel(gpio_context[i].irqenable1, -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 00/22] gpio/omap: driver cleanup and fixes
This series is continuation of cleanup of OMAP GPIO driver and fixes. The cleanup include getting rid of cpu_is_* checks wherever possible, use of gpio_bank list instead of static array, use of unique platform specific value associated data member to OMAP platforms to avoid cpu_is_* checks. The series also include PM runtime support.* Baseline: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git Branch: master Commit: 02f8c6a (Linux 3.0) The patch series was applied on the mainline on top of Kevin's gpio cleanup patch series taken from following location: git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git Branch: for_3.1/gpio-cleanup-2 Test Details: - Compile tested for omap1_defconfig and omap2plus_defconfig. - OMAP1710-H3: Bootup test. - OMAP2430/SDP, OMAP3430/SDP, OMAP4430/SDP, 4430/Blaze: Functional testing. - PM Testing on OMAP3430-SDP: retention, off_mode, system_wide suspend and gpio wakeup. v5: - Reduce runtime callback overhead when *_get/put_sync() called from probe() and *_gpio_request/free(). - Dynamic context save within functions where context is modified instead of saving all context within a common function. - Removed call to mpuio_init() from omap_gpio_mod_init(). Both the functions are called once during initialization in *_gpio_probe(). Call to omap_gpio_mod_init() has been removed from omap_gpio_request() on the first access to gpio bank. One time initialization looks sufficient. - In *_gpio_irq_handler() use *_put_sync_suspend() instead of *_put_sync(). - Removed hardcoding of OMAP16xx sysconfig register value and instead defined an associated constant. - Removed *_get_sync() call from *_gpio_suspend() and *_put_sync() call from *_gpio_resume(). They got wrongly slipped into the code. - Removed following redundant zero allocated initialization from mach-omap2/gpio.c + pdata-regs-irqctrl = 0; + pdata-regs-edgectrl1 = 0; + pdata-regs-edgectrl2 = 0; - Removed following redundant code in gpio-omap.c -#define bank_is_mpuio(bank) ((bank)-method == METHOD_MPUIO) v4: - since all accesses to registers are 4-byte aligned, removing special checks and handling of 16 and 32-bit wide bank registers and instead use 32-bit read/write access consistently. - redundant usage of MOD_REG_BIT has been corrected and replaced with _gpio_rmw(). - omap_gpio_mod_init() function has been simplified further using _gpio_rmw(). - sysconfig register offset specific to omap16xx has been removed along with its usage. - additional logic to skip from suspend/resume: if (!bank-regs-wkup_status || !bank-suspend_wakeup) return 0; if (!bank-regs-wkup_status || !bank-saved_wakeup) return 0; - separated mpuio related changes into a different patch from the patch where wakeup status register related changes are done. - Incorrect replacement of !cpu_class_is_omap2() in gpio_irq_type() corrected: + if (!bank-regs-leveldetect0 + (type (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) return -EINVAL; v3: - Avoid use of wkup_set and wkup_clear registers. Instead use wkup_status register for all platforms. This is because on OMAP4 it is recommended not to use them. - Remove duplicate code in omap_gpio_mod_init() for handling the same for 32-bit and 16-bit GPIO bank widths. This is accomplished by having two functions to handle each case while assiging a common function pointer during initialization. - Remove OMAP16xx specific one time initialization from omap_gpio_mod_init(). Move it inside omap16xx_gpio_init(). - Avoid usage of USHRT_MAX to indicate undefined values. Use 0 instead. - In omap_gpio_suspend()/resume() functions remove code that checks if the feature is supported. Instead, assign these functions to struct platform_driver's suspend resume function pointers for those OMAP platforms whcih support this feature. - Remove 'suspend_support' flag because it is redundant. Instead use wkup_* registers to decode the same information. - Restore context also when we don't know if the context is lost. - Make omap_gpio_save_context() and omap_gpio_restore_context() static. v2: - Do special handling of non-wakeup GPIOs only on OMAP2420. Avoid this handling on OMAP3430. - Isolate cleanups and fixes into separate set of patches. Keep the cleanup first followed by the fixes. - Avoid calling omap_gpio_get_context_loss() directly and instead call it through function pointer in pdata initialized during init. - workaround_enabled flag is not longer needed and is removed. - Call pwrdm_post_transition() before calling omap_gpio_resume_after_idle(). - In omap2_gpio_resume_after_idle() do context restore before handling workaround. - Use PM runtime framework. - Modify register offset names to : wkup_status, wkup_clear, wkup_set. Also use 'base + offset' for readibility in all relevant places. - Remove unwanted messages from commit
[PATCH v5 01/22] gpio/omap: remove dependency on gpio_bank_count
From: Charulatha V ch...@ti.com The gpio_bank_count is the count of number of GPIO devices in a SoC. Remove this dependency from the driver by using list. Also remove the dependency on array of pointers to gpio_bank struct of all GPIO devices. Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap1/gpio15xx.c |1 - arch/arm/mach-omap1/gpio16xx.c |2 - arch/arm/mach-omap1/gpio7xx.c |2 - arch/arm/mach-omap2/gpio.c |1 - arch/arm/plat-omap/include/plat/gpio.h |3 - drivers/gpio/gpio-omap.c | 163 6 files changed, 80 insertions(+), 92 deletions(-) diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 399da4c..f8c15ea 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -115,7 +115,6 @@ static int __init omap15xx_gpio_init(void) platform_device_register(omap15xx_mpu_gpio); platform_device_register(omap15xx_gpio); - gpio_bank_count = 2; return 0; } postcore_initcall(omap15xx_gpio_init); diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index 0f399bd..df4bb44 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -221,8 +221,6 @@ static int __init omap16xx_gpio_init(void) for (i = 0; i ARRAY_SIZE(omap16xx_gpio_dev); i++) platform_device_register(omap16xx_gpio_dev[i]); - gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev); - return 0; } postcore_initcall(omap16xx_gpio_init); diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index 5ab63ea..923eaa1 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c @@ -282,8 +282,6 @@ static int __init omap7xx_gpio_init(void) for (i = 0; i ARRAY_SIZE(omap7xx_gpio_dev); i++) platform_device_register(omap7xx_gpio_dev[i]); - gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev); - return 0; } postcore_initcall(omap7xx_gpio_init); diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 9a46d77..f805cda 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -119,7 +119,6 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) return PTR_ERR(od); } - gpio_bank_count++; return 0; } diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 91e8de3..dd330ed 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -202,9 +202,6 @@ struct omap_gpio_platform_data { struct omap_gpio_reg_offs *regs; }; -/* TODO: Analyze removing gpio_bank_count usage from driver code */ -extern int gpio_bank_count; - extern void omap2_gpio_prepare_for_idle(int off_mode); extern void omap2_gpio_resume_after_idle(void); extern void omap_set_gpio_debounce(int gpio, int enable); diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 34a7110..13d5ca4 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -28,7 +28,10 @@ #include mach/gpio.h #include asm/mach/irq.h +static LIST_HEAD(omap_gpio_list); + struct gpio_bank { + struct list_head node; unsigned long pbase; void __iomem *base; u16 irq; @@ -55,6 +58,7 @@ struct gpio_bank { bool dbck_flag; int stride; u32 width; + u16 id; void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable); @@ -78,15 +82,6 @@ struct omap3_gpio_regs { static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; #endif -/* - * TODO: Cleanup gpio_bank usage as it is having information - * related to all instances of the device - */ -static struct gpio_bank *gpio_bank; - -/* TODO: Analyze removing gpio_bank_count usage from driver code */ -int gpio_bank_count; - #define GPIO_INDEX(bank, gpio) (gpio % bank-width) #define GPIO_BIT(bank, gpio) (1 GPIO_INDEX(bank, gpio)) @@ -869,9 +864,8 @@ static struct platform_device omap_mpuio_device = { /* could list the /proc/iomem resources */ }; -static inline void mpuio_init(void) +static inline void mpuio_init(struct gpio_bank *bank) { - struct gpio_bank *bank = gpio_bank[0]; platform_set_drvdata(omap_mpuio_device, bank); if (platform_driver_register(omap_mpuio_driver) == 0) @@ -879,13 +873,13 @@ static inline void mpuio_init(void) } #else -static inline void mpuio_init(void) {} +static inline void mpuio_init(struct gpio_bank *bank) {} #endif /* 16xx */ #else #define bank_is_mpuio(bank)0 -static inline void mpuio_init(void) {} +static inline void mpuio_init(struct gpio_bank *bank) {} #endif @@ -1007,20 +1001,8 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank) */ static struct lock_class_key gpio_lock_class; -static inline int init_gpio_info(struct platform_device
[PATCH v5 12/22] gpio/omap: cleanup set_gpio_triggering function
Getting rid of ifdefs within the function by adding register offset intctrl and associating OMAP_GPIO_INT_CONTROL in respective SoC specific files. Also, use wkup_status register consistently instead of referring to wakeup clear and wakeup set register offsets. Signed-off-by: Charulatha V ch...@ti.com Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com --- arch/arm/mach-omap1/gpio15xx.c |2 + arch/arm/mach-omap1/gpio16xx.c |3 + arch/arm/mach-omap1/gpio7xx.c |2 + arch/arm/plat-omap/include/plat/gpio.h |3 + drivers/gpio/gpio-omap.c | 159 --- 5 files changed, 51 insertions(+), 118 deletions(-) diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index f8c15ea..2adfece 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -42,6 +42,7 @@ static struct omap_gpio_reg_offs omap15xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT, .irqenable = OMAP_MPUIO_GPIO_MASKIT, .irqenable_inv = true, + .irqctrl= OMAP_MPUIO_GPIO_INT_EDGE, }; static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { @@ -83,6 +84,7 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = { .irqstatus = OMAP1510_GPIO_INT_STATUS, .irqenable = OMAP1510_GPIO_INT_MASK, .irqenable_inv = true, + .irqctrl= OMAP1510_GPIO_INT_CONTROL, }; static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index ed9f285..f619805 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -45,6 +45,7 @@ static struct omap_gpio_reg_offs omap16xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT, .irqenable = OMAP_MPUIO_GPIO_MASKIT, .irqenable_inv = true, + .irqctrl= OMAP_MPUIO_GPIO_INT_EDGE, }; static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { @@ -90,6 +91,8 @@ static struct omap_gpio_reg_offs omap16xx_gpio_regs = { .set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1, .clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1, .wkup_status= OMAP1610_GPIO_WAKEUPENABLE, + .edgectrl1 = OMAP1610_GPIO_EDGE_CTRL1, + .edgectrl2 = OMAP1610_GPIO_EDGE_CTRL2, }; static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index 923eaa1..cb083c5 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c @@ -47,6 +47,7 @@ static struct omap_gpio_reg_offs omap7xx_mpuio_regs = { .irqstatus = OMAP_MPUIO_GPIO_INT / 2, .irqenable = OMAP_MPUIO_GPIO_MASKIT / 2, .irqenable_inv = true, + .irqctrl= OMAP_MPUIO_GPIO_INT_EDGE / 2, }; static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { @@ -88,6 +89,7 @@ static struct omap_gpio_reg_offs omap7xx_gpio_regs = { .irqstatus = OMAP7XX_GPIO_INT_STATUS, .irqenable = OMAP7XX_GPIO_INT_MASK, .irqenable_inv = true, + .irqctrl= OMAP7XX_GPIO_INT_CONTROL, }; static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 0ad4f49..4f584de 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -195,6 +195,9 @@ struct omap_gpio_reg_offs { u16 leveldetect1; u16 risingdetect; u16 fallingdetect; + u16 irqctrl; + u16 edgectrl1; + u16 edgectrl2; bool irqenable_inv; }; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index e7c9fe5..21cb0d4 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -199,52 +199,27 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, __raw_writel(val, reg); } -#ifdef CONFIG_ARCH_OMAP2PLUS -static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, +static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, int trigger) { void __iomem *base = bank-base; u32 gpio_bit = 1 gpio; - if (cpu_is_omap44xx()) { - _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit, - trigger IRQ_TYPE_LEVEL_LOW); - _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit, - trigger IRQ_TYPE_LEVEL_HIGH); - _gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit, - trigger IRQ_TYPE_EDGE_RISING); - _gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit, - trigger IRQ_TYPE_EDGE_FALLING); - } else { -
[PATCH v5 14/22] gpio/omap: use pinctrl offset instead of macro
From: Charulatha V ch...@ti.com Use regs-pinctrl field instead of using the macro OMAP1510_GPIO_PIN_CONTROL Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap1/gpio15xx.c |1 + arch/arm/plat-omap/include/plat/gpio.h |1 + drivers/gpio/gpio-omap.c |8 +++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 2adfece..950e467 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -85,6 +85,7 @@ static struct omap_gpio_reg_offs omap15xx_gpio_regs = { .irqenable = OMAP1510_GPIO_INT_MASK, .irqenable_inv = true, .irqctrl= OMAP1510_GPIO_INT_CONTROL, + .pinctrl= OMAP1510_GPIO_PIN_CONTROL, }; static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 4f584de..3a05c58 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -198,6 +198,7 @@ struct omap_gpio_reg_offs { u16 irqctrl; u16 edgectrl1; u16 edgectrl2; + u16 pinctrl; bool irqenable_inv; }; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index f6855e5..3d18cdf 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -486,15 +486,13 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) */ _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); -#ifdef CONFIG_ARCH_OMAP15XX - if (bank-method == METHOD_GPIO_1510) { - void __iomem *reg; + if (bank-regs-pinctrl) { + void __iomem *reg = bank-base + bank-regs-pinctrl; /* Claim the pin for MPU */ - reg = bank-base + OMAP1510_GPIO_PIN_CONTROL; __raw_writel(__raw_readl(reg) | (1 offset), reg); } -#endif + if (bank-regs-ctrl !bank-mod_usage) { void __iomem *reg = bank-base + bank-regs-ctrl; u32 ctrl; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 21/22] gpio/omap: skip operations in runtime callbacks
Most operations within runtime callbacks should be skipped when *_runtime_get_sync() and *_runtime_put_sync() are called in probe(), *_gpio_request() and *_gpio_free(). We just need clock enable/disable. Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com --- drivers/gpio/gpio-omap.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index ba743f5..eae955a 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1142,6 +1142,9 @@ static int omap_gpio_runtime_suspend(struct device *dev) for (j = 0; j hweight_long(bank-dbck_enable_mask); j++) clk_disable(bank-dbck); + if (!bank-mod_usage) + return 0; + /* If going to OFF, remove triggering for all * non-wakeup GPIOs. Otherwise spurious IRQs will be * generated. See OMAP2420 Errata item 1.101. */ @@ -1180,6 +1183,9 @@ static int omap_gpio_runtime_resume(struct device *dev) for (j = 0; j hweight_long(bank-dbck_enable_mask); j++) clk_enable(bank-dbck); + if (!bank-mod_usage) + return 0; + if (bank-get_context_loss_count) { ctx_lost_cnt_after = bank-get_context_loss_count(bank-dev); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 05/22] gpio/omap: handle save/restore ctx in GPIO driver
From: Charulatha V ch...@ti.com Modify omap_gpio_prepare_for_idle() omap_gpio_resume_after_idle() functions to handle save context restore context respectively in the OMAP GPIO driver itself instead of calling these functions from pm specific files. For this, in gpio_prepare_for_idle(), call *_get_context_loss_count() and in gpio_resume_after_idle() call it again. If the count is different, do restore context. The workaround_enabled flag is no more required and is removed. Signed-off-by: Charulatha V ch...@ti.com Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com --- arch/arm/mach-omap2/gpio.c | 12 +++ arch/arm/mach-omap2/pm34xx.c | 14 arch/arm/plat-omap/include/plat/gpio.h |5 +- drivers/gpio/gpio-omap.c | 131 ++-- 4 files changed, 73 insertions(+), 89 deletions(-) diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 95195a8..2e65377 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -23,6 +23,7 @@ #include plat/omap_hwmod.h #include plat/omap_device.h +#include plat/omap-pm.h #include powerdomain.h @@ -34,6 +35,16 @@ static struct omap_device_pm_latency omap_gpio_latency[] = { }, }; +#ifdef CONFIG_PM +static int omap_gpio_get_context_loss(struct device *dev) +{ + return omap_pm_get_dev_context_loss_count(dev); +} + +#else +#define omap_gpio_get_context_loss NULL +#endif + static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) { struct omap_device *od; @@ -63,6 +74,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-bank_width = dev_attr-bank_width; pdata-dbck_flag = dev_attr-dbck_flag; pdata-virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1); + pdata-get_context_loss_count = omap_gpio_get_context_loss; pdata-regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL); if (!pdata) { diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 51d5a5c..0aaa32c 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -91,16 +91,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm; static struct powerdomain *core_pwrdm, *per_pwrdm; static struct powerdomain *cam_pwrdm; -static inline void omap3_per_save_context(void) -{ - omap_gpio_save_context(); -} - -static inline void omap3_per_restore_context(void) -{ - omap_gpio_restore_context(); -} - static void omap3_enable_io_chain(void) { int timeout = 0; @@ -405,8 +395,6 @@ void omap_sram_idle(void) omap_uart_prepare_idle(2); omap_uart_prepare_idle(3); omap2_gpio_prepare_for_idle(per_going_off); - if (per_next_state == PWRDM_POWER_OFF) - omap3_per_save_context(); } /* CORE */ @@ -474,8 +462,6 @@ void omap_sram_idle(void) if (per_next_state PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); omap2_gpio_resume_after_idle(); - if (per_prev_state == PWRDM_POWER_OFF) - omap3_per_restore_context(); omap_uart_resume_idle(2); omap_uart_resume_idle(3); } diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 58d0bf2..f7798b5 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -201,14 +201,15 @@ struct omap_gpio_platform_data { bool loses_context; /* whether the bank would ever lose context */ struct omap_gpio_reg_offs *regs; + + /* Return context loss count due to PM states changing */ + int (*get_context_loss_count)(struct device *dev); }; extern void omap2_gpio_prepare_for_idle(int off_mode); extern void omap2_gpio_resume_after_idle(void); extern void omap_set_gpio_debounce(int gpio, int enable); extern void omap_set_gpio_debounce_time(int gpio, int enable); -extern void omap_gpio_save_context(void); -extern void omap_gpio_restore_context(void); /*-*/ /* Wrappers for new style GPIO calls, using the new infrastructure diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 2fa8b13..61c0da9 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -72,9 +72,11 @@ struct gpio_bank { bool loses_context; int stride; u32 width; + u32 ctx_loss_count; u16 id; void (*set_dataout)(struct gpio_bank *bank, int gpio, int enable); + int (*get_context_loss_count)(struct device *dev); struct omap_gpio_reg_offs *regs; }; @@ -1174,6 +1176,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank-stride = pdata-bank_stride; bank-width = pdata-bank_width; bank-loses_context =
[PATCH v5 07/22] gpio/omap: avoid cpu checks during module ena/disable
From: Charulatha V ch...@ti.com Remove cpu-is checks while enabling/disabling OMAP GPIO module during a gpio request/free. Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap2/gpio.c |2 + arch/arm/plat-omap/include/plat/gpio.h |1 + drivers/gpio/gpio-omap.c | 53 ++-- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 4952a9d..cdbc728 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -107,6 +107,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-regs-clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1; pdata-regs-debounce = OMAP24XX_GPIO_DEBOUNCE_VAL; pdata-regs-debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN; + pdata-regs-ctrl = OMAP24XX_GPIO_CTRL; break; case 2: pdata-bank_type = METHOD_GPIO_44XX; @@ -123,6 +124,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) pdata-regs-clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0; pdata-regs-debounce = OMAP4_GPIO_DEBOUNCINGTIME; pdata-regs-debounce_en = OMAP4_GPIO_DEBOUNCENABLE; + pdata-regs-ctrl = OMAP4_GPIO_CTRL; break; default: WARN(1, Invalid gpio bank_type\n); diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index ce417cd..cf41743 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -188,6 +188,7 @@ struct omap_gpio_reg_offs { u16 clr_irqenable; u16 debounce; u16 debounce_en; + u16 ctrl; bool irqenable_inv; }; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 35ab3e9..4d26ba7 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -83,6 +83,7 @@ struct gpio_bank { #define GPIO_INDEX(bank, gpio) (gpio % bank-width) #define GPIO_BIT(bank, gpio) (1 GPIO_INDEX(bank, gpio)) +#define GPIO_MOD_CTRL_BIT BIT(0) static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) { @@ -577,22 +578,18 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) __raw_writel(__raw_readl(reg) | (1 offset), reg); } #endif - if (!cpu_class_is_omap1()) { - if (!bank-mod_usage) { - void __iomem *reg = bank-base; - u32 ctrl; - - if (cpu_is_omap24xx() || cpu_is_omap34xx()) - reg += OMAP24XX_GPIO_CTRL; - else if (cpu_is_omap44xx()) - reg += OMAP4_GPIO_CTRL; - ctrl = __raw_readl(reg); - /* Module is enabled, clocks are not gated */ - ctrl = 0xFFFE; - __raw_writel(ctrl, reg); - } - bank-mod_usage |= 1 offset; + if (bank-regs-ctrl !bank-mod_usage) { + void __iomem *reg = bank-base + bank-regs-ctrl; + u32 ctrl; + + ctrl = __raw_readl(reg); + /* Module is enabled, clocks are not gated */ + ctrl = ~GPIO_MOD_CTRL_BIT; + __raw_writel(ctrl, reg); } + + bank-mod_usage |= 1 offset; + spin_unlock_irqrestore(bank-lock, flags); return 0; @@ -625,22 +622,18 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) __raw_writel(1 offset, reg); } #endif - if (!cpu_class_is_omap1()) { - bank-mod_usage = ~(1 offset); - if (!bank-mod_usage) { - void __iomem *reg = bank-base; - u32 ctrl; - - if (cpu_is_omap24xx() || cpu_is_omap34xx()) - reg += OMAP24XX_GPIO_CTRL; - else if (cpu_is_omap44xx()) - reg += OMAP4_GPIO_CTRL; - ctrl = __raw_readl(reg); - /* Module is disabled, clocks are gated */ - ctrl |= 1; - __raw_writel(ctrl, reg); - } + bank-mod_usage = ~(1 offset); + + if (bank-regs-ctrl !bank-mod_usage) { + void __iomem *reg = bank-base + bank-regs-ctrl; + u32 ctrl; + + ctrl = __raw_readl(reg); + /* Module is disabled, clocks are gated */ + ctrl |= GPIO_MOD_CTRL_BIT; + __raw_writel(ctrl, reg); } + _reset_gpio(bank, bank-chip.base + offset); spin_unlock_irqrestore(bank-lock, flags); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to
[PATCH v5 03/22] gpio/omap: make gpio_context part of gpio_bank structure
From: Charulatha V ch...@ti.com Currently gpio_context array used to save gpio bank's context, is used only for OMAP3 architecture. Move gpio_context as part of gpio_bank structure so that it can be specific to each gpio bank and can be used for any OMAP architecture Signed-off-by: Charulatha V ch...@ti.com --- drivers/gpio/gpio-omap.c | 76 - 1 files changed, 34 insertions(+), 42 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index aaf07b8..2fa8b13 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -30,6 +30,19 @@ static LIST_HEAD(omap_gpio_list); +struct gpio_regs { + u32 irqenable1; + u32 irqenable2; + u32 wake_en; + u32 ctrl; + u32 oe; + u32 leveldetect0; + u32 leveldetect1; + u32 risingdetect; + u32 fallingdetect; + u32 dataout; +}; + struct gpio_bank { struct list_head node; unsigned long pbase; @@ -43,7 +56,7 @@ struct gpio_bank { #endif u32 non_wakeup_gpios; u32 enabled_non_wakeup_gpios; - + struct gpio_regs context; u32 saved_datain; u32 saved_fallingdetect; u32 saved_risingdetect; @@ -66,23 +79,6 @@ struct gpio_bank { struct omap_gpio_reg_offs *regs; }; -#ifdef CONFIG_ARCH_OMAP3 -struct omap3_gpio_regs { - u32 irqenable1; - u32 irqenable2; - u32 wake_en; - u32 ctrl; - u32 oe; - u32 leveldetect0; - u32 leveldetect1; - u32 risingdetect; - u32 fallingdetect; - u32 dataout; -}; - -static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; -#endif - #define GPIO_INDEX(bank, gpio) (gpio % bank-width) #define GPIO_BIT(bank, gpio) (1 GPIO_INDEX(bank, gpio)) @@ -1494,33 +1490,31 @@ void omap2_gpio_resume_after_idle(void) void omap_gpio_save_context(void) { struct gpio_bank *bank; - int i = 0; list_for_each_entry(bank, omap_gpio_list, node) { - i++; if (!bank-loses_context) continue; - gpio_context[i].irqenable1 = + bank-context.irqenable1 = __raw_readl(bank-base + OMAP24XX_GPIO_IRQENABLE1); - gpio_context[i].irqenable2 = + bank-context.irqenable2 = __raw_readl(bank-base + OMAP24XX_GPIO_IRQENABLE2); - gpio_context[i].wake_en = + bank-context.wake_en = __raw_readl(bank-base + OMAP24XX_GPIO_WAKE_EN); - gpio_context[i].ctrl = + bank-context.ctrl = __raw_readl(bank-base + OMAP24XX_GPIO_CTRL); - gpio_context[i].oe = + bank-context.oe = __raw_readl(bank-base + OMAP24XX_GPIO_OE); - gpio_context[i].leveldetect0 = + bank-context.leveldetect0 = __raw_readl(bank-base + OMAP24XX_GPIO_LEVELDETECT0); - gpio_context[i].leveldetect1 = + bank-context.leveldetect1 = __raw_readl(bank-base + OMAP24XX_GPIO_LEVELDETECT1); - gpio_context[i].risingdetect = + bank-context.risingdetect = __raw_readl(bank-base + OMAP24XX_GPIO_RISINGDETECT); - gpio_context[i].fallingdetect = + bank-context.fallingdetect = __raw_readl(bank-base + OMAP24XX_GPIO_FALLINGDETECT); - gpio_context[i].dataout = + bank-context.dataout = __raw_readl(bank-base + OMAP24XX_GPIO_DATAOUT); } } @@ -1528,33 +1522,31 @@ void omap_gpio_save_context(void) void omap_gpio_restore_context(void) { struct gpio_bank *bank; - int i = 0; list_for_each_entry(bank, omap_gpio_list, node) { - i++; if (!bank-loses_context) continue; - __raw_writel(gpio_context[i].irqenable1, + __raw_writel(bank-context.irqenable1, bank-base + OMAP24XX_GPIO_IRQENABLE1); - __raw_writel(gpio_context[i].irqenable2, + __raw_writel(bank-context.irqenable2, bank-base + OMAP24XX_GPIO_IRQENABLE2); - __raw_writel(gpio_context[i].wake_en, + __raw_writel(bank-context.wake_en, bank-base + OMAP24XX_GPIO_WAKE_EN); - __raw_writel(gpio_context[i].ctrl, + __raw_writel(bank-context.ctrl, bank-base + OMAP24XX_GPIO_CTRL); - __raw_writel(gpio_context[i].oe, + __raw_writel(bank-context.oe, bank-base + OMAP24XX_GPIO_OE); - __raw_writel(gpio_context[i].leveldetect0, + __raw_writel(bank-context.leveldetect0,
[PATCH v5 06/22] gpio/omap: make non-wakeup GPIO part of pdata
From: Charulatha V ch...@ti.com Non-wakeup GPIOs are available only in OMAP2. Avoid cpu_is checks by making non_wakeup_gpios as part of pdata. Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap2/gpio.c |8 arch/arm/plat-omap/include/plat/gpio.h |1 + drivers/gpio/gpio-omap.c |8 +--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 2e65377..4952a9d 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -84,6 +84,14 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) switch (oh-class-rev) { case 0: + if (id == 1) + /* non-wakeup GPIO pins for OMAP2 Bank1 */ + pdata-non_wakeup_gpios = 0xe203ffc0; + else if (id == 2) + /* non-wakeup GPIO pins for OMAP2 Bank2 */ + pdata-non_wakeup_gpios = 0x08700040; + /* fall through */ + case 1: pdata-bank_type = METHOD_GPIO_24XX; pdata-regs-revision = OMAP24XX_GPIO_REVISION; diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index f7798b5..ce417cd 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -199,6 +199,7 @@ struct omap_gpio_platform_data { int bank_stride;/* Only needed for omap1 MPUIO */ bool dbck_flag; /* dbck required or not - True for OMAP34 */ bool loses_context; /* whether the bank would ever lose context */ + u32 non_wakeup_gpios; struct omap_gpio_reg_offs *regs; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 61c0da9..35ab3e9 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1021,13 +1021,6 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) /* Initialize interface clk ungated, module enabled */ __raw_writel(0, bank-base + OMAP24XX_GPIO_CTRL); - } else if (cpu_is_omap24xx()) { - static const u32 non_wakeup_gpios[] = { - 0xe203ffc0, 0x08700040 - }; - if (bank-id ARRAY_SIZE(non_wakeup_gpios)) - bank-non_wakeup_gpios = - non_wakeup_gpios[bank-id]; } } else if (cpu_class_is_omap1()) { if (bank_is_mpuio(bank)) { @@ -1175,6 +1168,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank-dbck_flag = pdata-dbck_flag; bank-stride = pdata-bank_stride; bank-width = pdata-bank_width; + bank-non_wakeup_gpios = pdata-non_wakeup_gpios; bank-loses_context = pdata-loses_context; bank-get_context_loss_count = pdata-get_context_loss_count; bank-regs = pdata-regs; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 04/22] gpio/omap: fix pwrdm_post_transition call sequence
From: Charulatha V ch...@ti.com The context lost count is modified in omap_sram_idle() path when pwrdm_post_transition() is called. But pwrdm_post_transition() is called only after omap_gpio_resume_after_idle() is called. Correct this so that context lost count is modified before calling omap_gpio_resume_after_idle(). This would be useful when OMAP GPIO save/restore context is called by the OMAP GPIO driver itself. Signed-off-by: Charulatha V ch...@ti.com --- arch/arm/mach-omap2/pm34xx.c |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index c155c9d..51d5a5c 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -375,7 +375,6 @@ void omap_sram_idle(void) printk(KERN_ERR Invalid mpu state in sram_idle\n); return; } - pwrdm_pre_transition(); /* NEON control */ if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON) @@ -398,6 +397,8 @@ void omap_sram_idle(void) if (!console_trylock()) goto console_still_active; + pwrdm_pre_transition(); + /* PER */ if (per_next_state PWRDM_POWER_ON) { per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; @@ -467,6 +468,8 @@ void omap_sram_idle(void) } omap3_intc_resume_idle(); + pwrdm_post_transition(); + /* PER */ if (per_next_state PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); @@ -490,8 +493,6 @@ console_still_active: omap3_disable_io_chain(); } - pwrdm_post_transition(); - clkdm_allow_idle(mpu_pwrdm-pwrdm_clkdms[0]); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 20/22] gpio/omap: cleanup prepare_for_idle and resume_after_idle
Simplify omap2_gpio_prepare_for_idle() and omap2_gpio_resume_after_idle() by moving most of the stuff to *_runtime_suspend() and *_runtime_resume(). Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com Signed-off-by: Charulatha V ch...@ti.com --- drivers/gpio/gpio-omap.c | 230 -- 1 files changed, 121 insertions(+), 109 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index ce93898..ba743f5 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1132,142 +1132,149 @@ static int omap_gpio_resume(struct device *dev) static void omap_gpio_save_context(struct gpio_bank *bank); static void omap_gpio_restore_context(struct gpio_bank *bank); -void omap2_gpio_prepare_for_idle(int off_mode) +static int omap_gpio_runtime_suspend(struct device *dev) { - struct gpio_bank *bank; + struct platform_device *pdev = to_platform_device(dev); + struct gpio_bank *bank = platform_get_drvdata(pdev); + u32 l1 = 0, l2 = 0; + int j; - list_for_each_entry(bank, omap_gpio_list, node) { - u32 l1 = 0, l2 = 0; - int j; + for (j = 0; j hweight_long(bank-dbck_enable_mask); j++) + clk_disable(bank-dbck); - if (!bank-loses_context) - continue; + /* If going to OFF, remove triggering for all +* non-wakeup GPIOs. Otherwise spurious IRQs will be +* generated. See OMAP2420 Errata item 1.101. */ + if (!(bank-enabled_non_wakeup_gpios)) + goto save_gpio_ctx; - for (j = 0; j hweight_long(bank-dbck_enable_mask); j++) - clk_disable(bank-dbck); + bank-saved_datain = __raw_readl(bank-base + + bank-regs-datain); + l1 = __raw_readl(bank-base + bank-regs-fallingdetect); + l2 = __raw_readl(bank-base + bank-regs-risingdetect); - if (!off_mode) - continue; + bank-saved_fallingdetect = l1; + bank-saved_risingdetect = l2; + l1 = ~bank-enabled_non_wakeup_gpios; + l2 = ~bank-enabled_non_wakeup_gpios; - if (IS_ERR_VALUE(pm_runtime_put_sync(bank-dev) 0)) - dev_err(bank-dev, %s: GPIO bank %d - pm_runtime_put_sync failed\n, - __func__, bank-id); + __raw_writel(l1, bank-base + bank-regs-fallingdetect); + __raw_writel(l2, bank-base + bank-regs-risingdetect); + +save_gpio_ctx: + if (bank-get_context_loss_count) + bank-ctx_loss_count = bank-get_context_loss_count(bank-dev); + omap_gpio_save_context(bank); + + return 0; +} + +static int omap_gpio_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct gpio_bank *bank = platform_get_drvdata(pdev); + u32 ctx_lost_cnt_after; + u32 l = 0, gen, gen0, gen1; + int j; + + for (j = 0; j hweight_long(bank-dbck_enable_mask); j++) + clk_enable(bank-dbck); - /* If going to OFF, remove triggering for all -* non-wakeup GPIOs. Otherwise spurious IRQs will be -* generated. See OMAP2420 Errata item 1.101. */ - if (!(bank-enabled_non_wakeup_gpios)) - goto save_gpio_ctx; + if (bank-get_context_loss_count) { + ctx_lost_cnt_after = + bank-get_context_loss_count(bank-dev); + if (ctx_lost_cnt_after != bank-ctx_loss_count || + !ctx_lost_cnt_after) + omap_gpio_restore_context(bank); + else + return 0; + } - bank-saved_datain = __raw_readl(bank-base + - bank-regs-datain); - l1 = __raw_readl(bank-base + bank-regs-fallingdetect); - l2 = __raw_readl(bank-base + bank-regs-risingdetect); + if (!(bank-enabled_non_wakeup_gpios)) + return 0; - bank-saved_fallingdetect = l1; - bank-saved_risingdetect = l2; - l1 = ~bank-enabled_non_wakeup_gpios; - l2 = ~bank-enabled_non_wakeup_gpios; + __raw_writel(bank-saved_fallingdetect, + bank-base + bank-regs-fallingdetect); + __raw_writel(bank-saved_risingdetect, + bank-base + bank-regs-risingdetect); + l = __raw_readl(bank-base + bank-regs-datain); - __raw_writel(l1, bank-base + bank-regs-fallingdetect); - __raw_writel(l2, bank-base + bank-regs-risingdetect); + /* Check if any of the non-wakeup interrupt GPIOs have changed +* state. If so, generate an IRQ by software. This is +* horribly racy, but
[PATCH v5 15/22] gpio/omap: use readl in irq_handler for all access
From: Charulatha V ch...@ti.com Even when bank-width is 16, all the OMAP1 registers are 4-byte aligned, so just use a 4-byte read. The 'enabled' mask is already taking care to mask for bank width. Signed-off-by: Charulatha V ch...@ti.com Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com --- drivers/gpio/gpio-omap.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 3d18cdf..ba20e42 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -572,8 +572,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) enabled = _get_gpio_irqbank_mask(bank); isr_saved = isr = __raw_readl(isr_reg) enabled; - if (cpu_is_omap15xx() (bank-method == METHOD_MPUIO)) - isr = 0x; if (bank-level_mask) level_mask = bank-level_mask enabled; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] OMAP: DSS2: DSI: Support non-dcs long read
Hi, On Wed, 2011-06-29 at 20:44 -0700, Arve Hjønnevåg wrote: Change-Id: I18168c887e1384c07dc033a1ffc57abdacb26073 Signed-off-by: Arve Hjønnevåg a...@android.com --- drivers/video/omap2/dss/dsi.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) This feels somehow partial... Why do you want to read generic packets if there are no functions to send generic packets? And always write a patch description. Tomi diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index c16b933..6975645 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -206,6 +206,7 @@ struct dsi_reg { u16 idx; }; #define DSI_DT_DCS_LONG_WRITE0x39 #define DSI_DT_RX_ACK_WITH_ERR 0x02 +#define DSI_DT_RX_LONG_READ 0x1a #define DSI_DT_RX_DCS_LONG_READ 0x1c #define DSI_DT_RX_SHORT_READ_1 0x21 #define DSI_DT_RX_SHORT_READ_2 0x22 @@ -2943,6 +2944,10 @@ static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev, } else if (dt == DSI_DT_RX_SHORT_READ_2) { DSSERR(\tDCS short response, 2 byte: %#x\n, FLD_GET(val, 23, 8)); + } else if (dt == DSI_DT_RX_LONG_READ) { + DSSERR(\tlong response, len %d\n, + FLD_GET(val, 23, 8)); + dsi_vc_flush_long_data(dsidev, channel); } else if (dt == DSI_DT_RX_DCS_LONG_READ) { DSSERR(\tDCS long response, len %d\n, FLD_GET(val, 23, 8)); @@ -3287,7 +3292,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, buf[1] = (data 8) 0xff; return 2; - } else if (dt == DSI_DT_RX_DCS_LONG_READ) { + } else if (dt == DSI_DT_RX_DCS_LONG_READ || dt == DSI_DT_RX_LONG_READ) { int w; int len = FLD_GET(val, 23, 8); if (dsi-debug_read) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
On Wed, Aug 03, 2011 at 12:16:17AM +0200, Rafael J. Wysocki wrote: On Tuesday, August 02, 2011, Kevin Hilman wrote: I disagree and think that both are quite realistic (mainly because they exist today, albiet mostly out of tree because no generic QoS framework exist. e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting per-device wakeup latencies, and drivers and frameworks are using them.) I'm sure there are frameworks using such things. I'm also sure there are frameworks that don't. BTW, the we have it out of the tree argument is not very useful, so I'd appreciate it if you didn't use it. It's useful to know if people have tried things; it doesn't mean it's going to be OK for mainline but it is a data point. In this case, the video framework (V4L2) might not want any knobs exposed to userspace because userspace simply doesn't have the knowledge to set appropriate constraints. I'm less familiar with audio, but I believe audio would be similar (sample rate, number of channels, mixing with other concurrent audio streams, etc. etc. are all known by the kernel-side code.) Yeah, that sort of stuff and also data like wakeup latencies required to service interrupts. I still don't understand what's wrong with allowing user space to _add_ requirements. The will only override the drivers' or frameworks' requirements if they are stronger, so the functionality shouldn't be hurt. They may cause some more energy to be used, but if user space wants that, it's pretty much fine by me. On the one hand that's true. On the other hand that just seems like going down a bad road where we have drivers that only work when run with a magic userspace that may or may not be published which is just going to make people miserable. I'm not sure there are many people who would choose to use more power without wanting some functional change so presumably any users would be seeking to work around some kernel problem and adding the user interface seems to be saying that this is OK, expected and a natural part of power optimization. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [RFC 1/2] OMAP3+: voltage / oscillator parameter segregation
-Original Message- From: Tero Kristo [mailto:t-kri...@ti.com] Sent: Wednesday, August 03, 2011 8:59 PM To: linux-omap@vger.kernel.org Cc: Vishwanath Sripathy Subject: [RFC 1/2] OMAP3+: voltage / oscillator parameter segregation This patch separates board specific voltage and oscillator ramp / setup times from the core code. Things changed: - on/sleep/ret/off voltage setup moved from common twl code to VC / VP data (opp_data.c files) - added board support for vdd ramp up / down times - added board support for oscillator setup time declaration Todo: split patch into more easily manageable parts. Applies on top of pm/wip/voltdm branch, based on work done by Vishwanath Sripathy. Signed-off-by: Tero Kristo t-kri...@ti.com Cc: Vishwanath Sripathy vishwanath...@ti.com --- arch/arm/mach-omap2/omap_opp_data.h | 15 +++ arch/arm/mach-omap2/omap_twl.c| 59 -- arch/arm/mach-omap2/opp3xxx_data.c| 62 ++ arch/arm/mach-omap2/opp4xxx_data.c| 47 arch/arm/mach-omap2/prcm.c| 11 ++ arch/arm/mach-omap2/prm2xxx_3xxx.c|6 + arch/arm/mach-omap2/prm2xxx_3xxx.h|1 + arch/arm/mach-omap2/prm44xx.c |7 + arch/arm/mach-omap2/prm44xx.h |1 + arch/arm/mach-omap2/vc.c | 153 + arch/arm/mach-omap2/vc.h |1 - arch/arm/mach-omap2/voltage.c | 22 arch/arm/mach-omap2/voltage.h | 55 - arch/arm/mach-omap2/voltagedomains3xxx_data.c |8 ++ arch/arm/mach-omap2/voltagedomains44xx_data.c |8 ++ arch/arm/mach-omap2/vp.c |4 +- arch/arm/plat-omap/include/plat/prcm.h|7 + 17 files changed, 377 insertions(+), 90 deletions(-) diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach- omap2/omap_opp_data.h index c784c12..b5fe711 100644 --- a/arch/arm/mach-omap2/omap_opp_data.h +++ b/arch/arm/mach-omap2/omap_opp_data.h @@ -86,11 +86,26 @@ extern int __init omap_init_opp_table(struct omap_opp_def *opp_def, extern struct omap_volt_data omap34xx_vddmpu_volt_data[]; extern struct omap_volt_data omap34xx_vddcore_volt_data[]; +extern struct omap_vp_param omap34xx_mpu_vp_data; +extern struct omap_vp_param omap34xx_core_vp_data; +extern struct omap_vc_param omap34xx_mpu_vc_data; +extern struct omap_vc_param omap34xx_core_vc_data; + extern struct omap_volt_data omap36xx_vddmpu_volt_data[]; extern struct omap_volt_data omap36xx_vddcore_volt_data[]; +extern struct omap_vp_param omap36xx_mpu_vp_data; +extern struct omap_vp_param omap36xx_core_vp_data; +extern struct omap_vc_param omap36xx_mpu_vc_data; +extern struct omap_vc_param omap36xx_core_vc_data; extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[]; extern struct omap_volt_data omap44xx_vdd_iva_volt_data[]; extern struct omap_volt_data omap44xx_vdd_core_volt_data[]; +extern struct omap_vp_param omap44xx_mpu_vp_data; +extern struct omap_vp_param omap44xx_iva_vp_data; +extern struct omap_vp_param omap44xx_core_vp_data; +extern struct omap_vc_param omap44xx_mpu_vc_data; +extern struct omap_vc_param omap44xx_iva_vc_data; +extern struct omap_vc_param omap44xx_core_vc_data; #endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */ diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach- omap2/omap_twl.c index f515a1a..d239792 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -30,16 +30,6 @@ #define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04 #define OMAP3_VP_VLIMITTO_TIMEOUT_US 200 -#define OMAP3430_VP1_VLIMITTO_VDDMIN 0x14 -#define OMAP3430_VP1_VLIMITTO_VDDMAX 0x42 -#define OMAP3430_VP2_VLIMITTO_VDDMIN 0x18 -#define OMAP3430_VP2_VLIMITTO_VDDMAX 0x2c - -#define OMAP3630_VP1_VLIMITTO_VDDMIN 0x18 -#define OMAP3630_VP1_VLIMITTO_VDDMAX 0x3c -#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18 -#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30 - #define OMAP4_SRI2C_SLAVE_ADDR 0x12 #define OMAP4_VDD_MPU_SR_VOLT_REG0x55 #define OMAP4_VDD_MPU_SR_CMD_REG 0x56 @@ -53,13 +43,6 @@ #define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04 #define OMAP4_VP_VLIMITTO_TIMEOUT_US 200 -#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA -#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39 -#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA -#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D -#define OMAP4_VP_CORE_VLIMITTO_VDDMIN0xA -#define OMAP4_VP_CORE_VLIMITTO_VDDMAX0x28 - static bool is_offset_valid; static u8 smps_offset; /* @@ -158,16 +141,9 @@ static u8 twl6030_uv_to_vsel(unsigned long uv) static struct omap_voltdm_pmic omap3_mpu_pmic = { .slew_rate = 4000, .step_size = 12500, - .on_volt= 120, - .onlp_volt = 100, - .ret_volt =
Re: [PATCH] Revert i2c-omap: fix static suspend vs. runtime suspend
Felipe Balbi ba...@ti.com writes: On Wed, Aug 03, 2011 at 10:59:39AM -0700, Kevin Hilman wrote: This reverts commit adf6e07922255937c8bfeea777d19502b4c9a2be. Remove system PM methods which can race with runtime PM methods. Also, as of v3.1, the PM domain level code for OMAP handles device power state transistions automatically for devices, so calling them from from where ? I didn't quite get this ;-) heh, looks like i got distracted before finishing the changelog. Will respin. Thanks, Kevin -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] Revert i2c-omap: fix static suspend vs. runtime suspend
This reverts commit adf6e07922255937c8bfeea777d19502b4c9a2be. Remove system PM methods which can race with runtime PM methods. Also, as of v3.1, the PM domain level code for OMAP handles device power state transistions automatically for devices, so drivers no longer need to specifically call the bus/pm_domain methods themselves. Signed-off-by: Kevin Hilman khil...@ti.com --- v2: updated changelog to remove cliff-hanger ending drivers/i2c/busses/i2c-omap.c | 29 - 1 files changed, 0 insertions(+), 29 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 84df53f..e854be0 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1148,41 +1148,12 @@ omap_i2c_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_SUSPEND -static int omap_i2c_suspend(struct device *dev) -{ - if (!pm_runtime_suspended(dev)) - if (dev-bus dev-bus-pm dev-bus-pm-runtime_suspend) - dev-bus-pm-runtime_suspend(dev); - - return 0; -} - -static int omap_i2c_resume(struct device *dev) -{ - if (!pm_runtime_suspended(dev)) - if (dev-bus dev-bus-pm dev-bus-pm-runtime_resume) - dev-bus-pm-runtime_resume(dev); - - return 0; -} - -static struct dev_pm_ops omap_i2c_pm_ops = { - .suspend = omap_i2c_suspend, - .resume = omap_i2c_resume, -}; -#define OMAP_I2C_PM_OPS (omap_i2c_pm_ops) -#else -#define OMAP_I2C_PM_OPS NULL -#endif - static struct platform_driver omap_i2c_driver = { .probe = omap_i2c_probe, .remove = omap_i2c_remove, .driver = { .name = omap_i2c, .owner = THIS_MODULE, - .pm = OMAP_I2C_PM_OPS, }, }; -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] I2C: OMAP: remove dev-idle, use usage counting provided by runtime PM
Felipe Balbi ba...@ti.com writes: Hi, On Wed, Aug 03, 2011 at 11:09:20AM -0700, Kevin Hilman wrote: Current usage of runtime PM is not quite correct. The actual idle/unidle of the I2C hardware should not happen until the runtime PM callbacks are called. Therefore, change omap_i2c_[un]idle() functions to only be called from the runtime PM callbacks (when usage count transitions to/from zero.) Also, the runtime PM core does usage counting and replaces functionality currently managed by the dev-idle flag. Remove usage of dev-idle in favor of using runtime PM, and checking status using pm_runtime_suspended(). Signed-off-by: Kevin Hilman khil...@ti.com --- drivers/i2c/busses/i2c-omap.c | 58 ++-- 1 files changed, 38 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 12d0cbc..1b5325b 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -194,7 +194,6 @@ struct omap_i2c_dev { */ u8 rev; unsignedb_hw:1; /* bad h/w fixes */ -unsignedidle:1; u16 iestate;/* Saved interrupt register */ u16 pscstate; u16 scllstate; @@ -269,12 +268,8 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) { struct omap_i2c_bus_platform_data *pdata; -WARN_ON(!dev-idle); - pdata = dev-dev-platform_data; -pm_runtime_get_sync(dev-dev); - if (pdata-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); @@ -285,7 +280,6 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); } -dev-idle = 0; /* * Don't write to this register if the IE state is 0 as it can @@ -300,8 +294,6 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) struct omap_i2c_bus_platform_data *pdata; u16 iv; -WARN_ON(dev-idle); - pdata = dev-dev-platform_data; dev-iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); @@ -315,12 +307,9 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) } else { omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev-iestate); -/* Flush posted write before the dev-idle store occurs */ +/* Flush posted write */ omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); } -dev-idle = 1; - -pm_runtime_put_sync(dev-dev); } static int omap_i2c_init(struct omap_i2c_dev *dev) @@ -644,7 +633,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) int i; int r; -omap_i2c_unidle(dev); +pm_runtime_get_sync(dev-dev); r = omap_i2c_wait_for_bb(dev); if (r 0) @@ -667,7 +656,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) omap_i2c_wait_for_bb(dev); out: -omap_i2c_idle(dev); +pm_runtime_put_sync(dev-dev); I wonder if these pm_runtime_put need to be synchronous ? Could we just call pm_runtime_put() instead ? Ditto to all other. Yes, will use asynchronous versions. @@ -1140,6 +1128,36 @@ omap_i2c_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_RUNTIME +static int omap_i2c_runtime_suspend(struct device *dev) +{ +struct platform_device *pdev = to_platform_device(dev); +struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); what happened to dev_get_drvdata(dev) ?? Yes, that would work too since: static inline void *platform_get_drvdata(const struct platform_device *pdev) { return dev_get_drvdata(pdev-dev); } but IMO, readability is better if the driver does platform_set_drvdata() and then the corresponding platform_get_drvdata() +omap_i2c_idle(_dev); + +return 0; +} + +static int omap_i2c_runtime_resume(struct device *dev) +{ +struct platform_device *pdev = to_platform_device(dev); +struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); ditto +omap_i2c_unidle(_dev); + +return 0; +} + +static struct dev_pm_ops omap_i2c_pm_ops = { +.runtime_suspend = omap_i2c_runtime_suspend, +.runtime_resume = omap_i2c_runtime_resume, +}; +#define OMAP_I2C_PM_OPS (omap_i2c_pm_ops) +#else +#define OMAP_I2C_PM_OPS NULL +#endif OMAP_I2C_PM_OPS isn't used anywhere ?? doh thanks for catching Kevin -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/2] I2C: OMAP: remove unneccesary use of pdev
A pointer to the struct device associated with the i2c device is already kept in the struct omap_i2c_dev, so use omap_i2c_device to find the pointer to struct device. Reviewed-by: Felipe Balbi ba...@ti.com Signed-off-by: Kevin Hilman khil...@ti.com --- drivers/i2c/busses/i2c-omap.c | 22 +++--- 1 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index e854be0..12d0cbc 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -267,15 +267,13 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) static void omap_i2c_unidle(struct omap_i2c_dev *dev) { - struct platform_device *pdev; struct omap_i2c_bus_platform_data *pdata; WARN_ON(!dev-idle); - pdev = to_platform_device(dev-dev); - pdata = pdev-dev.platform_data; + pdata = dev-dev-platform_data; - pm_runtime_get_sync(pdev-dev); + pm_runtime_get_sync(dev-dev); if (pdata-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); @@ -299,14 +297,12 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) static void omap_i2c_idle(struct omap_i2c_dev *dev) { - struct platform_device *pdev; struct omap_i2c_bus_platform_data *pdata; u16 iv; WARN_ON(dev-idle); - pdev = to_platform_device(dev-dev); - pdata = pdev-dev.platform_data; + pdata = dev-dev-platform_data; dev-iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); if (pdata-rev == OMAP_I2C_IP_VERSION_2) @@ -324,7 +320,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) } dev-idle = 1; - pm_runtime_put_sync(pdev-dev); + pm_runtime_put_sync(dev-dev); } static int omap_i2c_init(struct omap_i2c_dev *dev) @@ -335,11 +331,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) unsigned long timeout; unsigned long internal_clk = 0; struct clk *fclk; - struct platform_device *pdev; struct omap_i2c_bus_platform_data *pdata; - pdev = to_platform_device(dev-dev); - pdata = pdev-dev.platform_data; + pdata = dev-dev-platform_data; if (dev-rev = OMAP_I2C_OMAP1_REV_2) { /* Disable I2C controller before soft reset */ @@ -821,11 +815,9 @@ omap_i2c_isr(int this_irq, void *dev_id) u16 bits; u16 stat, w; int err, count = 0; - struct platform_device *pdev; struct omap_i2c_bus_platform_data *pdata; - pdev = to_platform_device(dev-dev); - pdata = pdev-dev.platform_data; + pdata = dev-dev-platform_data; if (dev-idle) return IRQ_NONE; @@ -1047,7 +1039,7 @@ omap_i2c_probe(struct platform_device *pdev) else dev-regs = (u8 *)reg_map_ip_v1; - pm_runtime_enable(pdev-dev); + pm_runtime_enable(dev-dev); omap_i2c_unidle(dev); dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/2] I2C: OMAP: remove dev-idle, use usage counting provided by runtime PM
Current usage of runtime PM is not quite correct. The actual idle/unidle of the I2C hardware should not happen until the runtime PM callbacks are called. Therefore, change omap_i2c_[un]idle() functions to only be called from the runtime PM callbacks (when usage count transitions to/from zero.) Also, the runtime PM core does usage counting and replaces functionality currently managed by the dev-idle flag. Remove usage of dev-idle in favor of using runtime PM, and checking status using pm_runtime_suspended(). Signed-off-by: Kevin Hilman khil...@ti.com --- drivers/i2c/busses/i2c-omap.c | 59 +++-- 1 files changed, 39 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 12d0cbc..1c75d13 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -194,7 +194,6 @@ struct omap_i2c_dev { */ u8 rev; unsignedb_hw:1; /* bad h/w fixes */ - unsignedidle:1; u16 iestate;/* Saved interrupt register */ u16 pscstate; u16 scllstate; @@ -269,12 +268,8 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) { struct omap_i2c_bus_platform_data *pdata; - WARN_ON(!dev-idle); - pdata = dev-dev-platform_data; - pm_runtime_get_sync(dev-dev); - if (pdata-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); @@ -285,7 +280,6 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); } - dev-idle = 0; /* * Don't write to this register if the IE state is 0 as it can @@ -300,8 +294,6 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) struct omap_i2c_bus_platform_data *pdata; u16 iv; - WARN_ON(dev-idle); - pdata = dev-dev-platform_data; dev-iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); @@ -315,12 +307,9 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) } else { omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev-iestate); - /* Flush posted write before the dev-idle store occurs */ + /* Flush posted write */ omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); } - dev-idle = 1; - - pm_runtime_put_sync(dev-dev); } static int omap_i2c_init(struct omap_i2c_dev *dev) @@ -644,7 +633,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) int i; int r; - omap_i2c_unidle(dev); + pm_runtime_get_sync(dev-dev); r = omap_i2c_wait_for_bb(dev); if (r 0) @@ -667,7 +656,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) omap_i2c_wait_for_bb(dev); out: - omap_i2c_idle(dev); + pm_runtime_put(dev-dev); return r; } @@ -727,7 +716,7 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id) struct omap_i2c_dev *dev = dev_id; u16 iv, w; - if (dev-idle) + if (pm_runtime_suspended(dev-dev)) return IRQ_NONE; iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); @@ -819,7 +808,7 @@ omap_i2c_isr(int this_irq, void *dev_id) pdata = dev-dev-platform_data; - if (dev-idle) + if (pm_runtime_suspended(dev-dev)) return IRQ_NONE; bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); @@ -1021,7 +1010,6 @@ omap_i2c_probe(struct platform_device *pdev) } dev-speed = speed; - dev-idle = 1; dev-dev = pdev-dev; dev-irq = irq-start; dev-base = ioremap(mem-start, resource_size(mem)); @@ -1040,7 +1028,7 @@ omap_i2c_probe(struct platform_device *pdev) dev-regs = (u8 *)reg_map_ip_v1; pm_runtime_enable(dev-dev); - omap_i2c_unidle(dev); + pm_runtime_get_sync(dev-dev); dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; @@ -1087,7 +1075,7 @@ omap_i2c_probe(struct platform_device *pdev) dev_info(dev-dev, bus %d rev%d.%d.%d at %d kHz\n, pdev-id, pdata-rev, dev-rev 4, dev-rev 0xf, dev-speed); - omap_i2c_idle(dev); + pm_runtime_put(dev-dev); adap = dev-adapter; i2c_set_adapdata(adap, dev); @@ -,7 +1099,7 @@ err_free_irq: free_irq(dev-irq, dev); err_unuse_clocks: omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); - omap_i2c_idle(dev); + pm_runtime_put(dev-dev); iounmap(dev-base); err_free_mem: platform_set_drvdata(pdev, NULL); @@ -1140,12 +1128,43 @@
[PATCH v2 0/2] I2C: OMAP: misc. PM-related cleanups
Do some PM-related cleanup on this driver and make the runtime PM usage more standard. Series applies on Andy's I2C cleanup series (for_3.1/i2c-andy-2 branch in my tree[1]) plus the misc. i2c fixes queued for v3.1-rc (for_3.1/i2c-fixes branch) and are available in the for_3.2/i2c-cleanup branch of my tree. [1] git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git Kevin Hilman (2): I2C: OMAP: remove unneccesary use of pdev I2C: OMAP: remove dev-idle, use usage counting provided by runtime PM drivers/i2c/busses/i2c-omap.c | 77 +++- 1 files changed, 44 insertions(+), 33 deletions(-) -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] Macro for getting the BASEADDRESS field in omap's gpmc configuration
BASEADDRESS is located in the 6 lower bits of the CONFIG7 register. See OMAP 35x Technical Reference Manual, p. 1169. Signed-off-by: David Wagner david.wag...@free-electrons.com --- arch/arm/plat-omap/include/plat/gpmc.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 1527929..154456d 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -72,6 +72,7 @@ #define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2)) #define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3)) #define GPMC_CONFIG7_CSVALID (1 6) +#define GPMC_CONFIG7_BASEADDRESS(val) (val 0x3F) #define GPMC_DEVICETYPE_NOR0 #define GPMC_DEVICETYPE_NAND 2 -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] Use existing GPMC macros instead of bit manipulation
--- arch/arm/mach-omap2/board-igep0020.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 35be778..f89573a 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -175,12 +175,12 @@ static void __init igep_flash_init(void) ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); /* Check if NAND/oneNAND is configured */ - if ((ret 0xC00) == 0x800) + if (GPMC_CONFIG1_DEVICETYPE(ret) == GPMC_DEVICETYPE_NAND) /* NAND found */ pr_err(IGEP: Unsupported NAND found\n); else { ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - if ((ret 0x3F) == (ONENAND_MAP 24)) + if (GPMC_CONFIG7_BASEADDRESS(ret) == (ONENAND_MAP 24)) /* ONENAND found */ onenandcs = cs; } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv5 1/3] OMAP: I2C: Reset support
Shubhrajyoti shubhrajy...@ti.com writes: On Wednesday 03 August 2011 04:53 AM, Kevin Hilman wrote: Shubhrajyoti Dshubhrajy...@ti.com writes: Under some error conditions the i2c driver may do a reset. ^^ minor: extra whitespace Adding a reset field and support in the platform. s/platform/device-specific code/ Yes will fix these. Signed-off-by: Shubhrajyoti Dshubhrajy...@ti.com That being said, omap_device_shutdown() should already do a clean shutdown + reset for you, and i2c-omap.h already has a pointer for -device_shutdown() so a new device_reset() should not be needed. IOW, simply adding pdata-device_shutdown = omap_device_shutdown() should work. i2C has a special reset sequence ie Disable - reset - enable - Poll on reset done. This function is implemented in omap_i2c_reset. The omap_hwmod_reset calls - _reset which calls ocp_softrest or custom reset if it is present.The latter is true for I2C. However I see that omap_device_shutdown - _assert_hardreset However for I2c there doesnt seem to be a HW reset line. Am I missing something? No, my fault. I thought omap_device_shutdown() also did soft reset, but I see that's not the case. You can ignore my comments about using omap_device_shutdown. Kevin -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/2] I2C: OMAP: remove unused function pointers from pdata
Now that this driver is using runtime PM, there is no longer a need for the idle/enable/shutdown function pointers in pdata. Signed-off-by: Kevin Hilman khil...@ti.com --- Here's one more for the i2c-cleanup series include/linux/i2c-omap.h |3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index 56a9924..92a0dc7 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -35,9 +35,6 @@ struct omap_i2c_bus_platform_data { u32 rev; u32 flags; void(*set_mpu_wkup_lat)(struct device *dev, long set); - int (*device_enable) (struct platform_device *pdev); - int (*device_shutdown) (struct platform_device *pdev); - int (*device_idle) (struct platform_device *pdev); }; #endif -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] I2C: OMAP: remove dev-idle, use usage counting provided by runtime PM
Hi, On Thu, Aug 04, 2011 at 07:53:37AM -0700, Kevin Hilman wrote: @@ -1140,6 +1128,36 @@ omap_i2c_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_RUNTIME +static int omap_i2c_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); what happened to dev_get_drvdata(dev) ?? Yes, that would work too since: static inline void *platform_get_drvdata(const struct platform_device *pdev) { return dev_get_drvdata(pdev-dev); } but IMO, readability is better if the driver does platform_set_drvdata() and then the corresponding platform_get_drvdata() fair enough, but if you already have the dev pointer, what's the gain in doing a container_of() just to go back to the dev pointer again ? IMHO, there's really no need for that and just calling dev_get_drvdata() straight is enough. All in all, platform_get_[sg]et_drvdata() are just wrappers for dev_[sg]et_drvdata(). The whole point, was to avoid dev_[sg]et_drvdata(pdev-dev). It's the same with drivername_writel() calls we see on all drivers. Just a wrapper, but you can use __raw_writel() directly if you wish. -- balbi signature.asc Description: Digital signature
[PATCH 2/2] Use existing GPMC macros instead of bit manipulation
Signed-off-by: David Wagner david.wag...@free-electrons.com --- erratum: added the missing s-o-b arch/arm/mach-omap2/board-igep0020.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 35be778..f89573a 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -175,12 +175,12 @@ static void __init igep_flash_init(void) ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); /* Check if NAND/oneNAND is configured */ - if ((ret 0xC00) == 0x800) + if (GPMC_CONFIG1_DEVICETYPE(ret) == GPMC_DEVICETYPE_NAND) /* NAND found */ pr_err(IGEP: Unsupported NAND found\n); else { ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - if ((ret 0x3F) == (ONENAND_MAP 24)) + if (GPMC_CONFIG7_BASEADDRESS(ret) == (ONENAND_MAP 24)) /* ONENAND found */ onenandcs = cs; } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/6] OMAP: misc. PM-related fixes for v3.1-rc
Hi Tony, Here's my current collection of PM-related fixes for the -rc cycle. They are based on the next/board branch of Arnd's arm-soc tree (which has already been merged by Linus) and are also available in the for_3.1/pm-fixes branch of my tree: git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git Kevin Colin Cross (1): OMAP2+: PM: SmartReflex: use put_sync_suspend for IRQ-safe disabling Kevin Hilman (4): OMAP2+: Kconfig: don't select PM in OMAP2PLUS_TYPICAL OMAP1: enable GENERIC_IRQ_CHIP OMAP3: beagle: don't touch omap_device internals OMAP: McBSP: use existing macros for converting between devices Nishanth Menon (1): OMAP3+: SR: ensure pm-runtime callbacks can be invoked with IRQs disabled arch/arm/mach-omap2/Kconfig |1 - arch/arm/mach-omap2/board-omap3beagle.c | 23 ++- arch/arm/mach-omap2/smartreflex.c |3 ++- arch/arm/plat-omap/Kconfig |1 + arch/arm/plat-omap/mcbsp.c |6 +++--- 5 files changed, 16 insertions(+), 18 deletions(-) -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/6] OMAP2+: Kconfig: don't select PM in OMAP2PLUS_TYPICAL
CONFIG_PM is no longer a user-selectable Kconfig option. Rather it is automatically enabled if either CONFIG_SUSPEND or CONFIG_RUNTIME_PM is enabled, so having a 'select PM' here is redunant when 'select CONFIG_PM_RUNTIME' is present. Signed-off-by: Kevin Hilman khil...@ti.com --- arch/arm/mach-omap2/Kconfig |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 4ae6257..57b66d5 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -7,7 +7,6 @@ config ARCH_OMAP2PLUS_TYPICAL default y select AEABI select REGULATOR - select PM select PM_RUNTIME select VFP select NEON if ARCH_OMAP3 || ARCH_OMAP4 -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] OMAP3+: SR: ensure pm-runtime callbacks can be invoked with IRQs disabled
From: Nishanth Menon n...@ti.com SmartReflex should be disabled while entering low power mode due to a) SmartReflex values are not defined for retention voltage, further b) with SmartReflex enabled, if CPU enters lower c-states, FSM will try to bump the voltage to current OPP's voltage for which it has entered c-state; hence SmartReflex needs to be disabled for MPU, CORE and IVA voltage domains in idle path before enabling auto retention voltage achievement on the device. However, since the current pm_runtime setup for SmartReflex devices are setup to allow callbacks to be invoked with interrupts enabled, calling SmartReflex enable/disable from other contexts such as idle paths where preemption is disabled causes warnings such as the following indicating of a potential race. [ 82.023895] [c04d079c] (__irq_svc+0x3c/0x120) from [c04d0484] (_raw_spin_unlock_irq+0x28/0x2c) [ 82.023895] [c04d0484] (_raw_spin_unlock_irq+0x28/0x2c) from [c0323234] (rpm_callback+0x4c/0x68) [ 82.023956] [c0323234] (rpm_callback+0x4c/0x68) from [c0323f7c] (rpm_resume+0x338/0x53c) [ 82.023956] [c0323f7c] (rpm_resume+0x338/0x53c) from [c03243f4] (__pm_runtime_resume+0x48/0x60) [ 82.023986] [c03243f4] (__pm_runtime_resume+0x48/0x60) from [c008aee0] (sr_enable+0xa8/0x19c) [ 82.023986] [c008aee0] (sr_enable+0xa8/0x19c) from [c008b2fc] (omap_sr_enable+0x50/0x90) [ 82.024017] [c008b2fc] (omap_sr_enable+0x50/0x90) from [c00888c0] (omap4_enter_sleep+0x138/0x168) Instead, we use pm_runtime_irq_safe to tell the PM core that callbacks can be invoked in interrupt disabled contexts. Acked-by: Rajendra Nayak rna...@ti.com Signed-off-by: Nishanth Menon n...@ti.com [khil...@ti.com: minor changelog edits] Signed-off-by: Kevin Hilman khil...@ti.com --- arch/arm/mach-omap2/smartreflex.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 2ce2fb7..dc8e86a 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -860,6 +860,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); pm_runtime_enable(pdev-dev); + pm_runtime_irq_safe(pdev-dev); sr_info-pdev = pdev; sr_info-srid = pdev-id; -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/6] OMAP1: enable GENERIC_IRQ_CHIP
OMAP1 needs this also since GPIO driver (common for all OMAPs) is being converted to use generic IRQ chip. Signed-off-by: Kevin Hilman khil...@ti.com --- arch/arm/plat-omap/Kconfig |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 49a4c75..9a4a6bf 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -13,6 +13,7 @@ config ARCH_OMAP1 bool TI OMAP1 select CLKDEV_LOOKUP select CLKSRC_MMIO + select GENERIC_IRQ_CHIP help Systems based on omap7xx, omap15xx or omap16xx -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/6] OMAP2+: PM: SmartReflex: use put_sync_suspend for IRQ-safe disabling
From: Colin Cross ccr...@google.com omap_sr_disable_reset_volt is called with irqs off in omapx_enter_sleep, as part of idle sequence, this eventually calls sr_disable and pm_runtime_put_sync. pm_runtime_put_sync calls rpm_idle, which will enable interrupts in order to call the callback. In this short interval when interrupts are enabled, scenarios such as the following can occur: while interrupts are enabled, the timer interrupt that is supposed to wake the device out of idle occurs and is acked, so when the CPU finally goes to off, the timer is already gone, missing a wakeup event. Further, as the documentation for runtime states: However, subsystems can use the pm_runtime_irq_safe() helper function to tell the PM core that a device's -runtime_suspend() and -runtime_resume() callbacks should be invoked in atomic context with interrupts disabled (-runtime_idle() is still invoked the default way). Hence, replace pm_runtime_put_sync with pm_runtime_put_sync_suspend to invoke the suspend handler and shut off the fclk for SmartReflex module instead of using the idle handler in interrupt disabled context. Signed-off-by: Nishanth Menon n...@ti.com Signed-off-by: Colin Cross ccr...@google.com [khil...@ti.com: minor Subject edits] Signed-off-by: Kevin Hilman khil...@ti.com --- arch/arm/mach-omap2/smartreflex.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index dc8e86a..34c01a7 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -621,7 +621,7 @@ void sr_disable(struct voltagedomain *voltdm) sr_v2_disable(sr); } - pm_runtime_put_sync(sr-pdev-dev); + pm_runtime_put_sync_suspend(sr-pdev-dev); } /** -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/6] OMAP: McBSP: use existing macros for converting between devices
For converting from struct device to platform_device, and from platform_device to struct omap_device, there are existing macros. Use them instead of manual use of container_of(). Signed-off-by: Kevin Hilman khil...@ti.com --- arch/arm/plat-omap/mcbsp.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 3c1fbdc..47016f7 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -260,9 +260,9 @@ EXPORT_SYMBOL(omap_mcbsp_dma_reg_params); #ifdef CONFIG_ARCH_OMAP3 static struct omap_device *find_omap_device_by_dev(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); - return container_of(pdev, struct omap_device, pdev); + struct platform_device *pdev = to_platform_device(dev); + + return to_omap_device(pdev); } static void omap_st_on(struct omap_mcbsp *mcbsp) -- 1.7.6 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] AM3517: Booting up
This patch-set gets the kernel booting up on a AM3517 EVM. The board is able to boot with ramdisk after this,but the MMC and Ethernet drivers are not up yet. Lots of warnings remain which will be addressed in subsequent patches. The patches are tested on master of tmlind/linux-omap-2.6.git. Kernel version is 3.0.0-rc7 and last commit on top of which these patches were added is: 885cf6ff7d3dad4cc44be74b0577d3a554d3ab71: Linux-omap rebuilt: Updated to -rc7, added new boards Cc: Sanjeev Premi pr...@ti.com Cc: Vaibhav Hiremath hvaib...@ti.com --- Abhilash K V (1): AM35x: Using OMAP3 generic hwmods Vaibhav Hiremath (1): omap_twl: Prevent SR to enable for am3517/am3505 devices arch/arm/mach-omap2/board-am3517evm.c| 11 +++ arch/arm/mach-omap2/omap_hwmod.c |3 ++- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 18 ++ arch/arm/mach-omap2/omap_twl.c |8 arch/arm/plat-omap/include/plat/omap_hwmod.h |3 +++ 5 files changed, 42 insertions(+), 1 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] AM35x: Using OMAP3 generic hwmods
This patch enables AM35x SoCs to use generic OMAP3 hwmods (i,e. omap3xxx_hwmods) by allowing board-am3517evm.c to disable the modules which are not present in AM3517. Reviewed-by: Sanjeev Premi pr...@ti.com Signed-off-by: Abhilash K V abhilash...@ti.com --- arch/arm/mach-omap2/board-am3517evm.c| 11 +++ arch/arm/mach-omap2/omap_hwmod.c |3 ++- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 18 ++ arch/arm/plat-omap/include/plat/omap_hwmod.h |3 +++ 4 files changed, 34 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index f3006c3..8a5f232 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -34,6 +34,7 @@ #include plat/board.h #include plat/common.h #include plat/usb.h +#include plat/omap_hwmod.h #include video/omapdss.h #include video/omap-panel-generic-dpi.h @@ -359,11 +360,21 @@ static struct omap_dss_board_info am3517_evm_dss_data = { .default_device = am3517_evm_lcd_device, }; +static char *am3517_unused_hwmods[] = { + iva, + sr1_hwmod, + sr2_hwmod, + mailbox, + usb_otg_hs, + NULL, +}; + /* * Board initialization */ static void __init am3517_evm_init_early(void) { + omap2_disable_unused_hwmods(am3517_unused_hwmods); omap2_init_common_infrastructure(); omap2_init_common_devices(NULL, NULL); } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 84cc0bd..bb765b5 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1954,7 +1954,8 @@ int __init omap_hwmod_register(struct omap_hwmod **ohs) i = 0; do { - if (!omap_chip_is(ohs[i]-omap_chip)) + if (!omap_chip_is(ohs[i]-omap_chip) + || (ohs[i]-flags HWMOD_UNUSED)) continue; r = _register(ohs[i]); diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 25bf43b..5c282bb 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3281,6 +3281,24 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { NULL, }; +void __init omap2_disable_unused_hwmods(char *unused_hwmods[]) +{ + int index; + + for (index = 0; omap3xxx_hwmods[index]; index++) { + char **hwmods = unused_hwmods; + while (*hwmods) { + if (strcmp(omap3xxx_hwmods[index]-name, + *hwmods) == 0) { + omap3xxx_hwmods[index]-flags + = HWMOD_UNUSED; + break; + } + hwmods++; + } + } +} + int __init omap3xxx_hwmod_init(void) { return omap_hwmod_register(omap3xxx_hwmods); diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 0e329ca..490a95a 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -398,6 +398,7 @@ struct omap_hwmod_omap4_prcm { * in order to complete the reset. Optional clocks will be disabled * again after the reset. * HWMOD_16BIT_REG: Module has 16bit registers + * HWMOD_UNUSED: The IP for this module is unused or disabled on current SoC */ #define HWMOD_SWSUP_SIDLE (1 0) #define HWMOD_SWSUP_MSTANDBY (1 1) @@ -408,6 +409,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_NO_IDLEST(1 6) #define HWMOD_CONTROL_OPT_CLKS_IN_RESET(1 7) #define HWMOD_16BIT_REG(1 8) +#define HWMOD_UNUSED (1 9) /* * omap_hwmod._int_flags definitions @@ -615,5 +617,6 @@ extern int omap2420_hwmod_init(void); extern int omap2430_hwmod_init(void); extern int omap3xxx_hwmod_init(void); extern int omap44xx_hwmod_init(void); +extern void omap2_disable_unused_hwmods(char *unused_hwmods[]); #endif -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] omap_twl: Prevent SR to enable for am3517/am3505 devices
From: Vaibhav Hiremath hvaib...@ti.com In case of AM3517 AM3505, Smart Reflex is not applicable so we must not enable it. So add check for am3517/05 cpu revision in omap3_twl_init() and return -ENODEV if true, else continue. Signed-off-by: Vaibhav Hiremath hvaib...@ti.com Signed-off-by: Abhilash K V abhilash...@ti.com --- arch/arm/mach-omap2/omap_twl.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 07d6140..92fadcb 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -269,6 +269,14 @@ int __init omap3_twl_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + /* +* In case of AM3517/AM3505 we should not be going down +* further, since SR is not applicable there. +*/ + if (cpu_is_omap3505() || cpu_is_omap3517()) { + return -ENODEV; + } + if (cpu_is_omap3630()) { omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN; omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv5 2/3] OMAP: I2C: Remove the reset in the init path
On Wednesday 03 August 2011 04:57 AM, Kevin Hilman wrote: Shubhrajyoti Dshubhrajy...@ti.com writes: - The reset in the driver at init is not needed anymore as the hwmod framework takes care of reseting it. - Reset is removed from omap_i2c_init, which was called not only during probe, but also after time out and error handling. device_reset were added in those places to effect the reset. Not specifically related to this patch, as the reset behavior was already there, but do you know why the reset is needed after timeout and error handling? IOW, was the reset truly required in those cases, or was just the re-init necessary? To me doing a full reset of the IP in those cases sounds like a hack for a buggy driver. My idea, there have been errata workaround that recommend reset in case of a lockup that may happen after a warmreset. - Earlier the hwmod SYSC settings were over-written in the driver. Removing the same and letting the hwmod take care of the settings. - Clean up the SYSS_RESETDONE_MASK macro as it is no longer needed. - Clean up the SYSCONFIG SYSC bit defination macros. - Fix the typos in wakeup. Signed-off-by: Shubhrajyoti Dshubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 83 +++-- 1 files changed, 22 insertions(+), 61 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 4e3256f..d8f4470 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -155,19 +155,6 @@ enum { #define OMAP_I2C_SYSTEST_SDA_O(1 0) /* SDA line drive out */ #endif -/* OCP_SYSSTATUS bit definitions */ -#define SYSS_RESETDONE_MASK(1 0) - -/* OCP_SYSCONFIG bit definitions */ -#define SYSC_CLOCKACTIVITY_MASK(0x3 8) -#define SYSC_SIDLEMODE_MASK(0x3 3) -#define SYSC_ENAWAKEUP_MASK(1 2) -#define SYSC_SOFTRESET_MASK(1 1) -#define SYSC_AUTOIDLE_MASK (1 0) - -#define SYSC_IDLEMODE_SMART0x2 -#define SYSC_CLOCKACTIVITY_FCLK0x2 - /* Errata definitions */ #define I2C_OMAP_ERRATA_I207 (1 0) #define I2C_OMAP3_1P153 (1 1) @@ -182,6 +169,7 @@ struct omap_i2c_dev { u32 latency;/* maximum mpu wkup latency */ void(*set_mpu_wkup_lat)(struct device *dev, long latency); + int (*device_reset)(struct device *dev); u32 speed; /* Speed of bus in Khz */ u16 cmd_err; u8 *buf; @@ -317,60 +305,22 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) u16 psc = 0, scll = 0, sclh = 0, buf = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; - unsigned long timeout; unsigned long internal_clk = 0; struct clk *fclk; struct omap_i2c_bus_platform_data *pdata; pdata = dev-dev-platform_data; - if (dev-rev= OMAP_I2C_OMAP1_REV_2) { - /* Disable I2C controller before soft reset */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, - omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) - ~(OMAP_I2C_CON_EN)); - - omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK); - /* For some reason we need to set the EN bit before the -* reset done bit gets set. */ - timeout = jiffies + OMAP_I2C_TIMEOUT; - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - while (!(omap_i2c_read_reg(dev, OMAP_I2C_SYSS_REG) -SYSS_RESETDONE_MASK)) { - if (time_after(jiffies, timeout)) { - dev_warn(dev-dev, timeout waiting - for controller reset\n); - return -ETIMEDOUT; - } - msleep(1); - } - - /* SYSC register is cleared by the reset; rewrite it */ - if (dev-rev == OMAP_I2C_REV_ON_2430) { - - omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, - SYSC_AUTOIDLE_MASK); - - } else if (dev-rev= OMAP_I2C_REV_ON_3430) { - dev-syscstate = SYSC_AUTOIDLE_MASK; - dev-syscstate |= SYSC_ENAWAKEUP_MASK; - dev-syscstate |= (SYSC_IDLEMODE_SMART - __ffs(SYSC_SIDLEMODE_MASK)); - dev-syscstate |= (SYSC_CLOCKACTIVITY_FCLK - __ffs(SYSC_CLOCKACTIVITY_MASK)); - - omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, -
RE: [PATCH 1/2] TI816X: Add minimal hwmod data
Hi Paul, Paul Walmsley wrote on Saturday, July 16, 2011 1:38 PM: Hello Hemant, On Wed, 13 Jul 2011, Pedanekar, Hemant wrote: Any comments on the hwmod and clock patch sets? I haven't forgotten about these patches. Here are a few questions: Sorry I missed this mail. - Are there are public documents about what interconnect is used on these chips? Is it a SonicsMX, an Arteris NOC, or something else? I will get back to you on this. - It looks like you've grouped the PRCM implementation with the existing OMAP3 PRCM code. But it appears to me, looking at the 816X TRM, that the register layout is closer to OMAP4 - the MODULEMODE bits, etc. Any comments on this? You are correct. The register layout is closer to OMAP4 hence I have Used .omap4 from PRCM data union field in struct omap_hwmod for Hwmod data. Thanks. Hemant-- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 3/4] TI816X: clock: Add clockdomains and powerdomains data
Paul Walmsley wrote on Saturday, July 16, 2011 1:25 PM: On Fri, 25 Mar 2011, Hemant Pedanekar wrote: This patch adds data for various clock domains and power domains in TI816X. Note that at present this is not exhaustive and need to add missing domains. Signed-off-by: Hemant Pedanekar hema...@ti.com --- arch/arm/mach-omap2/clockdomains816x.h | 167 arch/arm/mach-omap2/powerdomains816x.h | 74 ++ 2 files changed, 241 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-omap2/clockdomains816x.h create mode 100644 arch/arm/mach-omap2/powerdomains816x.h Static data shouldn't be declared in .h files; it should be declared in *domains81*_data.c files, as is the practice with the rest of the powerdomains/clockdomains data here. Will take care of this in next version. Thanks. Hemant-- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] Add support for TI814X processor series
This patch set adds support for DM814x, C6A814x and AM387x device series having Cortex-A8 MPU. The technical documents are available from following link: http://focus.ti.com/docs/prod/folders/print/tms320dm8148.html This series is referred in code as TI814X. Since these devices share similar architecture as TI816X devices, existing TI816X code is updated to accomodate TI814X support. The code shared across TI816X and TI814X devices is updated with TI81XX/ti81xx prefix as applicable, while maintaining cpu_is_ti816x() and cpu_is_ti814x() to distinguish specific execution differences. Hemant Pedanekar (3): TI81XX: Prepare for addition of TI814X support TI814X: Add cpu type macros and detection support TI814X: Create board support and enable build for TI8148 EVM arch/arm/mach-omap2/Kconfig| 11 +++- arch/arm/mach-omap2/Makefile |1 + arch/arm/mach-omap2/board-ti8148evm.c | 57 arch/arm/mach-omap2/board-ti8168evm.c |6 +- arch/arm/mach-omap2/clock.c|2 +- arch/arm/mach-omap2/clock.h|2 +- arch/arm/mach-omap2/clock3xxx_data.c |5 ++- arch/arm/mach-omap2/common.c | 22 arch/arm/mach-omap2/control.h |8 ++-- arch/arm/mach-omap2/id.c | 26 -- arch/arm/mach-omap2/include/mach/debug-macro.S | 12 ++-- arch/arm/mach-omap2/include/mach/entry-macro.S |4 +- arch/arm/mach-omap2/io.c | 10 ++-- arch/arm/mach-omap2/irq.c |2 +- arch/arm/mach-omap2/opp2xxx.h |2 +- arch/arm/mach-omap2/serial.c |6 +- arch/arm/plat-omap/include/plat/clkdev_omap.h |1 + arch/arm/plat-omap/include/plat/clock.h|3 +- arch/arm/plat-omap/include/plat/common.h |2 +- arch/arm/plat-omap/include/plat/cpu.h | 25 - arch/arm/plat-omap/include/plat/hardware.h |2 +- arch/arm/plat-omap/include/plat/io.h |6 +- arch/arm/plat-omap/include/plat/irqs.h |2 +- arch/arm/plat-omap/include/plat/serial.h | 14 +++--- .../plat-omap/include/plat/{ti816x.h = ti81xx.h} | 18 +++--- arch/arm/plat-omap/include/plat/uncompress.h | 11 +++-- arch/arm/plat-omap/io.c|2 +- 27 files changed, 187 insertions(+), 75 deletions(-) create mode 100644 arch/arm/mach-omap2/board-ti8148evm.c rename arch/arm/plat-omap/include/plat/{ti816x.h = ti81xx.h} (60%) -- 1.7.3.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] TI81XX: Prepare for addition of TI814X support
This patch updates existing macros, functions used for TI816X, to enable addition of other SoCs belonging to TI81XX family (e.g., TI814X). The approach taken is to use TI81XX/ti81xx for code/data going to be common across all TI81XX devices. cpu_is_ti81xx() is introduced to handle code common across TI81XX devices. Signed-off-by: Hemant Pedanekar hema...@ti.com --- arch/arm/mach-omap2/Kconfig|6 ++-- arch/arm/mach-omap2/board-ti8168evm.c |6 ++-- arch/arm/mach-omap2/clock3xxx_data.c |2 +- arch/arm/mach-omap2/common.c | 22 ++-- arch/arm/mach-omap2/control.h |8 +++--- arch/arm/mach-omap2/id.c |8 +++--- arch/arm/mach-omap2/include/mach/debug-macro.S | 12 +- arch/arm/mach-omap2/include/mach/entry-macro.S |4 +- arch/arm/mach-omap2/io.c | 10 arch/arm/mach-omap2/irq.c |2 +- arch/arm/mach-omap2/serial.c |6 ++-- arch/arm/plat-omap/include/plat/common.h |2 +- arch/arm/plat-omap/include/plat/cpu.h | 13 +++ arch/arm/plat-omap/include/plat/hardware.h |2 +- arch/arm/plat-omap/include/plat/io.h |6 ++-- arch/arm/plat-omap/include/plat/irqs.h |2 +- arch/arm/plat-omap/include/plat/serial.h | 14 ++-- .../plat-omap/include/plat/{ti816x.h = ti81xx.h} | 18 arch/arm/plat-omap/include/plat/uncompress.h |8 +++--- arch/arm/plat-omap/io.c|2 +- 20 files changed, 83 insertions(+), 70 deletions(-) rename arch/arm/plat-omap/include/plat/{ti816x.h = ti81xx.h} (60%) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index d5e4b60..242d9ab 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -74,8 +74,8 @@ config SOC_OMAP3430 default y select ARCH_OMAP_OTG -config SOC_OMAPTI816X - bool TI816X support +config SOC_OMAPTI81XX + bool TI81XX support depends on ARCH_OMAP3 default y @@ -314,7 +314,7 @@ config MACH_OMAP_3630SDP config MACH_TI8168EVM bool TI8168 Evaluation Module - depends on SOC_OMAPTI816X + depends on SOC_OMAPTI81XX default y config MACH_OMAP_4430SDP diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index a85d5b0..e516a04 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -42,8 +42,8 @@ static void __init ti8168_evm_init(void) static void __init ti8168_evm_map_io(void) { - omap2_set_globals_ti816x(); - omapti816x_map_common_io(); + omap2_set_globals_ti81xx(); + omapti81xx_map_common_io(); } MACHINE_START(TI8168EVM, ti8168evm) @@ -51,7 +51,7 @@ MACHINE_START(TI8168EVM, ti8168evm) .boot_params= 0x8100, .map_io = ti8168_evm_map_io, .init_early = ti8168_init_early, - .init_irq = ti816x_init_irq, + .init_irq = ti81xx_init_irq, .timer = omap3_timer, .init_machine = ti8168_evm_init, MACHINE_END diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index ffd55b1..10cf22f 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3565,7 +3565,7 @@ int __init omap3xxx_clk_init(void) * Lock DPLL5 -- here only until other device init code can * handle this */ - if (!cpu_is_ti816x() (omap_rev() = OMAP3430_REV_ES2_0)) + if (!cpu_is_ti81xx() (omap_rev() = OMAP3430_REV_ES2_0)) omap3_clk_lock_dpll5(); /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index 3f20cbb..7ce80f2 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -101,23 +101,23 @@ void __init omap3_map_io(void) /* * Adjust TAP register base such that omap3_check_revision accesses the correct - * TI816X register for checking device ID (it adds 0x204 to tap base while - * TI816X DEVICE ID register is at offset 0x600 from control base). + * TI81XX register for checking device ID (it adds 0x204 to tap base while + * TI81XX DEVICE ID register is at offset 0x600 from control base). */ -#define TI816X_TAP_BASE(TI816X_CTRL_BASE + \ - TI816X_CONTROL_DEVICE_ID - 0x204) +#define TI81XX_TAP_BASE(TI81XX_CTRL_BASE + \ + TI81XX_CONTROL_DEVICE_ID - 0x204) -static struct omap_globals ti816x_globals = { +static struct omap_globals ti81xx_globals = { .class = OMAP343X_CLASS, - .tap= OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE), - .ctrl =
[PATCH 2/3] TI814X: Add cpu type macros and detection support
This patch adds cpu type, macros for identification of TI814X device. Note that following updates to common OMAP data structures are made: 1) struct omap_chip_id member 'oc' is updated to u32 from u16 as omap chip bitfield has exhausted 16 bits for CHIP_IS_XXX. 2) cpu_mask and RATE_IN_XXX flags have crossed 8 bit hence struct clksel_rate.flags, struct prcm_config.flags and cpu_mask are changed to u16 from u8. Signed-off-by: Hemant Pedanekar hema...@ti.com --- arch/arm/mach-omap2/clock.c |2 +- arch/arm/mach-omap2/clock.h |2 +- arch/arm/mach-omap2/clock3xxx_data.c |3 +++ arch/arm/mach-omap2/id.c | 18 ++ arch/arm/mach-omap2/opp2xxx.h |2 +- arch/arm/plat-omap/include/plat/clkdev_omap.h |1 + arch/arm/plat-omap/include/plat/clock.h |3 ++- arch/arm/plat-omap/include/plat/cpu.h | 12 +++- 8 files changed, 38 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 1f3481f..f57ed5b 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -35,7 +35,7 @@ #include cm-regbits-24xx.h #include cm-regbits-34xx.h -u8 cpu_mask; +u16 cpu_mask; /* * clkdm_control: if true, then when a clock is enabled in the diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 48ac568..687d3d3 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -130,7 +130,7 @@ void omap2_clk_print_new_rates(const char *hfclkin_ck_name, const char *core_ck_name, const char *mpu_ck_name); -extern u8 cpu_mask; +extern u16 cpu_mask; extern const struct clkops clkops_omap2_dflt_wait; extern const struct clkops clkops_dummy; diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 10cf22f..af58741 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3482,6 +3482,9 @@ int __init omap3xxx_clk_init(void) } else if (cpu_is_ti816x()) { cpu_mask = RATE_IN_TI816X; cpu_clkflg = CK_TI816X; + } else if (cpu_is_ti814x()) { + cpu_mask = RATE_IN_TI814X; + cpu_clkflg = CK_TI814X; } else if (cpu_is_omap34xx()) { if (omap_rev() == OMAP3430_REV_ES1_0) { cpu_mask = RATE_IN_3430ES1; diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 3d84fca..98f1922 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -346,6 +346,22 @@ static void __init omap3_check_revision(void) omap_revision = TI8168_REV_ES1_1; } break; + case 0xb8f2: + omap_chip.oc = CHIP_IS_TI814X; + + switch (rev) { + case 0: + /* FALLTHROUGH */ + case 1: + omap_revision = TI8148_REV_ES1_0; + break; + case 2: + omap_revision = TI8148_REV_ES2_0; + break; + default: + omap_revision = TI8148_REV_ES2_1; + } + break; default: /* Unknown default to latest silicon rev as default*/ omap_revision = OMAP3630_REV_ES1_2; @@ -451,6 +467,8 @@ static void __init omap3_cpuinfo(void) } } else if (cpu_is_ti816x()) { strcpy(cpu_name, TI816X); + } else if (cpu_is_ti814x()) { + strcpy(cpu_name, TI814X); } else if (omap3_has_iva() omap3_has_sgx()) { /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ strcpy(cpu_name, OMAP3430/3530); diff --git a/arch/arm/mach-omap2/opp2xxx.h b/arch/arm/mach-omap2/opp2xxx.h index 8affc66..8fae534 100644 --- a/arch/arm/mach-omap2/opp2xxx.h +++ b/arch/arm/mach-omap2/opp2xxx.h @@ -51,7 +51,7 @@ struct prcm_config { unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */ unsigned long cm_clksel_mdm;/* modem dividers 2430 only */ unsigned long base_sdrc_rfr;/* base refresh timing for a set */ - unsigned char flags; + unsigned short flags; }; diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h index 387a963..3c50ec8 100644 --- a/arch/arm/plat-omap/include/plat/clkdev_omap.h +++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h @@ -40,6 +40,7 @@ struct omap_clk { #define CK_443X(1 11) #define CK_TI816X (1 12) #define CK_446X(1 13) +#define CK_TI814X (1 14) #define CK_34XX(CK_3430ES1 | CK_3430ES2PLUS) diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index df4b968..1c41292 100644 ---
[PATCH 3/3] TI814X: Create board support and enable build for TI8148 EVM
This patch adds minimal support and build configuration for TI8148 EVM. Also adds support for low level debugging on UART1 console on the EVM. Signed-off-by: Hemant Pedanekar hema...@ti.com --- arch/arm/mach-omap2/Kconfig |5 ++ arch/arm/mach-omap2/Makefile |1 + arch/arm/mach-omap2/board-ti8148evm.c| 57 ++ arch/arm/plat-omap/include/plat/uncompress.h |3 + 4 files changed, 66 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-omap2/board-ti8148evm.c diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 242d9ab..4dacb8e 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -317,6 +317,11 @@ config MACH_TI8168EVM depends on SOC_OMAPTI81XX default y +config MACH_TI8148EVM + bool TI8148 Evaluation Module + depends on SOC_OMAPTI81XX + default y + config MACH_OMAP_4430SDP bool OMAP 4430 SDP board default y diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index fb02937..fa54361 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -262,6 +262,7 @@ obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o \ hsmmc.o obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o +obj-$(CONFIG_MACH_TI8148EVM) += board-ti8148evm.o # Platform specific device init code usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o obj-y += $(usbfs-m) $(usbfs-y) diff --git a/arch/arm/mach-omap2/board-ti8148evm.c b/arch/arm/mach-omap2/board-ti8148evm.c new file mode 100644 index 000..588d6b7 --- /dev/null +++ b/arch/arm/mach-omap2/board-ti8148evm.c @@ -0,0 +1,57 @@ +/* + * Code for TI8148 EVM. + * + * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ + * + * 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. + * + * This program is distributed as is WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include linux/kernel.h +#include linux/init.h + +#include mach/hardware.h +#include asm/mach-types.h +#include asm/mach/arch.h +#include asm/mach/map.h + +#include plat/irqs.h +#include plat/board.h +#include plat/common.h + +static struct omap_board_config_kernel ti8148_evm_config[] __initdata = { +}; + +static void __init ti8148_init_early(void) +{ + omap2_init_common_infrastructure(); + omap2_init_common_devices(NULL, NULL); +} + +static void __init ti8148_evm_init(void) +{ + omap_serial_init(); + omap_board_config = ti8148_evm_config; + omap_board_config_size = ARRAY_SIZE(ti8148_evm_config); +} + +static void __init ti8148_evm_map_io(void) +{ + omap2_set_globals_ti81xx(); + omapti81xx_map_common_io(); +} + +MACHINE_START(TI8148EVM, ti8148evm) + /* Maintainer: Texas Instruments */ + .boot_params= 0x8100, + .map_io = ti8148_evm_map_io, + .init_early = ti8148_init_early, + .init_irq = ti81xx_init_irq, + .timer = omap3_timer, + .init_machine = ti8148_evm_init, +MACHINE_END diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index 40336ad..8d052e7 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -175,6 +175,9 @@ static inline void __arch_decomp_setup(unsigned long arch_id) /* TI8168 base boards using UART3 */ DEBUG_LL_TI81XX(3, ti8168evm); + /* TI8148 base boards using UART1 */ + DEBUG_LL_TI81XX(1, ti8148evm); + } while (0); } -- 1.7.3.5 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/4] Omap-related warnings compiling current mainline 3.1-rc tree
Compiling the current mainline tree (commit 288d5abec8314ae50fe6692f324b0444acae8486) produces some omap-related warnings. Most of them are harmless, and they are simple enough to fix that even I can do it. I hope.. The compiler warnings from running `make omap2plus_defconfig uImage CONFIG_DEBUG_SECTION_MISMATCH=1': ... CC arch/arm/mach-omap2/clock44xx_data.o arch/arm/mach-omap2/clock44xx_data.c: In function 'omap4xxx_clk_init': arch/arm/mach-omap2/clock44xx_data.c:3371: warning: 'cpu_clkflg' may be used uninitialized in this function ... CC arch/arm/mach-omap2/usb-musb.o arch/arm/mach-omap2/usb-musb.c:71: warning: 'usb_musb_mux_init' defined but not used arch/arm/mach-omap2/usb-musb.c: In function 'usb_musb_init': arch/arm/mach-omap2/usb-musb.c:141: warning: 'dev' may be used uninitialized in this function ... CC arch/arm/mach-omap2/display.o arch/arm/mach-omap2/display.c: In function 'omap_display_init': arch/arm/mach-omap2/display.c:101: warning: assignment from incompatible pointer type ... LD arch/arm/mach-omap2/built-in.o WARNING: arch/arm/mach-omap2/built-in.o(.data+0x354d0): Section mismatch in reference from the variable keypad_data to the (unknown reference) .init.data:(unknown) The variable keypad_data references the (unknown reference) __initdata (unknown) By applying the patches is this series, most of these warnings are gone. The warning from omap_display has not been fixed. I could do something similar to what hsmmc.c is using, but I think this is unnessarily complex. I think the real fix for this warning is to make the type of the returned value from omap_pm_get_dev_context_loss_count() be the same as the prototype in struct omap_dss_board_info. I can't see why one should be u32, and the other int. However, I don't know which to fix.. The resulting kernel has been booted on a pandaboard. Please note that commit a0bfa1373859e9d11dc92561a8667588803e42d8 introduces a typo in arch/arm/kernel/process.c, and this needs to be fixed in order to even compile the kernel. Please see attached patch. This patch is sufficient to make it compile, but probably not a complete fix for the problems introduced by the changes to cpu_idle. There is still a boot messages from lockdep pointing to cpu_idle. Bjarne Steinsbo 0001-cpuidle-fix-typos.patch Description: Binary data
[PATCH 1/4] OMAP4: clockdata: Make compiler shut up about possible uninitialized variable
Stop `warning: 'cpu_clkflg' may be used uninitialized in this function' from compiler. --- arch/arm/mach-omap2/clock44xx_data.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 2af0e3f..a9c19c8 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -3368,7 +3368,7 @@ static struct omap_clk omap44xx_clks[] = { int __init omap4xxx_clk_init(void) { struct omap_clk *c; - u32 cpu_clkflg; + u32 cpu_clkflg = 0; if (cpu_is_omap44xx()) { cpu_mask = RATE_IN_4430; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] OMAP4: Keyboard: Fix section mismatch in the board file
`keypad_pads' is referred to by `keypad_data' which is not __initdata, so `keypad_pads' should not be __initdata either. --- arch/arm/mach-omap2/board-4430sdp.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index c7cef44..9e423ac 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -129,7 +129,7 @@ static const int sdp4430_keymap[] = { KEY(7, 6, KEY_OK), KEY(7, 7, KEY_DOWN), }; -static struct omap_device_pad keypad_pads[] __initdata = { +static struct omap_device_pad keypad_pads[] = { { .name = kpd_col1.kpd_col1, .enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1, }, -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] usb: musb: OMAP4430: Remove incorrect call to omap4430_phy_init()
Don't call omap4430_phy_init(dev) before dev is initialized. The real omap4430_phy_init(dev) call is done at the end of this function. --- arch/arm/mach-omap2/usb-musb.c |3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index a65145b..19e4dac 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -137,9 +137,6 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) musb_plat.mode = board_data-mode; musb_plat.extvbus = board_data-extvbus; - if (cpu_is_omap44xx()) - omap4430_phy_init(dev); - if (cpu_is_omap3517() || cpu_is_omap3505()) { oh_name = am35x_otg_hs; name = musb-am35x; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] usb: musb: OMAP: Delete unused function
Not in use anymore. --- arch/arm/mach-omap2/usb-musb.c | 38 -- 1 files changed, 0 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 19e4dac..852d6e4 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -68,44 +68,6 @@ static struct omap_device_pm_latency omap_musb_latency[] = { }, }; -static void usb_musb_mux_init(struct omap_musb_board_data *board_data) -{ - switch (board_data-interface_type) { - case MUSB_INTERFACE_UTMI: - omap_mux_init_signal(usba0_otg_dp, OMAP_PIN_INPUT); - omap_mux_init_signal(usba0_otg_dm, OMAP_PIN_INPUT); - break; - case MUSB_INTERFACE_ULPI: - omap_mux_init_signal(usba0_ulpiphy_clk, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_stp, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dir, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_nxt, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dat0, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dat1, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dat2, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dat3, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dat4, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dat5, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dat6, - OMAP_PIN_INPUT_PULLDOWN); - omap_mux_init_signal(usba0_ulpiphy_dat7, - OMAP_PIN_INPUT_PULLDOWN); - break; - default: - break; - } -} - static struct omap_musb_board_data musb_default_board_data = { .interface_type = MUSB_INTERFACE_ULPI, .mode = MUSB_OTG, -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
On Thursday, August 04, 2011, Mark Brown wrote: On Wed, Aug 03, 2011 at 12:16:17AM +0200, Rafael J. Wysocki wrote: On Tuesday, August 02, 2011, Kevin Hilman wrote: I disagree and think that both are quite realistic (mainly because they exist today, albiet mostly out of tree because no generic QoS framework exist. e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting per-device wakeup latencies, and drivers and frameworks are using them.) I'm sure there are frameworks using such things. I'm also sure there are frameworks that don't. BTW, the we have it out of the tree argument is not very useful, so I'd appreciate it if you didn't use it. It's useful to know if people have tried things; it doesn't mean it's going to be OK for mainline but it is a data point. In this case, the video framework (V4L2) might not want any knobs exposed to userspace because userspace simply doesn't have the knowledge to set appropriate constraints. I'm less familiar with audio, but I believe audio would be similar (sample rate, number of channels, mixing with other concurrent audio streams, etc. etc. are all known by the kernel-side code.) Yeah, that sort of stuff and also data like wakeup latencies required to service interrupts. I still don't understand what's wrong with allowing user space to _add_ requirements. The will only override the drivers' or frameworks' requirements if they are stronger, so the functionality shouldn't be hurt. They may cause some more energy to be used, but if user space wants that, it's pretty much fine by me. On the one hand that's true. On the other hand that just seems like going down a bad road where we have drivers that only work when run with a magic userspace that may or may not be published which is just going to make people miserable. I'm not sure there are many people who would choose to use more power without wanting some functional change so presumably any users would be seeking to work around some kernel problem and adding the user interface seems to be saying that this is OK, expected and a natural part of power optimization. First off, we're doing this already (user space can block runtime PM, for one example, because there are systems where runtime PM doesn't work although it works on other systems with analogous hardware and pretty much the same set of drivers). Second, I think there are valid use cases in which user space _really_ knows better than the kernel. I'm opposed to the idea that users shouldn't be given control of their systems, because they may not know what they're doing. Thanks, Rafael -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: musb: use put_sync_suspend instead of put_sync
From: Axel Haslam axelhas...@ti.com As Documented in runtime documentation, drivers can call put_sync in contexts where sleep is allowed, in contexts where sleep is not possible, the drivers need to mark these as to be made interrupt safe and also use put_sync_suspend instead of put_sync as the idle callbacks will be called with interrupt enabled - which is not a good thing to happen in isr context. BUG: sleeping function called from invalid context at drivers/base/power/runtime.c:798 in_atomic(): 0, irqs_disabled(): 0, pid: 44, name: irq/164-fsa9480 Backtrace: [c00520f0] (dump_backtrace+0x0/0x110) from [c059c1bc] (dump_stack+0x18/0x1c) r6:de41bcd8 r5:72b6 r4:6f03 r3:6113 [c059c1a4] (dump_stack+0x0/0x1c) from [c007e370] (__might_sleep+0x130/0x134) [c007e240] (__might_sleep+0x0/0x134) from [c02b2cc0] (__pm_runtime_resume+0x94/0x98) r5:0004 r4:de58a408 [c02b2c2c] (__pm_runtime_resume+0x0/0x98) from [c0367b30] (musb_otg_notifications+0x90/0x140) r7:c07c8220 r6:de41bcd8 r5:c0760494 r4:de41b000 [c0367aa0] (musb_otg_notifications+0x0/0x140) from [c00b2bc8] (notifier_call_chain+0x4c/0x8c) r5: r4: [c00b2b7c] (notifier_call_chain+0x0/0x8c) from [c00b3280] (__atomic_notifier_call_chain+0x40/0x54) r8:0004 r7:0001 r6:de41bcd8 r5: r4:c078ca38 A call to pm_runtime_irq_safe, will indefently prevent the parent from sleeping by doing a call to get-sync on the parent. this is to prevent a irq-safe child to wait for a non-irq safe parent. For this reason, the parent runtime-pm suspend is blocked, and we dont let L3 and CORE enter into low power. As a workaround, we call the parent runtime functions on the child runtime hooks, for this to work, the parent has to be set to ignere children, otherwise, even with a timmed autosuspend call, will return BUSY, as the child is not yet suspended. This patch is based off: https://lkml.org/lkml/2011/7/20/357 Signed-off-by: Axel Haslam axelhas...@ti.com Reported-by: Colin Cross ccr...@google.com Signed-off-by: Moiz Sonasath m-sonas...@ti.com --- drivers/usb/musb/musb_core.c |9 + drivers/usb/musb/musb_gadget.c |2 +- drivers/usb/musb/omap2430.c|4 +++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index c71b037..d22bc73 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1941,7 +1941,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) pm_runtime_use_autosuspend(musb-controller); pm_runtime_set_autosuspend_delay(musb-controller, 200); + pm_runtime_use_autosuspend(musb-controller-parent); + pm_runtime_set_autosuspend_delay(musb-controller-parent, 500); + pm_suspend_ignore_children(musb-controller-parent,true); pm_runtime_enable(musb-controller); + pm_runtime_irq_safe(musb-controller); spin_lock_init(musb-lock); musb-board_mode = plat-mode; @@ -2375,6 +2379,9 @@ static int musb_runtime_suspend(struct device *dev) musb_save_context(musb); + pm_runtime_mark_last_busy(musb-controller-parent); + pm_runtime_put_autosuspend(musb-controller-parent); + return 0; } @@ -2392,6 +2399,8 @@ static int musb_runtime_resume(struct device *dev) * Also context restore without save does not make * any sense */ + if (pm_runtime_suspended(dev-parent)) + pm_runtime_get_sync(dev-parent); if (!first) musb_restore_context(musb); first = 0; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 548338c..d5d8f3a 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1710,7 +1710,7 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) } spin_unlock_irqrestore(musb-lock, flags); - pm_runtime_put(musb-controller); + pm_runtime_put_sync_suspend(musb-controller); return 0; } diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index c5d4c44..8b6888d 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -471,6 +471,7 @@ static int __init omap2430_probe(struct platform_device *pdev) } pm_runtime_enable(pdev-dev); + pm_runtime_irq_safe(pdev-dev); return 0; @@ -516,7 +517,8 @@ static int omap2430_runtime_resume(struct device *dev) struct musb *musb = glue_to_musb(glue); omap2430_low_level_init(musb); - otg_set_suspend(musb-xceiv, 0); + if (musb-xceiv) + otg_set_suspend(musb-xceiv, 0); return 0; } -- 1.6.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] I2C: OMAP: remove dev-idle, use usage counting provided by runtime PM
Felipe Balbi ba...@ti.com writes: Hi, On Thu, Aug 04, 2011 at 07:53:37AM -0700, Kevin Hilman wrote: @@ -1140,6 +1128,36 @@ omap_i2c_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_RUNTIME +static int omap_i2c_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); what happened to dev_get_drvdata(dev) ?? Yes, that would work too since: static inline void *platform_get_drvdata(const struct platform_device *pdev) { return dev_get_drvdata(pdev-dev); } but IMO, readability is better if the driver does platform_set_drvdata() and then the corresponding platform_get_drvdata() fair enough, but if you already have the dev pointer, what's the gain in doing a container_of() just to go back to the dev pointer again ? There is no gain, but there is no loss either. The compiler is smart enough that the resulting assembly is the same. IMHO, there's really no need for that and just calling dev_get_drvdata() straight is enough. All in all, platform_get_[sg]et_drvdata() are just wrappers for dev_[sg]et_drvdata(). The whole point, was to avoid dev_[sg]et_drvdata(pdev-dev). Well, whether or not to use dev_[gs]et_* or platform_[gs]et_* is not relevant to $SUBJECT patch. The current driver does platform_set_drvdata(), so I used platform_get_drvdata() for consistency and readability. If I were to use dev_get* then I would want the correpsonding set changed to dev_set_* also for consistency. If someone wants to change both the sets and gets to the dev_ versions, that's fine with me, but it should be separate patch. Kevin -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] omap_twl: Prevent SR to enable for am3517/am3505 devices
Abhilash K V abhilash...@ti.com writes: From: Vaibhav Hiremath hvaib...@ti.com In case of AM3517 AM3505, Smart Reflex is not applicable so we must not enable it. So add check for am3517/05 cpu revision in omap3_twl_init() and return -ENODEV if true, else continue. Signed-off-by: Vaibhav Hiremath hvaib...@ti.com Signed-off-by: Abhilash K V abhilash...@ti.com --- arch/arm/mach-omap2/omap_twl.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 07d6140..92fadcb 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -269,6 +269,14 @@ int __init omap3_twl_init(void) if (!cpu_is_omap34xx()) return -ENODEV; + /* + * In case of AM3517/AM3505 we should not be going down + * further, since SR is not applicable there. + */ + if (cpu_is_omap3505() || cpu_is_omap3517()) { + return -ENODEV; + } + Rather than using cpu_is_*, you should add a new feature flag for SmartReflex. We already have this for things like SGX, IVA, NEON, etc. See plat/feature.h Kevin if (cpu_is_omap3630()) { omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN; omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX; -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2 V2] OMAP3+: PM: SR: add suspend/resume handlers
Nishanth Menon n...@ti.com writes: SmartReflex should be disabled while entering low power mode due to the following reasons: a) SmartReflex values are not defined for retention voltage. b) With SmartReflex enabled, if the CPU enters low power state, FSM will try to bump the voltage to current OPP's voltage for which it has entered low power state, causing power loss and potential unknown states for the SoC. Since we are sure to attempt entering the lowest possible power state during suspend operation, SmartReflex needs to be disabled for the voltage domains in suspend path before achieving auto retention voltage on the device. Traditionally, this has been done with interrupts disabled as part of the common code which handles the idle sequence. Instead, by using the fact that we have to disable SmartReflex for sure during suspend operations, we can opportunistically disable SmartReflex in device standard pm ops, instead of disabling it as part of the code which executes with interrupts disabled and slave CPU{s} shutdown. This allows the system to do other parallel activities(such as suspending other devices in the system using slave CPU{s}) and save the time required to achieve suspend and resume from suspended state as a sequential activity. However, by being opportunistic as described above, we also increase the likelihood of SmartReflex library access functions being invoked in parallel contexts *after* SmartReflex driver's suspend handler (during suspend operation) or *before* resume handler (during resume operation) have been invoked (Example: DVFS for dependent devices, cpufreq for MPU etc.). We prevent this by using a flag to reject the callers in the duration where SmartReflex has been disabled. Signed-off-by: Nishanth Menon n...@ti.com --- V2: more verbose changelog :) and SIMPLE_DEV_PM_OPS V1: https://patchwork.kernel.org/patch/998312/ arch/arm/mach-omap2/smartreflex.c | 87 + 1 files changed, 87 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 33a027f..8699682 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -23,6 +23,7 @@ #include linux/debugfs.h #include linux/delay.h #include linux/slab.h +#include linux/pm.h #include linux/pm_runtime.h #include plat/common.h @@ -39,6 +40,7 @@ struct omap_sr { int ip_type; int nvalue_count; boolautocomp_active; + boolis_suspended; u32 clk_length; u32 err_weight; u32 err_minlimit; @@ -684,6 +686,11 @@ void omap_sr_enable(struct voltagedomain *voltdm) if (!sr-autocomp_active) return; + if (sr-is_suspended) { + dev_dbg(sr-pdev-dev, %s: in suspended state\n, __func__); + return; + } + if (!sr_class || !(sr_class-enable) || !(sr_class-configure)) { dev_warn(sr-pdev-dev, %s: smartreflex class driver not registered\n, __func__); @@ -717,6 +724,11 @@ void omap_sr_disable(struct voltagedomain *voltdm) if (!sr-autocomp_active) return; + if (sr-is_suspended) { + dev_dbg(sr-pdev-dev, %s: in suspended state\n, __func__); + return; + } + if (!sr_class || !(sr_class-disable)) { dev_warn(sr-pdev-dev, %s: smartreflex class driver not registered\n, __func__); @@ -750,6 +762,11 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm) if (!sr-autocomp_active) return; + if (sr-is_suspended) { + dev_dbg(sr-pdev-dev, %s: in suspended state\n, __func__); + return; + } + if (!sr_class || !(sr_class-disable)) { dev_warn(sr-pdev-dev, %s: smartreflex class driver not registered\n, __func__); @@ -808,6 +825,11 @@ static int omap_sr_autocomp_store(void *data, u64 val) return -EINVAL; } + if (sr_info-is_suspended) { + pr_warning(%s: in suspended state\n, __func__); + return -EBUSY; + } + if (!val) sr_stop_vddautocomp(sr_info); else @@ -998,10 +1020,75 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) return 0; } +static int omap_sr_suspend(struct device *dev) +{ + struct omap_sr_data *pdata; + struct omap_sr *sr_info; + + pdata = dev_get_platdata(dev); + if (!pdata) { + dev_err(dev, %s: platform data missing\n, __func__); + return -EINVAL; + } + + sr_info = _sr_lookup(pdata-voltdm); + if (IS_ERR(sr_info)) { +
Re: [linux-pm] [RFC/PATCH v2] PM / Runtime: allow _put_sync() from interrupts-disabled context
Rafael J. Wysocki r...@sisk.pl writes: On Friday, July 22, 2011, Kevin Hilman wrote: Currently the use of pm_runtime_put_sync() is not safe from interrupts-disabled context because rpm_idle() will release the spinlock and enable interrupts for the idle callbacks. This enables interrupts during a time where interrupts were expected to be disabled, and can have strange side effects on drivers that expected interrupts to be disabled. This is not a bug since the documentation clearly states that only _put_sync_suspend() is safe in IRQ-safe mode. However, pm_runtime_put_sync() could be made safe when in IRQ-safe mode by releasing the spinlock but not re-enabling interrupts, which is what this patch aims to do. Problem was found when using some buggy drivers that set pm_runtime_irq_safe() and used _put_sync() in interrupts-disabled context. The offending drivers have been fixed to use _put_sync_suspend(), But this patch is an RFC to see if it might make sense to allow using _put_sync() from interrupts-disabled context. OK, I'm going to take this for 3.2. Rafael, Since you're planning to merge this, maybe we should consider merging this as a fix for v3.1, and possibly even for v3.0 stable. That way, any current drivers using irq_safe and the normal _put_sync() will not have this problem. Kevin -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/6] OMAP4: ID: add omap_has_feature for max freq supported
On Fri, Jul 1, 2011 at 21:30, Rajendra Nayak rna...@ti.com wrote: [...] +static void __init omap4_check_features(void) +{ + u32 si_type; + + if (cpu_is_omap443x()) + omap_features |= OMAP4_HAS_MPU_1GHZ; + + + if (cpu_is_omap446x()) { + si_type = + read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1); + switch ((si_type (3 16)) 16) { + case 2: + /* High performance device */ + omap_features |= OMAP4_HAS_MPU_1_5GHZ; + break; I have seen http://www.mail-archive.com/linux-omap@vger.kernel.org/msg51988.html and I disagree with this. We are setting up a standard for all future silicon that omap_features if it contains a higher frequency will always support all lower frequencies in omap_feature. This may be convinent for the moment, BUT, I disagree with the approach as we cannot guarantee that this will be the approach for all silica in the future and approach taken here could be considered short-sighted. if 1.2GHz will be supported then a check for omap_has_1_2GHz should be true as well - which this patch will fail to support. E.g. on 4460 has_1GHz should'nt return true as it is 920MHz, but the check for 1_2GHz should be true - which it wont as return omap_features OMAP3_HAS_ ##flag; will not have BIT(9) set. Regards, Nishanth Menon + case 1: + default: + /* Standard device */ + omap_features |= OMAP4_HAS_MPU_1_2GHZ; + break; + } + } +} [...] -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: musb: use put_sync_suspend instead of put_sync
Moiz Sonasath m-sonas...@ti.com writes: From: Axel Haslam axelhas...@ti.com As Documented in runtime documentation, drivers can call put_sync in contexts where sleep is allowed, in contexts where sleep is not possible, the drivers need to mark these as to be made interrupt safe and also use put_sync_suspend instead of put_sync as the idle callbacks will be called with interrupt enabled - which is not a good thing to happen in isr context. There are several things happening in this patch, and I think this needs to be broken into separate fixes/features. Re: the put_sync_suspend change, for mainline, I posted a fix that allows a normal _put_sync() to work from IRQ-safe context: https://lists.linux-foundation.org/pipermail/linux-pm/2011-July/032261.html That will be merging for v3.2, likely for v3.1-rc and possible for v3.0.stable, so while changing the driver is harmless, it's no longer necessary. [...] A call to pm_runtime_irq_safe, will indefently prevent the parent from sleeping by doing a call to get-sync on the parent. this is to prevent a irq-safe child to wait for a non-irq safe parent. For this reason, the parent runtime-pm suspend is blocked, and we dont let L3 and CORE enter into low power. First, you should describe why you need to use pm_runtime_irq_safe() in the first place, since the rest of the workarounds in this patch are a result of using that. For those of us not intimately familar with this driver, a description of why IRQ-safe callbacks are needed would be most helpful. It might be that a simpler solution would be switching to using asynchronous runtime PM calls so that IRQ-safe mode is not required. As a workaround, we call the parent runtime functions on the child runtime hooks, for this to work, the parent has to be set to ignere children, otherwise, even with a timmed autosuspend call, will return BUSY, as the child is not yet suspended. Hmm, why is the child not yet suspended when the parent's autosuspend delay expires? Also, It's not clear to me how the parent is eventually suspending at all. After pm_runtime_irq_safe() is called on the child, the parent should *never* runtime suspend. Not only does pm_runtime_irq_safe() do a get_sync() on the parent, but rpm_suspend() has an explict check for !dev-power.irq_safe before suspending the parent. Something else must be going on (actually, going wrong) in order for the parent device to runtime suspend. Is the problem with L3/CORE not runtime suspending? or is it a problem with system suspend? If system suspend, are you using current mainline? There is now support at the omap_device level[1] to ensure all devices are idled at the omap_device level during system suspend. This patch is based off: https://lkml.org/lkml/2011/7/20/357 Signed-off-by: Axel Haslam axelhas...@ti.com Reported-by: Colin Cross ccr...@google.com Signed-off-by: Moiz Sonasath m-sonas...@ti.com --- drivers/usb/musb/musb_core.c |9 + drivers/usb/musb/musb_gadget.c |2 +- drivers/usb/musb/omap2430.c|4 +++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index c71b037..d22bc73 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1941,7 +1941,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) pm_runtime_use_autosuspend(musb-controller); pm_runtime_set_autosuspend_delay(musb-controller, 200); + pm_runtime_use_autosuspend(musb-controller-parent); + pm_runtime_set_autosuspend_delay(musb-controller-parent, 500); + pm_suspend_ignore_children(musb-controller-parent,true); Running checkpatch would have yelled at you on this line: ERROR: space required after that ',' (ctx:VxV) pm_runtime_enable(musb-controller); + pm_runtime_irq_safe(musb-controller); spin_lock_init(musb-lock); musb-board_mode = plat-mode; @@ -2375,6 +2379,9 @@ static int musb_runtime_suspend(struct device *dev) musb_save_context(musb); + pm_runtime_mark_last_busy(musb-controller-parent); + pm_runtime_put_autosuspend(musb-controller-parent); + return 0; } @@ -2392,6 +2399,8 @@ static int musb_runtime_resume(struct device *dev) * Also context restore without save does not make * any sense */ + if (pm_runtime_suspended(dev-parent)) Why this check? + pm_runtime_get_sync(dev-parent); if (!first) musb_restore_context(musb); first = 0; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 548338c..d5d8f3a 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1710,7 +1710,7 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) } spin_unlock_irqrestore(musb-lock, flags); - pm_runtime_put(musb-controller); +
Re: [PATCH] OMAP: DSS2: DSI: Support non-dcs long read
2011/8/4 Tomi Valkeinen tomi.valkei...@ti.com: Hi, On Wed, 2011-06-29 at 20:44 -0700, Arve Hjønnevåg wrote: Change-Id: I18168c887e1384c07dc033a1ffc57abdacb26073 Signed-off-by: Arve Hjønnevåg a...@android.com --- drivers/video/omap2/dss/dsi.c | 7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) This feels somehow partial... Why do you want to read generic packets if there are no functions to send generic packets? The chip responds with a generic packet when reading from some registers. This is a simple fix while adding support for sending generic packets would probably require an api change. And always write a patch description. Tomi diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index c16b933..6975645 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -206,6 +206,7 @@ struct dsi_reg { u16 idx; }; #define DSI_DT_DCS_LONG_WRITE 0x39 #define DSI_DT_RX_ACK_WITH_ERR 0x02 +#define DSI_DT_RX_LONG_READ 0x1a #define DSI_DT_RX_DCS_LONG_READ 0x1c #define DSI_DT_RX_SHORT_READ_1 0x21 #define DSI_DT_RX_SHORT_READ_2 0x22 @@ -2943,6 +2944,10 @@ static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev, } else if (dt == DSI_DT_RX_SHORT_READ_2) { DSSERR(\tDCS short response, 2 byte: %#x\n, FLD_GET(val, 23, 8)); + } else if (dt == DSI_DT_RX_LONG_READ) { + DSSERR(\tlong response, len %d\n, + FLD_GET(val, 23, 8)); + dsi_vc_flush_long_data(dsidev, channel); } else if (dt == DSI_DT_RX_DCS_LONG_READ) { DSSERR(\tDCS long response, len %d\n, FLD_GET(val, 23, 8)); @@ -3287,7 +3292,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, buf[1] = (data 8) 0xff; return 2; - } else if (dt == DSI_DT_RX_DCS_LONG_READ) { + } else if (dt == DSI_DT_RX_DCS_LONG_READ || dt == DSI_DT_RX_LONG_READ) { int w; int len = FLD_GET(val, 23, 8); if (dsi-debug_read) -- Arve Hjønnevåg -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html