diff options
| author | Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> | 2024-12-04 09:04:14 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-12-19 18:13:03 +0100 |
| commit | d7a7e501fb720e5f50313cdc5a7919a4a2fa9d1f (patch) | |
| tree | ad7d61e2dc12d8d53bed1fe0a6ae4eb21eb6530b /drivers/gpio | |
| parent | e1ae3051044064ae1376498548580e8e52ca9af9 (diff) | |
| download | linux-d7a7e501fb720e5f50313cdc5a7919a4a2fa9d1f.tar.gz linux-d7a7e501fb720e5f50313cdc5a7919a4a2fa9d1f.tar.bz2 linux-d7a7e501fb720e5f50313cdc5a7919a4a2fa9d1f.zip | |
gpio: graniterapids: Check if GPIO line can be used for IRQs
commit c0ec4890d6454980c53c3cc164140115c4a671f2 upstream.
GPIO line can only be used as interrupt if its INTSEL register is
programmed by the BIOS.
Cc: stable@vger.kernel.org
Signed-off-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Andy Shevchenko <andy@kernel.org>
Link: https://lore.kernel.org/r/20241204070415.1034449-7-mika.westerberg@linux.intel.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/gpio-graniterapids.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/gpio/gpio-graniterapids.c b/drivers/gpio/gpio-graniterapids.c index 88b579ff5f00..ad6a045fd3d2 100644 --- a/drivers/gpio/gpio-graniterapids.c +++ b/drivers/gpio/gpio-graniterapids.c @@ -39,6 +39,7 @@ #define GNR_CFG_DW_HOSTSW_MODE BIT(27) #define GNR_CFG_DW_RX_MASK GENMASK(23, 22) +#define GNR_CFG_DW_INTSEL_MASK GENMASK(21, 14) #define GNR_CFG_DW_RX_DISABLE FIELD_PREP(GNR_CFG_DW_RX_MASK, 2) #define GNR_CFG_DW_RX_EDGE FIELD_PREP(GNR_CFG_DW_RX_MASK, 1) #define GNR_CFG_DW_RX_LEVEL FIELD_PREP(GNR_CFG_DW_RX_MASK, 0) @@ -227,10 +228,18 @@ static void gnr_gpio_irq_unmask(struct irq_data *d) static int gnr_gpio_irq_set_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - irq_hw_number_t pin = irqd_to_hwirq(d); - u32 mask = GNR_CFG_DW_RX_MASK; + struct gnr_gpio *priv = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + u32 reg; u32 set; + /* Allow interrupts only if Interrupt Select field is non-zero */ + reg = readl(gnr_gpio_get_padcfg_addr(priv, hwirq)); + if (!(reg & GNR_CFG_DW_INTSEL_MASK)) { + dev_dbg(gc->parent, "GPIO %lu cannot be used as IRQ", hwirq); + return -EPERM; + } + /* Falling edge and level low triggers not supported by the GPIO controller */ switch (type) { case IRQ_TYPE_NONE: @@ -248,7 +257,7 @@ static int gnr_gpio_irq_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } - return gnr_gpio_configure_line(gc, pin, mask, set); + return gnr_gpio_configure_line(gc, hwirq, GNR_CFG_DW_RX_MASK, set); } static const struct irq_chip gnr_gpio_irq_chip = { |
