|
|
@@ -24,9 +24,9 @@
|
|
|
#include <linux/pm.h>
|
|
|
#include <linux/of.h>
|
|
|
#include <linux/of_device.h>
|
|
|
-#include <linux/irqdomain.h>
|
|
|
#include <linux/irqchip/chained_irq.h>
|
|
|
#include <linux/gpio.h>
|
|
|
+#include <linux/bitops.h>
|
|
|
#include <linux/platform_data/gpio-omap.h>
|
|
|
|
|
|
#define OFF_MODE 1
|
|
|
@@ -52,7 +52,6 @@ struct gpio_bank {
|
|
|
struct list_head node;
|
|
|
void __iomem *base;
|
|
|
u16 irq;
|
|
|
- struct irq_domain *domain;
|
|
|
u32 non_wakeup_gpios;
|
|
|
u32 enabled_non_wakeup_gpios;
|
|
|
struct gpio_regs context;
|
|
|
@@ -84,22 +83,21 @@ struct gpio_bank {
|
|
|
};
|
|
|
|
|
|
#define GPIO_INDEX(bank, gpio) (gpio % bank->width)
|
|
|
-#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio))
|
|
|
+#define GPIO_BIT(bank, gpio) (BIT(GPIO_INDEX(bank, gpio)))
|
|
|
#define GPIO_MOD_CTRL_BIT BIT(0)
|
|
|
|
|
|
#define BANK_USED(bank) (bank->mod_usage || bank->irq_usage)
|
|
|
-#define LINE_USED(line, offset) (line & (1 << offset))
|
|
|
+#define LINE_USED(line, offset) (line & (BIT(offset)))
|
|
|
|
|
|
static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq)
|
|
|
{
|
|
|
return bank->chip.base + gpio_irq;
|
|
|
}
|
|
|
|
|
|
-static int omap_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
|
|
+static inline struct gpio_bank *_irq_data_get_bank(struct irq_data *d)
|
|
|
{
|
|
|
- struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
|
|
|
-
|
|
|
- return irq_find_mapping(bank->domain, offset);
|
|
|
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
|
|
|
+ return container_of(chip, struct gpio_bank, chip);
|
|
|
}
|
|
|
|
|
|
static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
|
|
|
@@ -110,9 +108,9 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
|
|
|
reg += bank->regs->direction;
|
|
|
l = readl_relaxed(reg);
|
|
|
if (is_input)
|
|
|
- l |= 1 << gpio;
|
|
|
+ l |= BIT(gpio);
|
|
|
else
|
|
|
- l &= ~(1 << gpio);
|
|
|
+ l &= ~(BIT(gpio));
|
|
|
writel_relaxed(l, reg);
|
|
|
bank->context.oe = l;
|
|
|
}
|
|
|
@@ -155,14 +153,14 @@ static int _get_gpio_datain(struct gpio_bank *bank, int offset)
|
|
|
{
|
|
|
void __iomem *reg = bank->base + bank->regs->datain;
|
|
|
|
|
|
- return (readl_relaxed(reg) & (1 << offset)) != 0;
|
|
|
+ return (readl_relaxed(reg) & (BIT(offset))) != 0;
|
|
|
}
|
|
|
|
|
|
static int _get_gpio_dataout(struct gpio_bank *bank, int offset)
|
|
|
{
|
|
|
void __iomem *reg = bank->base + bank->regs->dataout;
|
|
|
|
|
|
- return (readl_relaxed(reg) & (1 << offset)) != 0;
|
|
|
+ return (readl_relaxed(reg) & (BIT(offset))) != 0;
|
|
|
}
|
|
|
|
|
|
static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
|
|
|
@@ -180,7 +178,7 @@ static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
|
|
|
static inline void _gpio_dbck_enable(struct gpio_bank *bank)
|
|
|
{
|
|
|
if (bank->dbck_enable_mask && !bank->dbck_enabled) {
|
|
|
- clk_enable(bank->dbck);
|
|
|
+ clk_prepare_enable(bank->dbck);
|
|
|
bank->dbck_enabled = true;
|
|
|
|
|
|
writel_relaxed(bank->dbck_enable_mask,
|
|
|
@@ -198,7 +196,7 @@ static inline void _gpio_dbck_disable(struct gpio_bank *bank)
|
|
|
*/
|
|
|
writel_relaxed(0, bank->base + bank->regs->debounce_en);
|
|
|
|
|
|
- clk_disable(bank->dbck);
|
|
|
+ clk_disable_unprepare(bank->dbck);
|
|
|
bank->dbck_enabled = false;
|
|
|
}
|
|
|
}
|
|
|
@@ -231,7 +229,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
|
|
|
|
|
|
l = GPIO_BIT(bank, gpio);
|
|
|
|
|
|
- clk_enable(bank->dbck);
|
|
|
+ clk_prepare_enable(bank->dbck);
|
|
|
reg = bank->base + bank->regs->debounce;
|
|
|
writel_relaxed(debounce, reg);
|
|
|
|
|
|
@@ -245,7 +243,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
|
|
|
bank->dbck_enable_mask = val;
|
|
|
|
|
|
writel_relaxed(val, reg);
|
|
|
- clk_disable(bank->dbck);
|
|
|
+ clk_disable_unprepare(bank->dbck);
|
|
|
/*
|
|
|
* Enable debounce clock per module.
|
|
|
* This call is mandatory because in omap_gpio_request() when
|
|
|
@@ -290,7 +288,7 @@ static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio)
|
|
|
bank->context.debounce = 0;
|
|
|
writel_relaxed(bank->context.debounce, bank->base +
|
|
|
bank->regs->debounce);
|
|
|
- clk_disable(bank->dbck);
|
|
|
+ clk_disable_unprepare(bank->dbck);
|
|
|
bank->dbck_enabled = false;
|
|
|
}
|
|
|
}
|
|
|
@@ -299,7 +297,7 @@ static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio,
|
|
|
unsigned trigger)
|
|
|
{
|
|
|
void __iomem *base = bank->base;
|
|
|
- u32 gpio_bit = 1 << gpio;
|
|
|
+ u32 gpio_bit = BIT(gpio);
|
|
|
|
|
|
_gpio_rmw(base, bank->regs->leveldetect0, gpio_bit,
|
|
|
trigger & IRQ_TYPE_LEVEL_LOW);
|
|
|
@@ -368,9 +366,9 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
|
|
|
|
|
|
l = readl_relaxed(reg);
|
|
|
if ((l >> gpio) & 1)
|
|
|
- l &= ~(1 << gpio);
|
|
|
+ l &= ~(BIT(gpio));
|
|
|
else
|
|
|
- l |= 1 << gpio;
|
|
|
+ l |= BIT(gpio);
|
|
|
|
|
|
writel_relaxed(l, reg);
|
|
|
}
|
|
|
@@ -392,11 +390,11 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
|
|
|
|
|
|
l = readl_relaxed(reg);
|
|
|
if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
|
|
|
- bank->toggle_mask |= 1 << gpio;
|
|
|
+ bank->toggle_mask |= BIT(gpio);
|
|
|
if (trigger & IRQ_TYPE_EDGE_RISING)
|
|
|
- l |= 1 << gpio;
|
|
|
+ l |= BIT(gpio);
|
|
|
else if (trigger & IRQ_TYPE_EDGE_FALLING)
|
|
|
- l &= ~(1 << gpio);
|
|
|
+ l &= ~(BIT(gpio));
|
|
|
else
|
|
|
return -EINVAL;
|
|
|
|
|
|
@@ -413,10 +411,10 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio,
|
|
|
if (trigger & IRQ_TYPE_EDGE_RISING)
|
|
|
l |= 2 << (gpio << 1);
|
|
|
if (trigger & IRQ_TYPE_EDGE_FALLING)
|
|
|
- l |= 1 << (gpio << 1);
|
|
|
+ l |= BIT(gpio << 1);
|
|
|
|
|
|
/* Enable wake-up during idle for dynamic tick */
|
|
|
- _gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger);
|
|
|
+ _gpio_rmw(base, bank->regs->wkup_en, BIT(gpio), trigger);
|
|
|
bank->context.wake_en =
|
|
|
readl_relaxed(bank->base + bank->regs->wkup_en);
|
|
|
writel_relaxed(l, reg);
|
|
|
@@ -430,7 +428,7 @@ static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset)
|
|
|
void __iomem *reg = bank->base + bank->regs->pinctrl;
|
|
|
|
|
|
/* Claim the pin for MPU */
|
|
|
- writel_relaxed(readl_relaxed(reg) | (1 << offset), reg);
|
|
|
+ writel_relaxed(readl_relaxed(reg) | (BIT(offset)), reg);
|
|
|
}
|
|
|
|
|
|
if (bank->regs->ctrl && !BANK_USED(bank)) {
|
|
|
@@ -453,7 +451,7 @@ static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset)
|
|
|
!LINE_USED(bank->mod_usage, offset) &&
|
|
|
!LINE_USED(bank->irq_usage, offset)) {
|
|
|
/* Disable wake-up during idle for dynamic tick */
|
|
|
- _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0);
|
|
|
+ _gpio_rmw(base, bank->regs->wkup_en, BIT(offset), 0);
|
|
|
bank->context.wake_en =
|
|
|
readl_relaxed(bank->base + bank->regs->wkup_en);
|
|
|
}
|
|
|
@@ -479,7 +477,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
|
|
|
|
|
|
static int gpio_irq_type(struct irq_data *d, unsigned type)
|
|
|
{
|
|
|
- struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
|
|
|
+ struct gpio_bank *bank = _irq_data_get_bank(d);
|
|
|
unsigned gpio = 0;
|
|
|
int retval;
|
|
|
unsigned long flags;
|
|
|
@@ -509,20 +507,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
|
|
|
if (!LINE_USED(bank->mod_usage, offset)) {
|
|
|
_enable_gpio_module(bank, offset);
|
|
|
_set_gpio_direction(bank, offset, 1);
|
|
|
- } else if (!gpio_is_input(bank, 1 << offset)) {
|
|
|
+ } else if (!gpio_is_input(bank, BIT(offset))) {
|
|
|
spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- retval = gpio_lock_as_irq(&bank->chip, offset);
|
|
|
- if (retval) {
|
|
|
- dev_err(bank->dev, "unable to lock offset %d for IRQ\n",
|
|
|
- offset);
|
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
- return retval;
|
|
|
- }
|
|
|
-
|
|
|
- bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio);
|
|
|
+ bank->irq_usage |= BIT(GPIO_INDEX(bank, gpio));
|
|
|
spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
|
|
|
@@ -559,7 +549,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
|
|
|
{
|
|
|
void __iomem *reg = bank->base;
|
|
|
u32 l;
|
|
|
- u32 mask = (1 << bank->width) - 1;
|
|
|
+ u32 mask = (BIT(bank->width)) - 1;
|
|
|
|
|
|
reg += bank->regs->irqenable;
|
|
|
l = readl_relaxed(reg);
|
|
|
@@ -664,7 +654,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio)
|
|
|
/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
|
|
|
static int gpio_wake_enable(struct irq_data *d, unsigned int enable)
|
|
|
{
|
|
|
- struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
|
|
|
+ struct gpio_bank *bank = _irq_data_get_bank(d);
|
|
|
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
|
|
|
|
|
|
return _set_gpio_wakeup(bank, gpio, enable);
|
|
|
@@ -691,7 +681,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
|
|
|
_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
|
|
_enable_gpio_module(bank, offset);
|
|
|
}
|
|
|
- bank->mod_usage |= 1 << offset;
|
|
|
+ bank->mod_usage |= BIT(offset);
|
|
|
spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
return 0;
|
|
|
@@ -703,7 +693,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
|
|
|
unsigned long flags;
|
|
|
|
|
|
spin_lock_irqsave(&bank->lock, flags);
|
|
|
- bank->mod_usage &= ~(1 << offset);
|
|
|
+ bank->mod_usage &= ~(BIT(offset));
|
|
|
_disable_gpio_module(bank, offset);
|
|
|
_reset_gpio(bank, bank->chip.base + offset);
|
|
|
spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
@@ -732,11 +722,12 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
|
unsigned int bit;
|
|
|
struct gpio_bank *bank;
|
|
|
int unmasked = 0;
|
|
|
- struct irq_chip *chip = irq_desc_get_chip(desc);
|
|
|
+ struct irq_chip *irqchip = irq_desc_get_chip(desc);
|
|
|
+ struct gpio_chip *chip = irq_get_handler_data(irq);
|
|
|
|
|
|
- chained_irq_enter(chip, desc);
|
|
|
+ chained_irq_enter(irqchip, desc);
|
|
|
|
|
|
- bank = irq_get_handler_data(irq);
|
|
|
+ bank = container_of(chip, struct gpio_bank, chip);
|
|
|
isr_reg = bank->base + bank->regs->irqstatus;
|
|
|
pm_runtime_get_sync(bank->dev);
|
|
|
|
|
|
@@ -764,7 +755,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
|
configured, we could unmask GPIO bank interrupt immediately */
|
|
|
if (!level_mask && !unmasked) {
|
|
|
unmasked = 1;
|
|
|
- chained_irq_exit(chip, desc);
|
|
|
+ chained_irq_exit(irqchip, desc);
|
|
|
}
|
|
|
|
|
|
if (!isr)
|
|
|
@@ -772,7 +763,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
|
|
|
|
while (isr) {
|
|
|
bit = __ffs(isr);
|
|
|
- isr &= ~(1 << bit);
|
|
|
+ isr &= ~(BIT(bit));
|
|
|
|
|
|
/*
|
|
|
* Some chips can't respond to both rising and falling
|
|
|
@@ -781,10 +772,11 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
|
* to respond to the IRQ for the opposite direction.
|
|
|
* This will be indicated in the bank toggle_mask.
|
|
|
*/
|
|
|
- if (bank->toggle_mask & (1 << bit))
|
|
|
+ if (bank->toggle_mask & (BIT(bit)))
|
|
|
_toggle_gpio_edge_triggering(bank, bit);
|
|
|
|
|
|
- generic_handle_irq(irq_find_mapping(bank->domain, bit));
|
|
|
+ generic_handle_irq(irq_find_mapping(bank->chip.irqdomain,
|
|
|
+ bit));
|
|
|
}
|
|
|
}
|
|
|
/* if bank has any level sensitive GPIO pin interrupt
|
|
|
@@ -793,20 +785,20 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
|
interrupt */
|
|
|
exit:
|
|
|
if (!unmasked)
|
|
|
- chained_irq_exit(chip, desc);
|
|
|
+ chained_irq_exit(irqchip, desc);
|
|
|
pm_runtime_put(bank->dev);
|
|
|
}
|
|
|
|
|
|
static void gpio_irq_shutdown(struct irq_data *d)
|
|
|
{
|
|
|
- struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
|
|
|
+ struct gpio_bank *bank = _irq_data_get_bank(d);
|
|
|
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
|
|
|
unsigned long flags;
|
|
|
unsigned offset = GPIO_INDEX(bank, gpio);
|
|
|
|
|
|
spin_lock_irqsave(&bank->lock, flags);
|
|
|
gpio_unlock_as_irq(&bank->chip, offset);
|
|
|
- bank->irq_usage &= ~(1 << offset);
|
|
|
+ bank->irq_usage &= ~(BIT(offset));
|
|
|
_disable_gpio_module(bank, offset);
|
|
|
_reset_gpio(bank, gpio);
|
|
|
spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
@@ -821,7 +813,7 @@ static void gpio_irq_shutdown(struct irq_data *d)
|
|
|
|
|
|
static void gpio_ack_irq(struct irq_data *d)
|
|
|
{
|
|
|
- struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
|
|
|
+ struct gpio_bank *bank = _irq_data_get_bank(d);
|
|
|
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
|
|
|
|
|
|
_clear_gpio_irqstatus(bank, gpio);
|
|
|
@@ -829,7 +821,7 @@ static void gpio_ack_irq(struct irq_data *d)
|
|
|
|
|
|
static void gpio_mask_irq(struct irq_data *d)
|
|
|
{
|
|
|
- struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
|
|
|
+ struct gpio_bank *bank = _irq_data_get_bank(d);
|
|
|
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
|
|
|
unsigned long flags;
|
|
|
|
|
|
@@ -841,7 +833,7 @@ static void gpio_mask_irq(struct irq_data *d)
|
|
|
|
|
|
static void gpio_unmask_irq(struct irq_data *d)
|
|
|
{
|
|
|
- struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
|
|
|
+ struct gpio_bank *bank = _irq_data_get_bank(d);
|
|
|
unsigned int gpio = irq_to_gpio(bank, d->hwirq);
|
|
|
unsigned int irq_mask = GPIO_BIT(bank, gpio);
|
|
|
u32 trigger = irqd_get_trigger_type(d);
|
|
|
@@ -936,6 +928,21 @@ static inline void mpuio_init(struct gpio_bank *bank)
|
|
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
|
|
|
|
+static int gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
|
|
+{
|
|
|
+ struct gpio_bank *bank;
|
|
|
+ unsigned long flags;
|
|
|
+ void __iomem *reg;
|
|
|
+ int dir;
|
|
|
+
|
|
|
+ bank = container_of(chip, struct gpio_bank, chip);
|
|
|
+ reg = bank->base + bank->regs->direction;
|
|
|
+ spin_lock_irqsave(&bank->lock, flags);
|
|
|
+ dir = !!(readl_relaxed(reg) & BIT(offset));
|
|
|
+ spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
+ return dir;
|
|
|
+}
|
|
|
+
|
|
|
static int gpio_input(struct gpio_chip *chip, unsigned offset)
|
|
|
{
|
|
|
struct gpio_bank *bank;
|
|
|
@@ -954,7 +961,7 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset)
|
|
|
u32 mask;
|
|
|
|
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
|
- mask = (1 << offset);
|
|
|
+ mask = (BIT(offset));
|
|
|
|
|
|
if (gpio_is_input(bank, mask))
|
|
|
return _get_gpio_datain(bank, offset);
|
|
|
@@ -1081,10 +1088,12 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
|
|
|
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
|
|
|
}
|
|
|
|
|
|
-static void omap_gpio_chip_init(struct gpio_bank *bank)
|
|
|
+static int omap_gpio_chip_init(struct gpio_bank *bank)
|
|
|
{
|
|
|
int j;
|
|
|
static int gpio;
|
|
|
+ int irq_base = 0;
|
|
|
+ int ret;
|
|
|
|
|
|
/*
|
|
|
* REVISIT eventually switch from OMAP-specific gpio structs
|
|
|
@@ -1092,12 +1101,12 @@ static void omap_gpio_chip_init(struct gpio_bank *bank)
|
|
|
*/
|
|
|
bank->chip.request = omap_gpio_request;
|
|
|
bank->chip.free = omap_gpio_free;
|
|
|
+ bank->chip.get_direction = gpio_get_direction;
|
|
|
bank->chip.direction_input = gpio_input;
|
|
|
bank->chip.get = gpio_get;
|
|
|
bank->chip.direction_output = gpio_output;
|
|
|
bank->chip.set_debounce = gpio_debounce;
|
|
|
bank->chip.set = gpio_set;
|
|
|
- bank->chip.to_irq = omap_gpio_to_irq;
|
|
|
if (bank->is_mpuio) {
|
|
|
bank->chip.label = "mpuio";
|
|
|
if (bank->regs->wkup_en)
|
|
|
@@ -1110,22 +1119,48 @@ static void omap_gpio_chip_init(struct gpio_bank *bank)
|
|
|
}
|
|
|
bank->chip.ngpio = bank->width;
|
|
|
|
|
|
- gpiochip_add(&bank->chip);
|
|
|
+ ret = gpiochip_add(&bank->chip);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(bank->dev, "Could not register gpio chip %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef CONFIG_ARCH_OMAP1
|
|
|
+ /*
|
|
|
+ * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
|
|
|
+ * irq_alloc_descs() since a base IRQ offset will no longer be needed.
|
|
|
+ */
|
|
|
+ irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
|
|
|
+ if (irq_base < 0) {
|
|
|
+ dev_err(bank->dev, "Couldn't allocate IRQ numbers\n");
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ ret = gpiochip_irqchip_add(&bank->chip, &gpio_irq_chip,
|
|
|
+ irq_base, gpio_irq_handler,
|
|
|
+ IRQ_TYPE_NONE);
|
|
|
+
|
|
|
+ if (ret) {
|
|
|
+ dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret);
|
|
|
+ ret = gpiochip_remove(&bank->chip);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+
|
|
|
+ gpiochip_set_chained_irqchip(&bank->chip, &gpio_irq_chip,
|
|
|
+ bank->irq, gpio_irq_handler);
|
|
|
|
|
|
for (j = 0; j < bank->width; j++) {
|
|
|
- int irq = irq_create_mapping(bank->domain, j);
|
|
|
+ int irq = irq_find_mapping(bank->chip.irqdomain, j);
|
|
|
irq_set_lockdep_class(irq, &gpio_lock_class);
|
|
|
- irq_set_chip_data(irq, bank);
|
|
|
if (bank->is_mpuio) {
|
|
|
omap_mpuio_alloc_gc(bank, irq, bank->width);
|
|
|
- } else {
|
|
|
- irq_set_chip_and_handler(irq, &gpio_irq_chip,
|
|
|
- handle_simple_irq);
|
|
|
- set_irq_flags(irq, IRQF_VALID);
|
|
|
+ irq_set_chip_and_handler(irq, NULL, NULL);
|
|
|
+ set_irq_flags(irq, 0);
|
|
|
}
|
|
|
}
|
|
|
- irq_set_chained_handler(bank->irq, gpio_irq_handler);
|
|
|
- irq_set_handler_data(bank->irq, bank);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static const struct of_device_id omap_gpio_match[];
|
|
|
@@ -1138,9 +1173,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|
|
const struct omap_gpio_platform_data *pdata;
|
|
|
struct resource *res;
|
|
|
struct gpio_bank *bank;
|
|
|
-#ifdef CONFIG_ARCH_OMAP1
|
|
|
- int irq_base;
|
|
|
-#endif
|
|
|
+ int ret;
|
|
|
|
|
|
match = of_match_device(of_match_ptr(omap_gpio_match), dev);
|
|
|
|
|
|
@@ -1162,6 +1195,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|
|
|
|
|
bank->irq = res->start;
|
|
|
bank->dev = dev;
|
|
|
+ bank->chip.dev = dev;
|
|
|
bank->dbck_flag = pdata->dbck_flag;
|
|
|
bank->stride = pdata->bank_stride;
|
|
|
bank->width = pdata->bank_width;
|
|
|
@@ -1182,29 +1216,6 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|
|
pdata->get_context_loss_count;
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_ARCH_OMAP1
|
|
|
- /*
|
|
|
- * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop
|
|
|
- * irq_alloc_descs() and irq_domain_add_legacy() and just use a
|
|
|
- * linear IRQ domain mapping for all OMAP platforms.
|
|
|
- */
|
|
|
- irq_base = irq_alloc_descs(-1, 0, bank->width, 0);
|
|
|
- if (irq_base < 0) {
|
|
|
- dev_err(dev, "Couldn't allocate IRQ numbers\n");
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
-
|
|
|
- bank->domain = irq_domain_add_legacy(node, bank->width, irq_base,
|
|
|
- 0, &irq_domain_simple_ops, NULL);
|
|
|
-#else
|
|
|
- bank->domain = irq_domain_add_linear(node, bank->width,
|
|
|
- &irq_domain_simple_ops, NULL);
|
|
|
-#endif
|
|
|
- if (!bank->domain) {
|
|
|
- dev_err(dev, "Couldn't register an IRQ domain\n");
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
-
|
|
|
if (bank->regs->set_dataout && bank->regs->clr_dataout)
|
|
|
bank->set_dataout = _set_gpio_dataout_reg;
|
|
|
else
|
|
|
@@ -1216,7 +1227,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
bank->base = devm_ioremap_resource(dev, res);
|
|
|
if (IS_ERR(bank->base)) {
|
|
|
- irq_domain_remove(bank->domain);
|
|
|
+ irq_domain_remove(bank->chip.irqdomain);
|
|
|
return PTR_ERR(bank->base);
|
|
|
}
|
|
|
|
|
|
@@ -1230,7 +1241,11 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|
|
mpuio_init(bank);
|
|
|
|
|
|
omap_gpio_mod_init(bank);
|
|
|
- omap_gpio_chip_init(bank);
|
|
|
+
|
|
|
+ ret = omap_gpio_chip_init(bank);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
omap_gpio_show_rev(bank);
|
|
|
|
|
|
pm_runtime_put(bank->dev);
|