|
@@ -29,6 +29,7 @@
|
|
#include <linux/platform_data/gpio-omap.h>
|
|
#include <linux/platform_data/gpio-omap.h>
|
|
|
|
|
|
#define OFF_MODE 1
|
|
#define OFF_MODE 1
|
|
|
|
+#define OMAP4_GPIO_DEBOUNCINGTIME_MASK 0xFF
|
|
|
|
|
|
static LIST_HEAD(omap_gpio_list);
|
|
static LIST_HEAD(omap_gpio_list);
|
|
|
|
|
|
@@ -57,7 +58,7 @@ struct gpio_bank {
|
|
u32 saved_datain;
|
|
u32 saved_datain;
|
|
u32 level_mask;
|
|
u32 level_mask;
|
|
u32 toggle_mask;
|
|
u32 toggle_mask;
|
|
- spinlock_t lock;
|
|
|
|
|
|
+ raw_spinlock_t lock;
|
|
struct gpio_chip chip;
|
|
struct gpio_chip chip;
|
|
struct clk *dbck;
|
|
struct clk *dbck;
|
|
u32 mod_usage;
|
|
u32 mod_usage;
|
|
@@ -175,7 +176,7 @@ static inline void omap_gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set
|
|
static inline void omap_gpio_dbck_enable(struct gpio_bank *bank)
|
|
static inline void omap_gpio_dbck_enable(struct gpio_bank *bank)
|
|
{
|
|
{
|
|
if (bank->dbck_enable_mask && !bank->dbck_enabled) {
|
|
if (bank->dbck_enable_mask && !bank->dbck_enabled) {
|
|
- clk_prepare_enable(bank->dbck);
|
|
|
|
|
|
+ clk_enable(bank->dbck);
|
|
bank->dbck_enabled = true;
|
|
bank->dbck_enabled = true;
|
|
|
|
|
|
writel_relaxed(bank->dbck_enable_mask,
|
|
writel_relaxed(bank->dbck_enable_mask,
|
|
@@ -193,7 +194,7 @@ static inline void omap_gpio_dbck_disable(struct gpio_bank *bank)
|
|
*/
|
|
*/
|
|
writel_relaxed(0, bank->base + bank->regs->debounce_en);
|
|
writel_relaxed(0, bank->base + bank->regs->debounce_en);
|
|
|
|
|
|
- clk_disable_unprepare(bank->dbck);
|
|
|
|
|
|
+ clk_disable(bank->dbck);
|
|
bank->dbck_enabled = false;
|
|
bank->dbck_enabled = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -204,8 +205,9 @@ static inline void omap_gpio_dbck_disable(struct gpio_bank *bank)
|
|
* @offset: the gpio number on this @bank
|
|
* @offset: the gpio number on this @bank
|
|
* @debounce: debounce time to use
|
|
* @debounce: debounce time to use
|
|
*
|
|
*
|
|
- * OMAP's debounce time is in 31us steps so we need
|
|
|
|
- * to convert and round up to the closest unit.
|
|
|
|
|
|
+ * OMAP's debounce time is in 31us steps
|
|
|
|
+ * <debounce time> = (GPIO_DEBOUNCINGTIME[7:0].DEBOUNCETIME + 1) x 31
|
|
|
|
+ * so we need to convert and round up to the closest unit.
|
|
*/
|
|
*/
|
|
static void omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
|
|
static void omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
|
|
unsigned debounce)
|
|
unsigned debounce)
|
|
@@ -213,34 +215,33 @@ static void omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset,
|
|
void __iomem *reg;
|
|
void __iomem *reg;
|
|
u32 val;
|
|
u32 val;
|
|
u32 l;
|
|
u32 l;
|
|
|
|
+ bool enable = !!debounce;
|
|
|
|
|
|
if (!bank->dbck_flag)
|
|
if (!bank->dbck_flag)
|
|
return;
|
|
return;
|
|
|
|
|
|
- if (debounce < 32)
|
|
|
|
- debounce = 0x01;
|
|
|
|
- else if (debounce > 7936)
|
|
|
|
- debounce = 0xff;
|
|
|
|
- else
|
|
|
|
- debounce = (debounce / 0x1f) - 1;
|
|
|
|
|
|
+ if (enable) {
|
|
|
|
+ debounce = DIV_ROUND_UP(debounce, 31) - 1;
|
|
|
|
+ debounce &= OMAP4_GPIO_DEBOUNCINGTIME_MASK;
|
|
|
|
+ }
|
|
|
|
|
|
l = BIT(offset);
|
|
l = BIT(offset);
|
|
|
|
|
|
- clk_prepare_enable(bank->dbck);
|
|
|
|
|
|
+ clk_enable(bank->dbck);
|
|
reg = bank->base + bank->regs->debounce;
|
|
reg = bank->base + bank->regs->debounce;
|
|
writel_relaxed(debounce, reg);
|
|
writel_relaxed(debounce, reg);
|
|
|
|
|
|
reg = bank->base + bank->regs->debounce_en;
|
|
reg = bank->base + bank->regs->debounce_en;
|
|
val = readl_relaxed(reg);
|
|
val = readl_relaxed(reg);
|
|
|
|
|
|
- if (debounce)
|
|
|
|
|
|
+ if (enable)
|
|
val |= l;
|
|
val |= l;
|
|
else
|
|
else
|
|
val &= ~l;
|
|
val &= ~l;
|
|
bank->dbck_enable_mask = val;
|
|
bank->dbck_enable_mask = val;
|
|
|
|
|
|
writel_relaxed(val, reg);
|
|
writel_relaxed(val, reg);
|
|
- clk_disable_unprepare(bank->dbck);
|
|
|
|
|
|
+ clk_disable(bank->dbck);
|
|
/*
|
|
/*
|
|
* Enable debounce clock per module.
|
|
* Enable debounce clock per module.
|
|
* This call is mandatory because in omap_gpio_request() when
|
|
* This call is mandatory because in omap_gpio_request() when
|
|
@@ -285,7 +286,7 @@ static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset)
|
|
bank->context.debounce = 0;
|
|
bank->context.debounce = 0;
|
|
writel_relaxed(bank->context.debounce, bank->base +
|
|
writel_relaxed(bank->context.debounce, bank->base +
|
|
bank->regs->debounce);
|
|
bank->regs->debounce);
|
|
- clk_disable_unprepare(bank->dbck);
|
|
|
|
|
|
+ clk_disable(bank->dbck);
|
|
bank->dbck_enabled = false;
|
|
bank->dbck_enabled = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -498,24 +499,24 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned type)
|
|
if (!BANK_USED(bank))
|
|
if (!BANK_USED(bank))
|
|
pm_runtime_get_sync(bank->dev);
|
|
pm_runtime_get_sync(bank->dev);
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
retval = omap_set_gpio_triggering(bank, offset, type);
|
|
retval = omap_set_gpio_triggering(bank, offset, type);
|
|
if (retval) {
|
|
if (retval) {
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
omap_gpio_init_irq(bank, offset);
|
|
omap_gpio_init_irq(bank, offset);
|
|
if (!omap_gpio_is_input(bank, offset)) {
|
|
if (!omap_gpio_is_input(bank, offset)) {
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
retval = -EINVAL;
|
|
retval = -EINVAL;
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
|
|
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
|
|
- __irq_set_handler_locked(d->irq, handle_level_irq);
|
|
|
|
|
|
+ irq_set_handler_locked(d, handle_level_irq);
|
|
else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
|
|
else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
|
|
- __irq_set_handler_locked(d->irq, handle_edge_irq);
|
|
|
|
|
|
+ irq_set_handler_locked(d, handle_edge_irq);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
@@ -636,14 +637,14 @@ static int omap_set_gpio_wakeup(struct gpio_bank *bank, unsigned offset,
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
if (enable)
|
|
if (enable)
|
|
bank->context.wake_en |= gpio_bit;
|
|
bank->context.wake_en |= gpio_bit;
|
|
else
|
|
else
|
|
bank->context.wake_en &= ~gpio_bit;
|
|
bank->context.wake_en &= ~gpio_bit;
|
|
|
|
|
|
writel_relaxed(bank->context.wake_en, bank->base + bank->regs->wkup_en);
|
|
writel_relaxed(bank->context.wake_en, bank->base + bank->regs->wkup_en);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -669,10 +670,10 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
|
|
if (!BANK_USED(bank))
|
|
if (!BANK_USED(bank))
|
|
pm_runtime_get_sync(bank->dev);
|
|
pm_runtime_get_sync(bank->dev);
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
omap_enable_gpio_module(bank, offset);
|
|
omap_enable_gpio_module(bank, offset);
|
|
bank->mod_usage |= BIT(offset);
|
|
bank->mod_usage |= BIT(offset);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -682,14 +683,14 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
|
|
struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
|
|
struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
bank->mod_usage &= ~(BIT(offset));
|
|
bank->mod_usage &= ~(BIT(offset));
|
|
if (!LINE_USED(bank->irq_usage, offset)) {
|
|
if (!LINE_USED(bank->irq_usage, offset)) {
|
|
omap_set_gpio_direction(bank, offset, 1);
|
|
omap_set_gpio_direction(bank, offset, 1);
|
|
omap_clear_gpio_debounce(bank, offset);
|
|
omap_clear_gpio_debounce(bank, offset);
|
|
}
|
|
}
|
|
omap_disable_gpio_module(bank, offset);
|
|
omap_disable_gpio_module(bank, offset);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
/*
|
|
/*
|
|
* If this is the last gpio to be freed in the bank,
|
|
* If this is the last gpio to be freed in the bank,
|
|
@@ -716,7 +717,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
struct gpio_bank *bank;
|
|
struct gpio_bank *bank;
|
|
int unmasked = 0;
|
|
int unmasked = 0;
|
|
struct irq_chip *irqchip = irq_desc_get_chip(desc);
|
|
struct irq_chip *irqchip = irq_desc_get_chip(desc);
|
|
- struct gpio_chip *chip = irq_get_handler_data(irq);
|
|
|
|
|
|
+ struct gpio_chip *chip = irq_desc_get_handler_data(desc);
|
|
|
|
+ unsigned long lock_flags;
|
|
|
|
|
|
chained_irq_enter(irqchip, desc);
|
|
chained_irq_enter(irqchip, desc);
|
|
|
|
|
|
@@ -731,6 +733,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
u32 isr_saved, level_mask = 0;
|
|
u32 isr_saved, level_mask = 0;
|
|
u32 enabled;
|
|
u32 enabled;
|
|
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, lock_flags);
|
|
|
|
+
|
|
enabled = omap_get_gpio_irqbank_mask(bank);
|
|
enabled = omap_get_gpio_irqbank_mask(bank);
|
|
isr_saved = isr = readl_relaxed(isr_reg) & enabled;
|
|
isr_saved = isr = readl_relaxed(isr_reg) & enabled;
|
|
|
|
|
|
@@ -744,6 +748,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
|
|
omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
|
|
omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask);
|
|
omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask);
|
|
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
|
|
|
|
+
|
|
/* if there is only edge sensitive GPIO pin interrupts
|
|
/* if there is only edge sensitive GPIO pin interrupts
|
|
configured, we could unmask GPIO bank interrupt immediately */
|
|
configured, we could unmask GPIO bank interrupt immediately */
|
|
if (!level_mask && !unmasked) {
|
|
if (!level_mask && !unmasked) {
|
|
@@ -758,6 +764,7 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
bit = __ffs(isr);
|
|
bit = __ffs(isr);
|
|
isr &= ~(BIT(bit));
|
|
isr &= ~(BIT(bit));
|
|
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, lock_flags);
|
|
/*
|
|
/*
|
|
* Some chips can't respond to both rising and falling
|
|
* Some chips can't respond to both rising and falling
|
|
* at the same time. If this irq was requested with
|
|
* at the same time. If this irq was requested with
|
|
@@ -768,6 +775,8 @@ static void omap_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|
if (bank->toggle_mask & (BIT(bit)))
|
|
if (bank->toggle_mask & (BIT(bit)))
|
|
omap_toggle_gpio_edge_triggering(bank, bit);
|
|
omap_toggle_gpio_edge_triggering(bank, bit);
|
|
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, lock_flags);
|
|
|
|
+
|
|
generic_handle_irq(irq_find_mapping(bank->chip.irqdomain,
|
|
generic_handle_irq(irq_find_mapping(bank->chip.irqdomain,
|
|
bit));
|
|
bit));
|
|
}
|
|
}
|
|
@@ -791,7 +800,7 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d)
|
|
if (!BANK_USED(bank))
|
|
if (!BANK_USED(bank))
|
|
pm_runtime_get_sync(bank->dev);
|
|
pm_runtime_get_sync(bank->dev);
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
if (!LINE_USED(bank->mod_usage, offset))
|
|
if (!LINE_USED(bank->mod_usage, offset))
|
|
omap_set_gpio_direction(bank, offset, 1);
|
|
omap_set_gpio_direction(bank, offset, 1);
|
|
@@ -800,12 +809,12 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d)
|
|
omap_enable_gpio_module(bank, offset);
|
|
omap_enable_gpio_module(bank, offset);
|
|
bank->irq_usage |= BIT(offset);
|
|
bank->irq_usage |= BIT(offset);
|
|
|
|
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
omap_gpio_unmask_irq(d);
|
|
omap_gpio_unmask_irq(d);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
err:
|
|
err:
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
if (!BANK_USED(bank))
|
|
if (!BANK_USED(bank))
|
|
pm_runtime_put(bank->dev);
|
|
pm_runtime_put(bank->dev);
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -817,7 +826,7 @@ static void omap_gpio_irq_shutdown(struct irq_data *d)
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
unsigned offset = d->hwirq;
|
|
unsigned offset = d->hwirq;
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
bank->irq_usage &= ~(BIT(offset));
|
|
bank->irq_usage &= ~(BIT(offset));
|
|
omap_set_gpio_irqenable(bank, offset, 0);
|
|
omap_set_gpio_irqenable(bank, offset, 0);
|
|
omap_clear_gpio_irqstatus(bank, offset);
|
|
omap_clear_gpio_irqstatus(bank, offset);
|
|
@@ -825,7 +834,7 @@ static void omap_gpio_irq_shutdown(struct irq_data *d)
|
|
if (!LINE_USED(bank->mod_usage, offset))
|
|
if (!LINE_USED(bank->mod_usage, offset))
|
|
omap_clear_gpio_debounce(bank, offset);
|
|
omap_clear_gpio_debounce(bank, offset);
|
|
omap_disable_gpio_module(bank, offset);
|
|
omap_disable_gpio_module(bank, offset);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
/*
|
|
/*
|
|
* If this is the last IRQ to be freed in the bank,
|
|
* If this is the last IRQ to be freed in the bank,
|
|
@@ -849,10 +858,10 @@ static void omap_gpio_mask_irq(struct irq_data *d)
|
|
unsigned offset = d->hwirq;
|
|
unsigned offset = d->hwirq;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
omap_set_gpio_irqenable(bank, offset, 0);
|
|
omap_set_gpio_irqenable(bank, offset, 0);
|
|
omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
|
omap_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
static void omap_gpio_unmask_irq(struct irq_data *d)
|
|
static void omap_gpio_unmask_irq(struct irq_data *d)
|
|
@@ -862,7 +871,7 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
|
u32 trigger = irqd_get_trigger_type(d);
|
|
u32 trigger = irqd_get_trigger_type(d);
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
if (trigger)
|
|
if (trigger)
|
|
omap_set_gpio_triggering(bank, offset, trigger);
|
|
omap_set_gpio_triggering(bank, offset, trigger);
|
|
|
|
|
|
@@ -874,7 +883,7 @@ static void omap_gpio_unmask_irq(struct irq_data *d)
|
|
}
|
|
}
|
|
|
|
|
|
omap_set_gpio_irqenable(bank, offset, 1);
|
|
omap_set_gpio_irqenable(bank, offset, 1);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/*---------------------------------------------------------------------*/
|
|
@@ -887,9 +896,9 @@ static int omap_mpuio_suspend_noirq(struct device *dev)
|
|
OMAP_MPUIO_GPIO_MASKIT / bank->stride;
|
|
OMAP_MPUIO_GPIO_MASKIT / bank->stride;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
writel_relaxed(0xffff & ~bank->context.wake_en, mask_reg);
|
|
writel_relaxed(0xffff & ~bank->context.wake_en, mask_reg);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -902,9 +911,9 @@ static int omap_mpuio_resume_noirq(struct device *dev)
|
|
OMAP_MPUIO_GPIO_MASKIT / bank->stride;
|
|
OMAP_MPUIO_GPIO_MASKIT / bank->stride;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
writel_relaxed(bank->context.wake_en, mask_reg);
|
|
writel_relaxed(bank->context.wake_en, mask_reg);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -950,9 +959,9 @@ static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
|
|
|
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
reg = bank->base + bank->regs->direction;
|
|
reg = bank->base + bank->regs->direction;
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
dir = !!(readl_relaxed(reg) & BIT(offset));
|
|
dir = !!(readl_relaxed(reg) & BIT(offset));
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
return dir;
|
|
return dir;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -962,9 +971,9 @@ static int omap_gpio_input(struct gpio_chip *chip, unsigned offset)
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
omap_set_gpio_direction(bank, offset, 1);
|
|
omap_set_gpio_direction(bank, offset, 1);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -986,10 +995,10 @@ static int omap_gpio_output(struct gpio_chip *chip, unsigned offset, int value)
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
bank->set_dataout(bank, offset, value);
|
|
bank->set_dataout(bank, offset, value);
|
|
omap_set_gpio_direction(bank, offset, 0);
|
|
omap_set_gpio_direction(bank, offset, 0);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1001,9 +1010,9 @@ static int omap_gpio_debounce(struct gpio_chip *chip, unsigned offset,
|
|
|
|
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
omap2_set_gpio_debounce(bank, offset, debounce);
|
|
omap2_set_gpio_debounce(bank, offset, debounce);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1014,9 +1023,9 @@ static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
bank = container_of(chip, struct gpio_bank, chip);
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
bank->set_dataout(bank, offset, value);
|
|
bank->set_dataout(bank, offset, value);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
/*---------------------------------------------------------------------*/
|
|
@@ -1061,10 +1070,6 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
|
|
/* Initialize interface clk ungated, module enabled */
|
|
/* Initialize interface clk ungated, module enabled */
|
|
if (bank->regs->ctrl)
|
|
if (bank->regs->ctrl)
|
|
writel_relaxed(0, base + bank->regs->ctrl);
|
|
writel_relaxed(0, base + bank->regs->ctrl);
|
|
-
|
|
|
|
- bank->dbck = clk_get(bank->dev, "dbclk");
|
|
|
|
- if (IS_ERR(bank->dbck))
|
|
|
|
- dev_err(bank->dev, "Could not get gpio dbck\n");
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
|
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
|
@@ -1178,13 +1183,16 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|
irqc->irq_set_wake = omap_gpio_wake_enable,
|
|
irqc->irq_set_wake = omap_gpio_wake_enable,
|
|
irqc->name = dev_name(&pdev->dev);
|
|
irqc->name = dev_name(&pdev->dev);
|
|
|
|
|
|
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
|
|
|
- if (unlikely(!res)) {
|
|
|
|
- dev_err(dev, "Invalid IRQ resource\n");
|
|
|
|
- return -ENODEV;
|
|
|
|
|
|
+ bank->irq = platform_get_irq(pdev, 0);
|
|
|
|
+ if (bank->irq <= 0) {
|
|
|
|
+ if (!bank->irq)
|
|
|
|
+ bank->irq = -ENXIO;
|
|
|
|
+ if (bank->irq != -EPROBE_DEFER)
|
|
|
|
+ dev_err(dev,
|
|
|
|
+ "can't get irq resource ret=%d\n", bank->irq);
|
|
|
|
+ return bank->irq;
|
|
}
|
|
}
|
|
|
|
|
|
- bank->irq = res->start;
|
|
|
|
bank->dev = dev;
|
|
bank->dev = dev;
|
|
bank->chip.dev = dev;
|
|
bank->chip.dev = dev;
|
|
bank->chip.owner = THIS_MODULE;
|
|
bank->chip.owner = THIS_MODULE;
|
|
@@ -1213,16 +1221,26 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|
else
|
|
else
|
|
bank->set_dataout = omap_set_gpio_dataout_mask;
|
|
bank->set_dataout = omap_set_gpio_dataout_mask;
|
|
|
|
|
|
- spin_lock_init(&bank->lock);
|
|
|
|
|
|
+ raw_spin_lock_init(&bank->lock);
|
|
|
|
|
|
/* Static mapping, never released */
|
|
/* Static mapping, never released */
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
bank->base = devm_ioremap_resource(dev, res);
|
|
bank->base = devm_ioremap_resource(dev, res);
|
|
if (IS_ERR(bank->base)) {
|
|
if (IS_ERR(bank->base)) {
|
|
- irq_domain_remove(bank->chip.irqdomain);
|
|
|
|
return PTR_ERR(bank->base);
|
|
return PTR_ERR(bank->base);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (bank->dbck_flag) {
|
|
|
|
+ bank->dbck = devm_clk_get(bank->dev, "dbclk");
|
|
|
|
+ if (IS_ERR(bank->dbck)) {
|
|
|
|
+ dev_err(bank->dev,
|
|
|
|
+ "Could not get gpio dbck. Disable debounce\n");
|
|
|
|
+ bank->dbck_flag = false;
|
|
|
|
+ } else {
|
|
|
|
+ clk_prepare(bank->dbck);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
platform_set_drvdata(pdev, bank);
|
|
platform_set_drvdata(pdev, bank);
|
|
|
|
|
|
pm_runtime_enable(bank->dev);
|
|
pm_runtime_enable(bank->dev);
|
|
@@ -1254,6 +1272,8 @@ static int omap_gpio_remove(struct platform_device *pdev)
|
|
list_del(&bank->node);
|
|
list_del(&bank->node);
|
|
gpiochip_remove(&bank->chip);
|
|
gpiochip_remove(&bank->chip);
|
|
pm_runtime_disable(bank->dev);
|
|
pm_runtime_disable(bank->dev);
|
|
|
|
+ if (bank->dbck_flag)
|
|
|
|
+ clk_unprepare(bank->dbck);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1271,7 +1291,7 @@ static int omap_gpio_runtime_suspend(struct device *dev)
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
u32 wake_low, wake_hi;
|
|
u32 wake_low, wake_hi;
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Only edges can generate a wakeup event to the PRCM.
|
|
* Only edges can generate a wakeup event to the PRCM.
|
|
@@ -1324,7 +1344,7 @@ update_gpio_context_count:
|
|
bank->get_context_loss_count(bank->dev);
|
|
bank->get_context_loss_count(bank->dev);
|
|
|
|
|
|
omap_gpio_dbck_disable(bank);
|
|
omap_gpio_dbck_disable(bank);
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1339,7 +1359,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
int c;
|
|
int c;
|
|
|
|
|
|
- spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_lock_irqsave(&bank->lock, flags);
|
|
|
|
|
|
/*
|
|
/*
|
|
* On the first resume during the probe, the context has not
|
|
* On the first resume during the probe, the context has not
|
|
@@ -1375,14 +1395,14 @@ static int omap_gpio_runtime_resume(struct device *dev)
|
|
if (c != bank->context_loss_count) {
|
|
if (c != bank->context_loss_count) {
|
|
omap_gpio_restore_context(bank);
|
|
omap_gpio_restore_context(bank);
|
|
} else {
|
|
} else {
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (!bank->workaround_enabled) {
|
|
if (!bank->workaround_enabled) {
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1437,7 +1457,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
|
|
}
|
|
}
|
|
|
|
|
|
bank->workaround_enabled = false;
|
|
bank->workaround_enabled = false;
|
|
- spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
+ raw_spin_unlock_irqrestore(&bank->lock, flags);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|