Commit 1eb058b8 authored by  David Brownell's avatar David Brownell Committed by Tony Lindgren

[PATCH] ARM: OMAP: support set_irq_type()

This updates IRQ triggering code to be a closer match for other ARMs:
 - Adds support for the standard ARM-Linux set_irq_type() call.
 - Reports errors on unsupported triggering modes (e.g. nothing except
   16xx GPIOs can trigger on both edges) and on bogus wakeup requests.
 - Deprecates the OMAP-only omap_set_gpio_edge_ctrl() call.
 - Removes many of the "sparse" warnings from the GPIO code.
 - Modifies the smc91x driver so it knows which OMAP boards use falling
   edge triggers (vs rising, like everything else).
Later patches can remove the deprecation warnings and then the OMAP-only
version of that standard call.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 3b40dee9
...@@ -220,12 +220,12 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) ...@@ -220,12 +220,12 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
reg += OMAP730_GPIO_DIR_CONTROL; reg += OMAP730_GPIO_DIR_CONTROL;
break; break;
} }
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (is_input) if (is_input)
l |= 1 << gpio; l |= 1 << gpio;
else else
l &= ~(1 << gpio); l &= ~(1 << gpio);
__raw_writel(l, reg); __raw_writel(l, (void __iomem *)reg);
} }
void omap_set_gpio_direction(int gpio, int is_input) void omap_set_gpio_direction(int gpio, int is_input)
...@@ -248,7 +248,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) ...@@ -248,7 +248,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
switch (bank->method) { switch (bank->method) {
case METHOD_MPUIO: case METHOD_MPUIO:
reg += OMAP_MPUIO_OUTPUT; reg += OMAP_MPUIO_OUTPUT;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (enable) if (enable)
l |= 1 << gpio; l |= 1 << gpio;
else else
...@@ -256,7 +256,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) ...@@ -256,7 +256,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
break; break;
case METHOD_GPIO_1510: case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_DATA_OUTPUT; reg += OMAP1510_GPIO_DATA_OUTPUT;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (enable) if (enable)
l |= 1 << gpio; l |= 1 << gpio;
else else
...@@ -271,7 +271,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) ...@@ -271,7 +271,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
break; break;
case METHOD_GPIO_730: case METHOD_GPIO_730:
reg += OMAP730_GPIO_DATA_OUTPUT; reg += OMAP730_GPIO_DATA_OUTPUT;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (enable) if (enable)
l |= 1 << gpio; l |= 1 << gpio;
else else
...@@ -281,7 +281,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) ...@@ -281,7 +281,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
BUG(); BUG();
return; return;
} }
__raw_writel(l, reg); __raw_writel(l, (void __iomem *)reg);
} }
void omap_set_gpio_dataout(int gpio, int enable) void omap_set_gpio_dataout(int gpio, int enable)
...@@ -322,10 +322,11 @@ int omap_get_gpio_datain(int gpio) ...@@ -322,10 +322,11 @@ int omap_get_gpio_datain(int gpio)
BUG(); BUG();
return -1; return -1;
} }
return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; return (__raw_readl((void __iomem *)reg)
& (1 << get_gpio_index(gpio))) != 0;
} }
static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge) static int _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
{ {
u32 reg = bank->base; u32 reg = bank->base;
u32 l; u32 l;
...@@ -333,21 +334,23 @@ static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge) ...@@ -333,21 +334,23 @@ static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
switch (bank->method) { switch (bank->method) {
case METHOD_MPUIO: case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_INT_EDGE; reg += OMAP_MPUIO_GPIO_INT_EDGE;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (edge == OMAP_GPIO_RISING_EDGE) if (edge == OMAP_GPIO_RISING_EDGE)
l |= 1 << gpio; l |= 1 << gpio;
else else if (edge == OMAP_GPIO_FALLING_EDGE)
l &= ~(1 << gpio); l &= ~(1 << gpio);
__raw_writel(l, reg); else
goto bad;
break; break;
case METHOD_GPIO_1510: case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_CONTROL; reg += OMAP1510_GPIO_INT_CONTROL;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (edge == OMAP_GPIO_RISING_EDGE) if (edge == OMAP_GPIO_RISING_EDGE)
l |= 1 << gpio; l |= 1 << gpio;
else else if (edge == OMAP_GPIO_FALLING_EDGE)
l &= ~(1 << gpio); l &= ~(1 << gpio);
__raw_writel(l, reg); else
goto bad;
break; break;
case METHOD_GPIO_1610: case METHOD_GPIO_1610:
edge &= 0x03; edge &= 0x03;
...@@ -356,24 +359,55 @@ static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge) ...@@ -356,24 +359,55 @@ static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
else else
reg += OMAP1610_GPIO_EDGE_CTRL1; reg += OMAP1610_GPIO_EDGE_CTRL1;
gpio &= 0x07; gpio &= 0x07;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
l &= ~(3 << (gpio << 1)); l &= ~(3 << (gpio << 1));
l |= edge << (gpio << 1); l |= edge << (gpio << 1);
__raw_writel(l, reg);
break; break;
case METHOD_GPIO_730: case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_CONTROL; reg += OMAP730_GPIO_INT_CONTROL;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (edge == OMAP_GPIO_RISING_EDGE) if (edge == OMAP_GPIO_RISING_EDGE)
l |= 1 << gpio; l |= 1 << gpio;
else else if (edge == OMAP_GPIO_FALLING_EDGE)
l &= ~(1 << gpio); l &= ~(1 << gpio);
__raw_writel(l, reg); else
goto bad;
break; break;
default: default:
BUG(); BUG();
return; goto bad;
} }
__raw_writel(l, (void __iomem *)reg);
return 0;
bad:
return -EINVAL;
}
static int gpio_irq_type(unsigned irq, unsigned type)
{
struct gpio_bank *bank;
unsigned gpio;
int retval;
if (irq > IH_MPUIO_BASE)
gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
else
gpio = irq - IH_GPIO_BASE;
if (check_gpio(gpio) < 0)
return -EINVAL;
/* NOTE: __IRQT_FALEDGE == OMAP_GPIO_FALLING_EDGE,
* and __IRQT_RISEDGE == OMAP_GPIO_RISING_EDGE
*/
if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE))
return -EINVAL;
bank = get_gpio_bank(gpio);
spin_lock(&bank->lock);
retval = _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), type);
spin_unlock(&bank->lock);
return retval;
} }
void omap_set_gpio_edge_ctrl(int gpio, int edge) void omap_set_gpio_edge_ctrl(int gpio, int edge)
...@@ -440,7 +474,7 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) ...@@ -440,7 +474,7 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
BUG(); BUG();
return; return;
} }
__raw_writel(gpio_mask, reg); __raw_writel(gpio_mask, (void __iomem *)reg);
} }
static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
...@@ -456,7 +490,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab ...@@ -456,7 +490,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
switch (bank->method) { switch (bank->method) {
case METHOD_MPUIO: case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_MASKIT; reg += OMAP_MPUIO_GPIO_MASKIT;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (enable) if (enable)
l &= ~(gpio_mask); l &= ~(gpio_mask);
else else
...@@ -464,7 +498,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab ...@@ -464,7 +498,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
break; break;
case METHOD_GPIO_1510: case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_MASK; reg += OMAP1510_GPIO_INT_MASK;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (enable) if (enable)
l &= ~(gpio_mask); l &= ~(gpio_mask);
else else
...@@ -479,7 +513,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab ...@@ -479,7 +513,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
break; break;
case METHOD_GPIO_730: case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_MASK; reg += OMAP730_GPIO_INT_MASK;
l = __raw_readl(reg); l = __raw_readl((void __iomem *)reg);
if (enable) if (enable)
l &= ~(gpio_mask); l &= ~(gpio_mask);
else else
...@@ -489,7 +523,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab ...@@ -489,7 +523,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
BUG(); BUG();
return; return;
} }
__raw_writel(l, reg); __raw_writel(l, (void __iomem *)reg);
} }
static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
...@@ -505,7 +539,7 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena ...@@ -505,7 +539,7 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena
* enabled. When system is suspended, only selected GPIO interrupts need * enabled. When system is suspended, only selected GPIO interrupts need
* to have wake-up enabled. * to have wake-up enabled.
*/ */
static void _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
{ {
switch (bank->method) { switch (bank->method) {
case METHOD_GPIO_1610: case METHOD_GPIO_1610:
...@@ -515,11 +549,11 @@ static void _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) ...@@ -515,11 +549,11 @@ static void _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
else else
bank->suspend_wakeup &= ~(1 << gpio); bank->suspend_wakeup &= ~(1 << gpio);
spin_unlock(&bank->lock); spin_unlock(&bank->lock);
break; return 0;
default: default:
printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n", printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
bank->method); bank->method);
return; return -EINVAL;
} }
} }
...@@ -528,15 +562,16 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) ...@@ -528,15 +562,16 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable)
{ {
unsigned int gpio = irq - IH_GPIO_BASE; unsigned int gpio = irq - IH_GPIO_BASE;
struct gpio_bank *bank; struct gpio_bank *bank;
int retval;
if (check_gpio(gpio) < 0) if (check_gpio(gpio) < 0)
return -ENODEV; return -ENODEV;
bank = get_gpio_bank(gpio); bank = get_gpio_bank(gpio);
spin_lock(&bank->lock); spin_lock(&bank->lock);
_set_gpio_wakeup(bank, get_gpio_index(gpio), enable); retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
spin_unlock(&bank->lock); spin_unlock(&bank->lock);
return 0; return retval;
} }
int omap_request_gpio(int gpio) int omap_request_gpio(int gpio)
...@@ -568,7 +603,7 @@ int omap_request_gpio(int gpio) ...@@ -568,7 +603,7 @@ int omap_request_gpio(int gpio)
if (bank->method == METHOD_GPIO_1610) { if (bank->method == METHOD_GPIO_1610) {
/* Enable wake-up during idle for dynamic tick */ /* Enable wake-up during idle for dynamic tick */
u32 reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; u32 reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
__raw_writel(1 << get_gpio_index(gpio), reg); __raw_writel(1 << get_gpio_index(gpio), (void __iomem *)reg);
} }
#endif #endif
spin_unlock(&bank->lock); spin_unlock(&bank->lock);
...@@ -594,7 +629,7 @@ void omap_free_gpio(int gpio) ...@@ -594,7 +629,7 @@ void omap_free_gpio(int gpio)
if (bank->method == METHOD_GPIO_1610) { if (bank->method == METHOD_GPIO_1610) {
/* Disable wake-up during idle for dynamic tick */ /* Disable wake-up during idle for dynamic tick */
u32 reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; u32 reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
__raw_writel(1 << get_gpio_index(gpio), reg); __raw_writel(1 << get_gpio_index(gpio), (void __iomem *)reg);
} }
#endif #endif
bank->reserved_map &= ~(1 << get_gpio_index(gpio)); bank->reserved_map &= ~(1 << get_gpio_index(gpio));
...@@ -639,7 +674,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, ...@@ -639,7 +674,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
isr_reg = bank->base + OMAP730_GPIO_INT_STATUS; isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
#endif #endif
isr = __raw_readl(isr_reg); isr = __raw_readl((void __iomem *)isr_reg);
_enable_gpio_irqbank(bank, isr, 0); _enable_gpio_irqbank(bank, isr, 0);
_clear_gpio_irqbank(bank, isr); _clear_gpio_irqbank(bank, isr);
_enable_gpio_irqbank(bank, isr, 1); _enable_gpio_irqbank(bank, isr, 1);
...@@ -712,6 +747,7 @@ static struct irqchip gpio_irq_chip = { ...@@ -712,6 +747,7 @@ static struct irqchip gpio_irq_chip = {
.ack = gpio_ack_irq, .ack = gpio_ack_irq,
.mask = gpio_mask_irq, .mask = gpio_mask_irq,
.unmask = gpio_unmask_irq, .unmask = gpio_unmask_irq,
.type = gpio_irq_type,
.wake = gpio_wake_enable, .wake = gpio_wake_enable,
}; };
...@@ -817,7 +853,7 @@ static int __init _omap_gpio_init(void) ...@@ -817,7 +853,7 @@ static int __init _omap_gpio_init(void)
} }
#ifdef CONFIG_ARCH_OMAP16XX #ifdef CONFIG_ARCH_OMAP16XX
static int omap_gpio_suspend(struct sys_device *dev, u32 state) static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
{ {
int i; int i;
......
...@@ -1990,7 +1990,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) ...@@ -1990,7 +1990,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
if (retval) if (retval)
goto err_out; goto err_out;
set_irq_type(dev->irq, IRQT_RISING); set_irq_type(dev->irq, IRQ_TRIGGER_TYPE);
#ifdef SMC_USE_PXA_DMA #ifdef SMC_USE_PXA_DMA
{ {
......
...@@ -182,6 +182,16 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg) ...@@ -182,6 +182,16 @@ SMC_outw(u16 val, unsigned long ioaddr, int reg)
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
#include <asm/mach-types.h>
#include <asm/arch/cpu.h>
#define IRQ_TRIGGER_TYPE (( \
machine_is_omap_h2() \
|| machine_is_omap_h3() \
|| (machine_is_omap_innovator() && !cpu_is_omap150()) \
) ? IRQT_FALLING : IRQT_RISING)
#elif defined(CONFIG_SH_SH4202_MICRODEV) #elif defined(CONFIG_SH_SH4202_MICRODEV)
#define SMC_CAN_USE_8BIT 0 #define SMC_CAN_USE_8BIT 0
...@@ -300,6 +310,9 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) ...@@ -300,6 +310,9 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
#endif #endif
#ifndef IRQ_TRIGGER_TYPE
#define IRQ_TRIGGER_TYPE IRQT_RISING
#endif
#ifdef SMC_USE_PXA_DMA #ifdef SMC_USE_PXA_DMA
/* /*
......
...@@ -64,6 +64,8 @@ extern void omap_free_gpio(int gpio); ...@@ -64,6 +64,8 @@ extern void omap_free_gpio(int gpio);
extern void omap_set_gpio_direction(int gpio, int is_input); extern void omap_set_gpio_direction(int gpio, int is_input);
extern void omap_set_gpio_dataout(int gpio, int enable); extern void omap_set_gpio_dataout(int gpio, int enable);
extern int omap_get_gpio_datain(int gpio); extern int omap_get_gpio_datain(int gpio);
extern void omap_set_gpio_edge_ctrl(int gpio, int edge);
/* use ARM-standard set_irq_type() instead */
extern void __deprecated omap_set_gpio_edge_ctrl(int gpio, int edge);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment