Skip to content

Commit fac7fa1

Browse files
Javier Martinez Canillaslinusw
authored andcommitted
gpio/omap: auto-setup a GPIO when used as an IRQ
The OMAP GPIO controller HW requires a pin to be configured in GPIO input mode in order to operate as an interrupt input. Since drivers should not be aware of whether an interrupt pin is also a GPIO or not, the HW should be fully configured/enabled as an IRQ if a driver solely uses IRQ APIs such as request_irq(), and never calls any GPIO-related APIs. As such, add the missing HW setup to the OMAP GPIO controller's irq_chip driver. Since this bypasses the GPIO subsystem we have to ensure that another driver won't be able to request the same GPIO pin that is used as an IRQ and set its direction as output. Requesting the GPIO and setting its direction as input is allowed though. This fixes smsc911x ethernet support for tobi and igep OMAP3 boards and OMAP4 SDP SPI based ethernet that use a GPIO as an interrupt line. Cc: [email protected] Acked-by: Stephen Warren <[email protected]> Tested-by: George Cherian <[email protected]> Tested-by: Aaro Koskinen <[email protected]> Tested-by: Lars Poeschel <[email protected]> Reviewed-by: Kevin Hilman <[email protected]> Tested-by: Kevin Hilman <[email protected]> Acked-by: Santosh Shilimkar <[email protected]> Acked-by: Tony Lindgren <[email protected]> Signed-off-by: Javier Martinez Canillas <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent fa365e4 commit fac7fa1

File tree

1 file changed

+83
-46
lines changed

1 file changed

+83
-46
lines changed

drivers/gpio/gpio-omap.c

Lines changed: 83 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,52 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
424424
return 0;
425425
}
426426

427+
static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset)
428+
{
429+
if (bank->regs->pinctrl) {
430+
void __iomem *reg = bank->base + bank->regs->pinctrl;
431+
432+
/* Claim the pin for MPU */
433+
__raw_writel(__raw_readl(reg) | (1 << offset), reg);
434+
}
435+
436+
if (bank->regs->ctrl && !BANK_USED(bank)) {
437+
void __iomem *reg = bank->base + bank->regs->ctrl;
438+
u32 ctrl;
439+
440+
ctrl = __raw_readl(reg);
441+
/* Module is enabled, clocks are not gated */
442+
ctrl &= ~GPIO_MOD_CTRL_BIT;
443+
__raw_writel(ctrl, reg);
444+
bank->context.ctrl = ctrl;
445+
}
446+
}
447+
448+
static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset)
449+
{
450+
void __iomem *base = bank->base;
451+
452+
if (bank->regs->wkup_en &&
453+
!LINE_USED(bank->mod_usage, offset) &&
454+
!LINE_USED(bank->irq_usage, offset)) {
455+
/* Disable wake-up during idle for dynamic tick */
456+
_gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
457+
bank->context.wake_en =
458+
__raw_readl(bank->base + bank->regs->wkup_en);
459+
}
460+
461+
if (bank->regs->ctrl && !BANK_USED(bank)) {
462+
void __iomem *reg = bank->base + bank->regs->ctrl;
463+
u32 ctrl;
464+
465+
ctrl = __raw_readl(reg);
466+
/* Module is disabled, clocks are gated */
467+
ctrl |= GPIO_MOD_CTRL_BIT;
468+
__raw_writel(ctrl, reg);
469+
bank->context.ctrl = ctrl;
470+
}
471+
}
472+
427473
static int gpio_is_input(struct gpio_bank *bank, int mask)
428474
{
429475
void __iomem *reg = bank->base + bank->regs->direction;
@@ -437,9 +483,10 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
437483
unsigned gpio = 0;
438484
int retval;
439485
unsigned long flags;
486+
unsigned offset;
440487

441-
if (WARN_ON(!BANK_USED(bank)))
442-
return -EINVAL;
488+
if (!BANK_USED(bank))
489+
pm_runtime_get_sync(bank->dev);
443490

444491
#ifdef CONFIG_ARCH_OMAP1
445492
if (d->irq > IH_MPUIO_BASE)
@@ -457,7 +504,16 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
457504
return -EINVAL;
458505

459506
spin_lock_irqsave(&bank->lock, flags);
460-
retval = _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), type);
507+
offset = GPIO_INDEX(bank, gpio);
508+
retval = _set_gpio_triggering(bank, offset, type);
509+
if (!LINE_USED(bank->mod_usage, offset)) {
510+
_enable_gpio_module(bank, offset);
511+
_set_gpio_direction(bank, offset, 1);
512+
} else if (!gpio_is_input(bank, 1 << offset)) {
513+
spin_unlock_irqrestore(&bank->lock, flags);
514+
return -EINVAL;
515+
}
516+
461517
bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio);
462518
spin_unlock_irqrestore(&bank->lock, flags);
463519

@@ -620,30 +676,14 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
620676

621677
spin_lock_irqsave(&bank->lock, flags);
622678
/* Set trigger to none. You need to enable the desired trigger with
623-
* request_irq() or set_irq_type().
679+
* request_irq() or set_irq_type(). Only do this if the IRQ line has
680+
* not already been requested.
624681
*/
625-
_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
626-
627-
if (bank->regs->pinctrl) {
628-
void __iomem *reg = bank->base + bank->regs->pinctrl;
629-
630-
/* Claim the pin for MPU */
631-
__raw_writel(__raw_readl(reg) | (1 << offset), reg);
682+
if (!LINE_USED(bank->irq_usage, offset)) {
683+
_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
684+
_enable_gpio_module(bank, offset);
632685
}
633-
634-
if (bank->regs->ctrl && !BANK_USED(bank)) {
635-
void __iomem *reg = bank->base + bank->regs->ctrl;
636-
u32 ctrl;
637-
638-
ctrl = __raw_readl(reg);
639-
/* Module is enabled, clocks are not gated */
640-
ctrl &= ~GPIO_MOD_CTRL_BIT;
641-
__raw_writel(ctrl, reg);
642-
bank->context.ctrl = ctrl;
643-
}
644-
645686
bank->mod_usage |= 1 << offset;
646-
647687
spin_unlock_irqrestore(&bank->lock, flags);
648688

649689
return 0;
@@ -652,31 +692,11 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
652692
static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
653693
{
654694
struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
655-
void __iomem *base = bank->base;
656695
unsigned long flags;
657696

658697
spin_lock_irqsave(&bank->lock, flags);
659-
660-
if (bank->regs->wkup_en) {
661-
/* Disable wake-up during idle for dynamic tick */
662-
_gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
663-
bank->context.wake_en =
664-
__raw_readl(bank->base + bank->regs->wkup_en);
665-
}
666-
667698
bank->mod_usage &= ~(1 << offset);
668-
669-
if (bank->regs->ctrl && !BANK_USED(bank)) {
670-
void __iomem *reg = bank->base + bank->regs->ctrl;
671-
u32 ctrl;
672-
673-
ctrl = __raw_readl(reg);
674-
/* Module is disabled, clocks are gated */
675-
ctrl |= GPIO_MOD_CTRL_BIT;
676-
__raw_writel(ctrl, reg);
677-
bank->context.ctrl = ctrl;
678-
}
679-
699+
_disable_gpio_module(bank, offset);
680700
_reset_gpio(bank, bank->chip.base + offset);
681701
spin_unlock_irqrestore(&bank->lock, flags);
682702

@@ -778,8 +798,16 @@ static void gpio_irq_shutdown(struct irq_data *d)
778798

779799
spin_lock_irqsave(&bank->lock, flags);
780800
bank->irq_usage &= ~(1 << offset);
801+
_disable_gpio_module(bank, offset);
781802
_reset_gpio(bank, gpio);
782803
spin_unlock_irqrestore(&bank->lock, flags);
804+
805+
/*
806+
* If this is the last IRQ to be freed in the bank,
807+
* disable the bank module.
808+
*/
809+
if (!BANK_USED(bank))
810+
pm_runtime_put(bank->dev);
783811
}
784812

785813
static void gpio_ack_irq(struct irq_data *d)
@@ -929,13 +957,22 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
929957
{
930958
struct gpio_bank *bank;
931959
unsigned long flags;
960+
int retval = 0;
932961

933962
bank = container_of(chip, struct gpio_bank, chip);
934963
spin_lock_irqsave(&bank->lock, flags);
964+
965+
if (LINE_USED(bank->irq_usage, offset)) {
966+
retval = -EINVAL;
967+
goto exit;
968+
}
969+
935970
bank->set_dataout(bank, offset, value);
936971
_set_gpio_direction(bank, offset, 0);
972+
973+
exit:
937974
spin_unlock_irqrestore(&bank->lock, flags);
938-
return 0;
975+
return retval;
939976
}
940977

941978
static int gpio_debounce(struct gpio_chip *chip, unsigned offset,

0 commit comments

Comments
 (0)