gpio: Initialize the irqchip valid_mask with a callback

After changing the valid_mask for the struct gpio_chip
to detect the need and presence of a valid mask with the
presence of a .init_valid_mask() callback to fill it in,
we augment the gpio_irq_chip to use the same logic.

Switch all driver using the gpio_irq_chio valid_mask
over to this new method.

This makes sure the valid_mask for the gpio_irq_chip gets
filled in when we add the gpio_chip, which makes it a
little easier to switch over drivers using the old
way of setting up gpio_irq_chip over to the new method
of passing the gpio_irq_chip along with the gpio_chip.
(See drivers/gpio/TODO for details.)

Cc: Joel Stanley <joel@jms.id.au>
Cc: Thierry Reding <treding@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
Link: https://lore.kernel.org/r/20190904140104.32426-1-linus.walleij@linaro.org
This commit is contained in:
Linus Walleij
2019-09-04 16:01:04 +02:00
parent 4f78d91c72
commit 5fbe5b5883
8 changed files with 111 additions and 54 deletions

View File

@@ -1455,6 +1455,20 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
chip->irq_eoi(data);
}
static void byt_init_irq_valid_mask(struct gpio_chip *chip,
unsigned long *valid_mask,
unsigned int ngpios)
{
/*
* FIXME: currently the valid_mask is filled in as part of
* initializing the irq_chip below in byt_gpio_irq_init_hw().
* when converting this driver to the new way of passing the
* gpio_irq_chip along when adding the gpio_chip, move the
* mask initialization into this callback instead. Right now
* this callback is here to make sure the mask gets allocated.
*/
}
static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
{
struct gpio_chip *gc = &vg->chip;
@@ -1525,7 +1539,7 @@ static int byt_gpio_probe(struct byt_gpio *vg)
gc->can_sleep = false;
gc->parent = &vg->pdev->dev;
gc->ngpio = vg->soc_data->npins;
gc->irq.need_valid_mask = true;
gc->irq.init_valid_mask = byt_init_irq_valid_mask;
#ifdef CONFIG_PM_SLEEP
vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio,

View File

@@ -1543,6 +1543,30 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
{}
};
static void chv_init_irq_valid_mask(struct gpio_chip *chip,
unsigned long *valid_mask,
unsigned int ngpios)
{
struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
const struct chv_community *community = pctrl->community;
int i;
/* Do not add GPIOs that can only generate GPEs to the IRQ domain */
for (i = 0; i < community->npins; i++) {
const struct pinctrl_pin_desc *desc;
u32 intsel;
desc = &community->pins[i];
intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
intsel &= CHV_PADCTRL0_INTSEL_MASK;
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
if (intsel >= community->nirqs)
clear_bit(i, valid_mask);
}
}
static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
{
const struct chv_gpio_pinrange *range;
@@ -1557,7 +1581,8 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
chip->label = dev_name(pctrl->dev);
chip->parent = pctrl->dev;
chip->base = -1;
chip->irq.need_valid_mask = need_valid_mask;
if (need_valid_mask)
chip->irq.init_valid_mask = chv_init_irq_valid_mask;
ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl);
if (ret) {
@@ -1576,21 +1601,6 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
}
}
/* Do not add GPIOs that can only generate GPEs to the IRQ domain */
for (i = 0; i < community->npins; i++) {
const struct pinctrl_pin_desc *desc;
u32 intsel;
desc = &community->pins[i];
intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
intsel &= CHV_PADCTRL0_INTSEL_MASK;
intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
if (need_valid_mask && intsel >= community->nirqs)
clear_bit(i, chip->irq.valid_mask);
}
/*
* The same set of machines in chv_no_valid_mask[] have incorrectly
* configured GPIOs that generate spurious interrupts so we use