From caebd9db7677166994570db69210cdaa3e30e1fb Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 6 Apr 2014 16:58:13 +0200 Subject: gpio: omap: convert to use irq_domain_add_simple() The GPIO OMAP driver supports different OMAP SoC families and not all of them have the needed support to use the linear IRQ domain mapping like OMAP1 that use the legacy domain mapping. But this special check is not necessary since the simple IRQ domain mapping is able to handle both cases. Having a zero IRQ offset will be interpreted as a linear domain case while a non-zero value will be interpreted as a legacy domain case. Signed-off-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Tested-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/gpio/gpio-omap.c') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 19b886c21b1d..3ee9b8d26f71 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1138,9 +1138,7 @@ static int omap_gpio_probe(struct platform_device *pdev) const struct omap_gpio_platform_data *pdata; struct resource *res; struct gpio_bank *bank; -#ifdef CONFIG_ARCH_OMAP1 - int irq_base; -#endif + int irq_base = 0; match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1185,21 +1183,16 @@ static int omap_gpio_probe(struct platform_device *pdev) #ifdef CONFIG_ARCH_OMAP1 /* * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop - * irq_alloc_descs() and irq_domain_add_legacy() and just use a - * linear IRQ domain mapping for all OMAP platforms. + * irq_alloc_descs() since a base IRQ offset will no longer be needed. */ irq_base = irq_alloc_descs(-1, 0, bank->width, 0); if (irq_base < 0) { dev_err(dev, "Couldn't allocate IRQ numbers\n"); return -ENODEV; } - - bank->domain = irq_domain_add_legacy(node, bank->width, irq_base, - 0, &irq_domain_simple_ops, NULL); -#else - bank->domain = irq_domain_add_linear(node, bank->width, - &irq_domain_simple_ops, NULL); #endif + bank->domain = irq_domain_add_simple(node, bank->width, irq_base, + &irq_domain_simple_ops, NULL); if (!bank->domain) { dev_err(dev, "Couldn't register an IRQ domain\n"); return -ENODEV; -- cgit v1.2.3 From 6ef7f385610a235c7041206da0f92f760b5d0e8d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 6 Apr 2014 16:58:14 +0200 Subject: gpio: omap: check gpiochip_add() return value The gpiochip_add() function can fail if the chip cannot be registered so the return value has to be checked and the error propagated in case it happens. Signed-off-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Tested-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/gpio/gpio-omap.c') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 3ee9b8d26f71..e71788835319 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1081,10 +1081,11 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, IRQ_NOREQUEST | IRQ_NOPROBE, 0); } -static void omap_gpio_chip_init(struct gpio_bank *bank) +static int omap_gpio_chip_init(struct gpio_bank *bank) { int j; static int gpio; + int ret; /* * REVISIT eventually switch from OMAP-specific gpio structs @@ -1110,7 +1111,11 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) } bank->chip.ngpio = bank->width; - gpiochip_add(&bank->chip); + ret = gpiochip_add(&bank->chip); + if (ret) { + dev_err(bank->dev, "Could not register gpio chip\n", ret); + return ret; + } for (j = 0; j < bank->width; j++) { int irq = irq_create_mapping(bank->domain, j); @@ -1139,6 +1144,7 @@ static int omap_gpio_probe(struct platform_device *pdev) struct resource *res; struct gpio_bank *bank; int irq_base = 0; + int ret; match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1223,7 +1229,11 @@ static int omap_gpio_probe(struct platform_device *pdev) mpuio_init(bank); omap_gpio_mod_init(bank); - omap_gpio_chip_init(bank); + + ret = omap_gpio_chip_init(bank); + if (ret) + return ret; + omap_gpio_show_rev(bank); pm_runtime_put(bank->dev); -- cgit v1.2.3 From fb655f57cee30f9121cce3653117d2c40affe194 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 6 Apr 2014 16:58:16 +0200 Subject: gpio: omap: convert driver to use gpiolib irqchip Converts the GPIO OMAP driver to register its chained irq handler and irqchip using the helpers in the gpiolib core. Signed-off-by: Javier Martinez Canillas Tested-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-omap.c | 107 ++++++++++++++++++++++------------------------- 2 files changed, 52 insertions(+), 56 deletions(-) (limited to 'drivers/gpio/gpio-omap.c') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 43a65ed010de..c58b828e882f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -247,6 +247,7 @@ config GPIO_OMAP bool "TI OMAP GPIO support" default y if ARCH_OMAP depends on ARM && ARCH_OMAP + select GPIOLIB_IRQCHIP help Say yes here to enable GPIO support for TI OMAP SoCs. diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index e71788835319..8cc9e91e7e4e 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -52,7 +51,6 @@ struct gpio_bank { struct list_head node; void __iomem *base; u16 irq; - struct irq_domain *domain; u32 non_wakeup_gpios; u32 enabled_non_wakeup_gpios; struct gpio_regs context; @@ -95,11 +93,10 @@ static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) return bank->chip.base + gpio_irq; } -static int omap_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +static inline struct gpio_bank *_irq_data_get_bank(struct irq_data *d) { - struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); - - return irq_find_mapping(bank->domain, offset); + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + return container_of(chip, struct gpio_bank, chip); } static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) @@ -479,7 +476,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask) static int gpio_irq_type(struct irq_data *d, unsigned type) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned gpio = 0; int retval; unsigned long flags; @@ -514,14 +511,6 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) return -EINVAL; } - retval = gpio_lock_as_irq(&bank->chip, offset); - if (retval) { - dev_err(bank->dev, "unable to lock offset %d for IRQ\n", - offset); - spin_unlock_irqrestore(&bank->lock, flags); - return retval; - } - bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); spin_unlock_irqrestore(&bank->lock, flags); @@ -664,7 +653,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ static int gpio_wake_enable(struct irq_data *d, unsigned int enable) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); return _set_gpio_wakeup(bank, gpio, enable); @@ -732,11 +721,12 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) unsigned int bit; struct gpio_bank *bank; int unmasked = 0; - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *irqchip = irq_desc_get_chip(desc); + struct gpio_chip *chip = irq_get_handler_data(irq); - chained_irq_enter(chip, desc); + chained_irq_enter(irqchip, desc); - bank = irq_get_handler_data(irq); + bank = container_of(chip, struct gpio_bank, chip); isr_reg = bank->base + bank->regs->irqstatus; pm_runtime_get_sync(bank->dev); @@ -764,7 +754,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) configured, we could unmask GPIO bank interrupt immediately */ if (!level_mask && !unmasked) { unmasked = 1; - chained_irq_exit(chip, desc); + chained_irq_exit(irqchip, desc); } if (!isr) @@ -784,7 +774,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) if (bank->toggle_mask & (1 << bit)) _toggle_gpio_edge_triggering(bank, bit); - generic_handle_irq(irq_find_mapping(bank->domain, bit)); + generic_handle_irq(irq_find_mapping(bank->chip.irqdomain, + bit)); } } /* if bank has any level sensitive GPIO pin interrupt @@ -793,13 +784,13 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) interrupt */ exit: if (!unmasked) - chained_irq_exit(chip, desc); + chained_irq_exit(irqchip, desc); pm_runtime_put(bank->dev); } static void gpio_irq_shutdown(struct irq_data *d) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned long flags; unsigned offset = GPIO_INDEX(bank, gpio); @@ -821,7 +812,7 @@ static void gpio_irq_shutdown(struct irq_data *d) static void gpio_ack_irq(struct irq_data *d) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); _clear_gpio_irqstatus(bank, gpio); @@ -829,7 +820,7 @@ static void gpio_ack_irq(struct irq_data *d) static void gpio_mask_irq(struct irq_data *d) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned long flags; @@ -841,7 +832,7 @@ static void gpio_mask_irq(struct irq_data *d) static void gpio_unmask_irq(struct irq_data *d) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned int irq_mask = GPIO_BIT(bank, gpio); u32 trigger = irqd_get_trigger_type(d); @@ -1085,6 +1076,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) { int j; static int gpio; + int irq_base = 0; int ret; /* @@ -1098,7 +1090,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) bank->chip.direction_output = gpio_output; bank->chip.set_debounce = gpio_debounce; bank->chip.set = gpio_set; - bank->chip.to_irq = omap_gpio_to_irq; if (bank->is_mpuio) { bank->chip.label = "mpuio"; if (bank->regs->wkup_en) @@ -1113,24 +1104,46 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) ret = gpiochip_add(&bank->chip); if (ret) { - dev_err(bank->dev, "Could not register gpio chip\n", ret); + dev_err(bank->dev, "Could not register gpio chip %d\n", ret); return ret; } +#ifdef CONFIG_ARCH_OMAP1 + /* + * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop + * irq_alloc_descs() since a base IRQ offset will no longer be needed. + */ + irq_base = irq_alloc_descs(-1, 0, bank->width, 0); + if (irq_base < 0) { + dev_err(bank->dev, "Couldn't allocate IRQ numbers\n"); + return -ENODEV; + } +#endif + + ret = gpiochip_irqchip_add(&bank->chip, &gpio_irq_chip, + irq_base, gpio_irq_handler, + IRQ_TYPE_NONE); + + if (ret) { + dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret); + ret = gpiochip_remove(&bank->chip); + return -ENODEV; + } + + gpiochip_set_chained_irqchip(&bank->chip, &gpio_irq_chip, + bank->irq, gpio_irq_handler); + for (j = 0; j < bank->width; j++) { - int irq = irq_create_mapping(bank->domain, j); + int irq = irq_find_mapping(bank->chip.irqdomain, j); irq_set_lockdep_class(irq, &gpio_lock_class); - irq_set_chip_data(irq, bank); if (bank->is_mpuio) { omap_mpuio_alloc_gc(bank, irq, bank->width); - } else { - irq_set_chip_and_handler(irq, &gpio_irq_chip, - handle_simple_irq); - set_irq_flags(irq, IRQF_VALID); + irq_set_chip_and_handler(irq, NULL, NULL); + set_irq_flags(irq, 0); } } - irq_set_chained_handler(bank->irq, gpio_irq_handler); - irq_set_handler_data(bank->irq, bank); + + return 0; } static const struct of_device_id omap_gpio_match[]; @@ -1143,7 +1156,6 @@ static int omap_gpio_probe(struct platform_device *pdev) const struct omap_gpio_platform_data *pdata; struct resource *res; struct gpio_bank *bank; - int irq_base = 0; int ret; match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1166,6 +1178,7 @@ static int omap_gpio_probe(struct platform_device *pdev) bank->irq = res->start; bank->dev = dev; + bank->chip.dev = dev; bank->dbck_flag = pdata->dbck_flag; bank->stride = pdata->bank_stride; bank->width = pdata->bank_width; @@ -1186,24 +1199,6 @@ static int omap_gpio_probe(struct platform_device *pdev) pdata->get_context_loss_count; } -#ifdef CONFIG_ARCH_OMAP1 - /* - * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop - * irq_alloc_descs() since a base IRQ offset will no longer be needed. - */ - irq_base = irq_alloc_descs(-1, 0, bank->width, 0); - if (irq_base < 0) { - dev_err(dev, "Couldn't allocate IRQ numbers\n"); - return -ENODEV; - } -#endif - bank->domain = irq_domain_add_simple(node, bank->width, irq_base, - &irq_domain_simple_ops, NULL); - if (!bank->domain) { - dev_err(dev, "Couldn't register an IRQ domain\n"); - return -ENODEV; - } - if (bank->regs->set_dataout && bank->regs->clr_dataout) bank->set_dataout = _set_gpio_dataout_reg; else @@ -1215,7 +1210,7 @@ static int omap_gpio_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bank->base = devm_ioremap_resource(dev, res); if (IS_ERR(bank->base)) { - irq_domain_remove(bank->domain); + irq_domain_remove(bank->chip.irqdomain); return PTR_ERR(bank->base); } -- cgit v1.2.3 From 9370084e685666fe33e9d62707433fa112446b03 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Thu, 24 Apr 2014 08:57:39 +0200 Subject: gpio: omap: implement get_direction This patch implements gpio_chip's get_direction() routine, that lets other drivers get particular GPIOs direction using struct gpio_desc. Signed-off-by: Yegor Yefremov Acked-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Tested-by: Tony Lindgren Reviewed-by: Kevin Hilman Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/gpio/gpio-omap.c') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 8cc9e91e7e4e..47c6056fe850 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #define OFF_MODE 1 @@ -927,6 +928,21 @@ static inline void mpuio_init(struct gpio_bank *bank) /*---------------------------------------------------------------------*/ +static int gpio_get_direction(struct gpio_chip *chip, unsigned offset) +{ + struct gpio_bank *bank; + unsigned long flags; + void __iomem *reg; + int dir; + + bank = container_of(chip, struct gpio_bank, chip); + reg = bank->base + bank->regs->direction; + spin_lock_irqsave(&bank->lock, flags); + dir = !!(readl_relaxed(reg) & BIT(offset)); + spin_unlock_irqrestore(&bank->lock, flags); + return dir; +} + static int gpio_input(struct gpio_chip *chip, unsigned offset) { struct gpio_bank *bank; @@ -1085,6 +1101,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) */ bank->chip.request = omap_gpio_request; bank->chip.free = omap_gpio_free; + bank->chip.get_direction = gpio_get_direction; bank->chip.direction_input = gpio_input; bank->chip.get = gpio_get; bank->chip.direction_output = gpio_output; -- cgit v1.2.3 From b1e9fec2b8690b153b0b9ebbe9dfe6a246d55e4a Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 27 Apr 2014 02:00:49 +0200 Subject: gpio: omap: use BIT() macro instead of shifting bits Using the BIT() macro instead of shifting bits makes the code less error prone and also more readable. Signed-off-by: Javier Martinez Canillas Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 50 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/gpio/gpio-omap.c') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 47c6056fe850..01d50a090d87 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -83,11 +83,11 @@ struct gpio_bank { }; #define GPIO_INDEX(bank, gpio) (gpio % bank->width) -#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) +#define GPIO_BIT(bank, gpio) (BIT(GPIO_INDEX(bank, gpio))) #define GPIO_MOD_CTRL_BIT BIT(0) #define BANK_USED(bank) (bank->mod_usage || bank->irq_usage) -#define LINE_USED(line, offset) (line & (1 << offset)) +#define LINE_USED(line, offset) (line & (BIT(offset))) static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) { @@ -108,9 +108,9 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) reg += bank->regs->direction; l = readl_relaxed(reg); if (is_input) - l |= 1 << gpio; + l |= BIT(gpio); else - l &= ~(1 << gpio); + l &= ~(BIT(gpio)); writel_relaxed(l, reg); bank->context.oe = l; } @@ -153,14 +153,14 @@ static int _get_gpio_datain(struct gpio_bank *bank, int offset) { void __iomem *reg = bank->base + bank->regs->datain; - return (readl_relaxed(reg) & (1 << offset)) != 0; + return (readl_relaxed(reg) & (BIT(offset))) != 0; } static int _get_gpio_dataout(struct gpio_bank *bank, int offset) { void __iomem *reg = bank->base + bank->regs->dataout; - return (readl_relaxed(reg) & (1 << offset)) != 0; + return (readl_relaxed(reg) & (BIT(offset))) != 0; } static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) @@ -297,7 +297,7 @@ static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, unsigned trigger) { void __iomem *base = bank->base; - u32 gpio_bit = 1 << gpio; + u32 gpio_bit = BIT(gpio); _gpio_rmw(base, bank->regs->leveldetect0, gpio_bit, trigger & IRQ_TYPE_LEVEL_LOW); @@ -366,9 +366,9 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) l = readl_relaxed(reg); if ((l >> gpio) & 1) - l &= ~(1 << gpio); + l &= ~(BIT(gpio)); else - l |= 1 << gpio; + l |= BIT(gpio); writel_relaxed(l, reg); } @@ -390,11 +390,11 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, l = readl_relaxed(reg); if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) - bank->toggle_mask |= 1 << gpio; + bank->toggle_mask |= BIT(gpio); if (trigger & IRQ_TYPE_EDGE_RISING) - l |= 1 << gpio; + l |= BIT(gpio); else if (trigger & IRQ_TYPE_EDGE_FALLING) - l &= ~(1 << gpio); + l &= ~(BIT(gpio)); else return -EINVAL; @@ -411,10 +411,10 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, if (trigger & IRQ_TYPE_EDGE_RISING) l |= 2 << (gpio << 1); if (trigger & IRQ_TYPE_EDGE_FALLING) - l |= 1 << (gpio << 1); + l |= BIT(gpio << 1); /* Enable wake-up during idle for dynamic tick */ - _gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger); + _gpio_rmw(base, bank->regs->wkup_en, BIT(gpio), trigger); bank->context.wake_en = readl_relaxed(bank->base + bank->regs->wkup_en); writel_relaxed(l, reg); @@ -428,7 +428,7 @@ static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset) void __iomem *reg = bank->base + bank->regs->pinctrl; /* Claim the pin for MPU */ - writel_relaxed(readl_relaxed(reg) | (1 << offset), reg); + writel_relaxed(readl_relaxed(reg) | (BIT(offset)), reg); } if (bank->regs->ctrl && !BANK_USED(bank)) { @@ -451,7 +451,7 @@ static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset) !LINE_USED(bank->mod_usage, offset) && !LINE_USED(bank->irq_usage, offset)) { /* Disable wake-up during idle for dynamic tick */ - _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); + _gpio_rmw(base, bank->regs->wkup_en, BIT(offset), 0); bank->context.wake_en = readl_relaxed(bank->base + bank->regs->wkup_en); } @@ -507,12 +507,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) if (!LINE_USED(bank->mod_usage, offset)) { _enable_gpio_module(bank, offset); _set_gpio_direction(bank, offset, 1); - } else if (!gpio_is_input(bank, 1 << offset)) { + } else if (!gpio_is_input(bank, BIT(offset))) { spin_unlock_irqrestore(&bank->lock, flags); return -EINVAL; } - bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); + bank->irq_usage |= BIT(GPIO_INDEX(bank, gpio)); spin_unlock_irqrestore(&bank->lock, flags); if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) @@ -549,7 +549,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) { void __iomem *reg = bank->base; u32 l; - u32 mask = (1 << bank->width) - 1; + u32 mask = (BIT(bank->width)) - 1; reg += bank->regs->irqenable; l = readl_relaxed(reg); @@ -681,7 +681,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); _enable_gpio_module(bank, offset); } - bank->mod_usage |= 1 << offset; + bank->mod_usage |= BIT(offset); spin_unlock_irqrestore(&bank->lock, flags); return 0; @@ -693,7 +693,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) unsigned long flags; spin_lock_irqsave(&bank->lock, flags); - bank->mod_usage &= ~(1 << offset); + bank->mod_usage &= ~(BIT(offset)); _disable_gpio_module(bank, offset); _reset_gpio(bank, bank->chip.base + offset); spin_unlock_irqrestore(&bank->lock, flags); @@ -763,7 +763,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) while (isr) { bit = __ffs(isr); - isr &= ~(1 << bit); + isr &= ~(BIT(bit)); /* * Some chips can't respond to both rising and falling @@ -772,7 +772,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) * to respond to the IRQ for the opposite direction. * This will be indicated in the bank toggle_mask. */ - if (bank->toggle_mask & (1 << bit)) + if (bank->toggle_mask & (BIT(bit))) _toggle_gpio_edge_triggering(bank, bit); generic_handle_irq(irq_find_mapping(bank->chip.irqdomain, @@ -798,7 +798,7 @@ static void gpio_irq_shutdown(struct irq_data *d) spin_lock_irqsave(&bank->lock, flags); gpio_unlock_as_irq(&bank->chip, offset); - bank->irq_usage &= ~(1 << offset); + bank->irq_usage &= ~(BIT(offset)); _disable_gpio_module(bank, offset); _reset_gpio(bank, gpio); spin_unlock_irqrestore(&bank->lock, flags); @@ -961,7 +961,7 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset) u32 mask; bank = container_of(chip, struct gpio_bank, chip); - mask = (1 << offset); + mask = (BIT(offset)); if (gpio_is_input(bank, mask)) return _get_gpio_datain(bank, offset); -- cgit v1.2.3 From 345477ffe2ed0c53ffbbfeae73f9bca38e827d0d Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 23 Apr 2014 11:41:03 +0530 Subject: gpio: omap: prepare and unprepare the debounce clock Replace the clk_enable()s with a clk_prepare_enable() and the clk_disables()s with a clk_disable_unprepare() This never showed issues due to the OMAP platform code (hwmod) leaving these clocks in clk_prepare()ed state by default. Reported-by: Kishon Vijay Abraham I Signed-off-by: Rajendra Nayak Acked-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Cc: Kevin Hilman Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpio/gpio-omap.c') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 01d50a090d87..00f29aa1fb9d 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -178,7 +178,7 @@ static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) static inline void _gpio_dbck_enable(struct gpio_bank *bank) { if (bank->dbck_enable_mask && !bank->dbck_enabled) { - clk_enable(bank->dbck); + clk_prepare_enable(bank->dbck); bank->dbck_enabled = true; writel_relaxed(bank->dbck_enable_mask, @@ -196,7 +196,7 @@ static inline void _gpio_dbck_disable(struct gpio_bank *bank) */ writel_relaxed(0, bank->base + bank->regs->debounce_en); - clk_disable(bank->dbck); + clk_disable_unprepare(bank->dbck); bank->dbck_enabled = false; } } @@ -229,7 +229,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, l = GPIO_BIT(bank, gpio); - clk_enable(bank->dbck); + clk_prepare_enable(bank->dbck); reg = bank->base + bank->regs->debounce; writel_relaxed(debounce, reg); @@ -243,7 +243,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, bank->dbck_enable_mask = val; writel_relaxed(val, reg); - clk_disable(bank->dbck); + clk_disable_unprepare(bank->dbck); /* * Enable debounce clock per module. * This call is mandatory because in omap_gpio_request() when @@ -288,7 +288,7 @@ static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio) bank->context.debounce = 0; writel_relaxed(bank->context.debounce, bank->base + bank->regs->debounce); - clk_disable(bank->dbck); + clk_disable_unprepare(bank->dbck); bank->dbck_enabled = false; } } -- cgit v1.2.3