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:
parent
4f78d91c72
commit
5fbe5b5883
@ -689,8 +689,11 @@ static struct irq_chip aspeed_gpio_irqchip = {
|
||||
.irq_set_type = aspeed_gpio_set_type,
|
||||
};
|
||||
|
||||
static void set_irq_valid_mask(struct aspeed_gpio *gpio)
|
||||
static void aspeed_init_irq_valid_mask(struct gpio_chip *gc,
|
||||
unsigned long *valid_mask,
|
||||
unsigned int ngpios)
|
||||
{
|
||||
struct aspeed_gpio *gpio = gpiochip_get_data(gc);
|
||||
const struct aspeed_bank_props *props = gpio->config->props;
|
||||
|
||||
while (!is_bank_props_sentinel(props)) {
|
||||
@ -704,7 +707,7 @@ static void set_irq_valid_mask(struct aspeed_gpio *gpio)
|
||||
if (i >= gpio->config->nr_gpios)
|
||||
break;
|
||||
|
||||
clear_bit(i, gpio->chip.irq.valid_mask);
|
||||
clear_bit(i, valid_mask);
|
||||
}
|
||||
|
||||
props++;
|
||||
@ -1203,7 +1206,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
|
||||
girq->parents[0] = gpio->irq;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
girq->need_valid_mask = true;
|
||||
girq->init_valid_mask = aspeed_init_irq_valid_mask;
|
||||
}
|
||||
|
||||
gpio->offset_timer =
|
||||
@ -1215,10 +1218,6 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Now the valid mask is allocated */
|
||||
if (gpio->irq)
|
||||
set_irq_valid_mask(gpio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -429,6 +429,23 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void stmpe_init_irq_valid_mask(struct gpio_chip *gc,
|
||||
unsigned long *valid_mask,
|
||||
unsigned int ngpios)
|
||||
{
|
||||
struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc);
|
||||
int i;
|
||||
|
||||
if (!stmpe_gpio->norequest_mask)
|
||||
return;
|
||||
|
||||
/* Forbid unused lines to be mapped as IRQs */
|
||||
for (i = 0; i < sizeof(u32); i++) {
|
||||
if (stmpe_gpio->norequest_mask & BIT(i))
|
||||
clear_bit(i, valid_mask);
|
||||
}
|
||||
}
|
||||
|
||||
static int stmpe_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
|
||||
@ -454,14 +471,21 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
|
||||
stmpe_gpio->chip.parent = &pdev->dev;
|
||||
stmpe_gpio->chip.of_node = np;
|
||||
stmpe_gpio->chip.base = -1;
|
||||
/*
|
||||
* REVISIT: this makes sure the valid mask gets allocated and
|
||||
* filled in when adding the gpio_chip, but the rest of the
|
||||
* gpio_irqchip is still filled in using the old method
|
||||
* in gpiochip_irqchip_add_nested() so clean this up once we
|
||||
* get the gpio_irqchip to initialize while adding the
|
||||
* gpio_chip also for threaded irqchips.
|
||||
*/
|
||||
stmpe_gpio->chip.irq.init_valid_mask = stmpe_init_irq_valid_mask;
|
||||
|
||||
if (IS_ENABLED(CONFIG_DEBUG_FS))
|
||||
stmpe_gpio->chip.dbg_show = stmpe_dbg_show;
|
||||
|
||||
of_property_read_u32(np, "st,norequest-mask",
|
||||
&stmpe_gpio->norequest_mask);
|
||||
if (stmpe_gpio->norequest_mask)
|
||||
stmpe_gpio->chip.irq.need_valid_mask = true;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
@ -487,14 +511,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
|
||||
dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
|
||||
goto out_disable;
|
||||
}
|
||||
if (stmpe_gpio->norequest_mask) {
|
||||
int i;
|
||||
|
||||
/* Forbid unused lines to be mapped as IRQs */
|
||||
for (i = 0; i < sizeof(u32); i++)
|
||||
if (stmpe_gpio->norequest_mask & BIT(i))
|
||||
clear_bit(i, stmpe_gpio->chip.irq.valid_mask);
|
||||
}
|
||||
ret = gpiochip_irqchip_add_nested(&stmpe_gpio->chip,
|
||||
&stmpe_gpio_irq_chip,
|
||||
0,
|
||||
|
@ -214,6 +214,17 @@ static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {
|
||||
tqmx86_gpio_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
|
||||
unsigned long *valid_mask,
|
||||
unsigned int ngpios)
|
||||
{
|
||||
/* Only GPIOs 4-7 are valid for interrupts. Clear the others */
|
||||
clear_bit(0, valid_mask);
|
||||
clear_bit(1, valid_mask);
|
||||
clear_bit(2, valid_mask);
|
||||
clear_bit(3, valid_mask);
|
||||
}
|
||||
|
||||
static int tqmx86_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -260,7 +271,6 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
|
||||
chip->get = tqmx86_gpio_get;
|
||||
chip->set = tqmx86_gpio_set;
|
||||
chip->ngpio = TQMX86_NGPIO;
|
||||
chip->irq.need_valid_mask = true;
|
||||
chip->parent = pdev->dev.parent;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
@ -296,6 +306,7 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
|
||||
girq->parents[0] = irq;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_simple_irq;
|
||||
girq->init_valid_mask = tqmx86_init_irq_valid_mask;
|
||||
}
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, chip, gpio);
|
||||
@ -304,14 +315,6 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
|
||||
goto out_pm_dis;
|
||||
}
|
||||
|
||||
/* Only GPIOs 4-7 are valid for interrupts. Clear the others */
|
||||
if (irq) {
|
||||
clear_bit(0, girq->valid_mask);
|
||||
clear_bit(1, girq->valid_mask);
|
||||
clear_bit(2, girq->valid_mask);
|
||||
clear_bit(3, girq->valid_mask);
|
||||
}
|
||||
|
||||
dev_info(dev, "GPIO functionality initialized with %d pins\n",
|
||||
chip->ngpio);
|
||||
|
||||
|
@ -1615,15 +1615,19 @@ static struct gpio_chip *find_chip_by_name(const char *name)
|
||||
* The following is irqchip helper code for gpiochips.
|
||||
*/
|
||||
|
||||
static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip)
|
||||
static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc)
|
||||
{
|
||||
if (!gpiochip->irq.need_valid_mask)
|
||||
struct gpio_irq_chip *girq = &gc->irq;
|
||||
|
||||
if (!girq->init_valid_mask)
|
||||
return 0;
|
||||
|
||||
gpiochip->irq.valid_mask = gpiochip_allocate_mask(gpiochip);
|
||||
if (!gpiochip->irq.valid_mask)
|
||||
girq->valid_mask = gpiochip_allocate_mask(gc);
|
||||
if (!girq->valid_mask)
|
||||
return -ENOMEM;
|
||||
|
||||
girq->init_valid_mask(gc, girq->valid_mask, gc->ngpio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -152,6 +152,13 @@ static const struct x86_cpu_id int0002_cpu_ids[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static void int0002_init_irq_valid_mask(struct gpio_chip *chip,
|
||||
unsigned long *valid_mask,
|
||||
unsigned int ngpios)
|
||||
{
|
||||
bitmap_clear(valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN);
|
||||
}
|
||||
|
||||
static int int0002_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -184,7 +191,7 @@ static int int0002_probe(struct platform_device *pdev)
|
||||
chip->direction_output = int0002_gpio_direction_output;
|
||||
chip->base = -1;
|
||||
chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1;
|
||||
chip->irq.need_valid_mask = true;
|
||||
chip->irq.init_valid_mask = int0002_init_irq_valid_mask;
|
||||
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL);
|
||||
if (ret) {
|
||||
@ -192,8 +199,6 @@ static int int0002_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bitmap_clear(chip->irq.valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN);
|
||||
|
||||
/*
|
||||
* We manually request the irq here instead of passing a flow-handler
|
||||
* to gpiochip_set_chained_irqchip, because the irq is shared.
|
||||
|
@ -202,11 +202,17 @@ struct gpio_irq_chip {
|
||||
bool threaded;
|
||||
|
||||
/**
|
||||
* @need_valid_mask:
|
||||
*
|
||||
* If set core allocates @valid_mask with all bits set to one.
|
||||
* @init_valid_mask: optional routine to initialize @valid_mask, to be
|
||||
* used if not all GPIO lines are valid interrupts. Sometimes some
|
||||
* lines just cannot fire interrupts, and this routine, when defined,
|
||||
* is passed a bitmap in "valid_mask" and it will have ngpios
|
||||
* bits from 0..(ngpios-1) set to "1" as in valid. The callback can
|
||||
* then directly set some bits to "0" if they cannot be used for
|
||||
* interrupts.
|
||||
*/
|
||||
bool need_valid_mask;
|
||||
void (*init_valid_mask)(struct gpio_chip *chip,
|
||||
unsigned long *valid_mask,
|
||||
unsigned int ngpios);
|
||||
|
||||
/**
|
||||
* @valid_mask:
|
||||
|
Loading…
Reference in New Issue
Block a user