diff options
Diffstat (limited to 'arch/arm/mach-omap2/gpio.c')
-rw-r--r-- | arch/arm/mach-omap2/gpio.c | 83 |
1 files changed, 65 insertions, 18 deletions
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 826861e88ea7..7dc8e0ce92c5 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -66,8 +66,6 @@ static inline struct gpio_bank *get_gpio_bank(int gpio) { if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) return &gpio_bank[gpio >> 5]; - BUG(); - return -EINVAL; } static inline int get_gpio_index(int gpio) @@ -172,7 +170,12 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) return -EINVAL; reg = bank->base; - reg += OMAP24XX_GPIO_DATAOUT; + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_DATAOUT; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_DATAOUT; + else + return -EINVAL; return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; } @@ -514,11 +517,21 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); if (!bank->mod_usage) { + void __iomem *reg = bank->base; u32 ctrl; - ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); + + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_CTRL; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_CTRL; + else { + spin_unlock_irqrestore(&bank->lock, flags); + return -EINVAL; + } + ctrl = __raw_readl(reg); ctrl &= 0xFFFFFFFE; /* Module is enabled, clocks are not gated */ - __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); + __raw_writel(ctrl, reg); } bank->mod_usage |= 1 << offset; @@ -534,18 +547,34 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(&bank->lock, flags); { - /* Disable wake-up during idle for dynamic tick */ - void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; - __raw_writel(1 << offset, reg); + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { + /* Disable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + + OMAP24XX_GPIO_CLEARWKUENA; + __raw_writel(1 << offset, reg); + } else if (cpu_is_omap44xx()) { + /* Disable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0; + __raw_writel(1 << offset, reg); + } else { + spin_lock_irqsave(&bank->lock, flags); + return -EINVAL; + } } bank->mod_usage &= ~(1 << offset); if (!bank->mod_usage) { + void __iomem *reg = bank->base; u32 ctrl; - ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_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, bank->base + OMAP24XX_GPIO_CTRL); + __raw_writel(ctrl, reg); } _reset_gpio(bank, bank->chip.base + offset); @@ -699,7 +728,12 @@ static int gpio_is_input(struct gpio_bank *bank, int mask) { void __iomem *reg = bank->base; - reg += OMAP24XX_GPIO_OE; + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_OE; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_OE; + else + return -EINVAL; return __raw_readl(reg) & mask; } @@ -882,7 +916,7 @@ void omap2_gpio_prepare_for_retention(void) bank->saved_risingdetect = l2; l1 &= ~bank->enabled_non_wakeup_gpios; l2 &= ~bank->enabled_non_wakeup_gpios; - if (cpu_is_omap24xx()) { + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT); __raw_writel(l2, bank->base + @@ -1065,12 +1099,14 @@ void omap_gpio_restore_context(void) static int __devexit omap_gpio_remove(struct platform_device *pdev) { - struct omap_gpio_platform_data *pdata = pdev->dev.platform_data; + struct omap_gpio_platform_data *pdata; struct gpio_bank *bank; int id; - if (!pdev || !pdata) - return 0; + if (!pdev || !pdev->dev.platform_data) + return -EINVAL; + + pdata = pdev->dev.platform_data; id = pdev->id; if (id > gpio_bank_count) @@ -1086,16 +1122,17 @@ static int __devexit omap_gpio_remove(struct platform_device *pdev) static int __devinit omap_gpio_probe(struct platform_device *pdev) { static int show_rev_once; - struct omap_gpio_platform_data *pdata = pdev->dev.platform_data; + struct omap_gpio_platform_data *pdata; struct gpio_bank *bank; int id, i; - if (!pdev || !pdata) { + if (!pdev || !pdev->dev.platform_data) { pr_err("GPIO device initialize without" "platform data\n"); return -EINVAL; } + pdata = pdev->dev.platform_data; gpio_bank_count = OMAP_NR_GPIOS; #ifdef CONFIG_ARCH_OMAP2 if (cpu_is_omap242x()) @@ -1103,7 +1140,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) #endif id = pdev->id; - if (id > gpio_bank_count) { + if (id >= gpio_bank_count) { pr_err("Invalid GPIO device id (%d)\n", id); return -EINVAL; } @@ -1232,6 +1269,11 @@ void __init omap_gpio_early_init(void) pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); + if (!pdata) { + WARN("Memory allocation failed gpio%d \n", i + 1); + return; + } + pdata->base = oh->_rt_va; pdata->irq = oh->mpu_irqs[0].irq; pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i; @@ -1272,11 +1314,16 @@ int __init omap_init_gpio(void) oh = omap_hwmod_lookup(oh_name); if (!oh) { pr_err("Could not look up %s\n", oh_name); + i++; continue; } pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); + if (!pdata) { + WARN("Memory allocation failed gpio%d \n", i + 1); + return; + } pdata->base = oh->_rt_va; pdata->irq = oh->mpu_irqs[0].irq; pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i; |