Re: [PATCH] gpio: tegra: use new gpio_lock_as_irq() API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Oct 16, 2013 at 9:25 PM, Stephen Warren <swarren@xxxxxxxxxxxxx> wrote:
> From: Stephen Warren <swarren@xxxxxxxxxx>
>
> Whenever an IRQ is claimed or freed, call gpio_lock_as_irq() or
> gpio_unlock_as_irq() on the associated GPIO, to prevent that GPIO from
> being configured in a manner incompatible with an interrupt.
>
> Signed-off-by: Stephen Warren <swarren@xxxxxxxxxx>
> ---
>  drivers/gpio/gpio-tegra.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
> index 9a62672..cfd3b90 100644
> --- a/drivers/gpio/gpio-tegra.c
> +++ b/drivers/gpio/gpio-tegra.c
> @@ -75,6 +75,7 @@ struct tegra_gpio_bank {
>  #endif
>  };
>
> +static struct device *dev;
>  static struct irq_domain *irq_domain;
>  static void __iomem *regs;
>  static u32 tegra_gpio_bank_count;
> @@ -205,6 +206,7 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
>         int lvl_type;
>         int val;
>         unsigned long flags;
> +       int ret;
>
>         switch (type & IRQ_TYPE_SENSE_MASK) {
>         case IRQ_TYPE_EDGE_RISING:
> @@ -231,6 +233,12 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
>                 return -EINVAL;
>         }
>
> +       ret = gpio_lock_as_irq(&tegra_gpio_chip, gpio);
> +       if (ret) {
> +               dev_err(dev, "unable to lock Tegra GPIO %d as IRQ\n", gpio);
> +               return ret;
> +       }
> +
>         spin_lock_irqsave(&bank->lvl_lock[port], flags);
>
>         val = tegra_gpio_readl(GPIO_INT_LVL(gpio));
> @@ -251,6 +259,13 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
>         return 0;
>  }
>
> +static void tegra_gpio_irq_shutdown(struct irq_data *d)
> +{
> +       int gpio = d->hwirq;
> +
> +       gpio_unlock_as_irq(&tegra_gpio_chip, gpio);
> +}
> +
>  static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
>  {
>         struct tegra_gpio_bank *bank;
> @@ -368,6 +383,7 @@ static struct irq_chip tegra_gpio_irq_chip = {
>         .irq_mask       = tegra_gpio_irq_mask,
>         .irq_unmask     = tegra_gpio_irq_unmask,
>         .irq_set_type   = tegra_gpio_irq_set_type,
> +       .irq_shutdown   = tegra_gpio_irq_shutdown,
>  #ifdef CONFIG_PM_SLEEP
>         .irq_set_wake   = tegra_gpio_irq_set_wake,
>  #endif
> @@ -413,6 +429,8 @@ static int tegra_gpio_probe(struct platform_device *pdev)
>         int i;
>         int j;
>
> +       dev = &pdev->dev;
> +
>         match = of_match_device(tegra_gpio_of_match, &pdev->dev);
>         if (!match) {
>                 dev_err(&pdev->dev, "Error: No device match found\n");
> --

Reviewed-by: Javier Martinez Canillas <javier@xxxxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux