[ARM] 5591/1: Add group irq enable/disable for w90p910 platform.
Add group irq enable/disable for w90p910 platform. Signed-off-by: Wan ZongShun <mcuos.com@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
28d0325ce6
commit
19c0a7286f
|
@ -10,8 +10,7 @@
|
|||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* the Free Software Foundation;version 2 of the License.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -29,9 +28,114 @@
|
|||
#include <mach/hardware.h>
|
||||
#include <mach/regs-irq.h>
|
||||
|
||||
struct group_irq {
|
||||
unsigned long gpen;
|
||||
unsigned int enabled;
|
||||
void (*enable)(struct group_irq *, int enable);
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(groupirq_lock);
|
||||
|
||||
#define DEFINE_GROUP(_name, _ctrlbit, _num) \
|
||||
struct group_irq group_##_name = { \
|
||||
.enable = w90x900_group_enable, \
|
||||
.gpen = ((2 ^ _num) - 1) << _ctrlbit, \
|
||||
}
|
||||
|
||||
static void w90x900_group_enable(struct group_irq *gpirq, int enable);
|
||||
|
||||
static DEFINE_GROUP(nirq0, 0, 4);
|
||||
static DEFINE_GROUP(nirq1, 4, 4);
|
||||
static DEFINE_GROUP(usbh, 8, 2);
|
||||
static DEFINE_GROUP(ottimer, 16, 3);
|
||||
static DEFINE_GROUP(gdma, 20, 2);
|
||||
static DEFINE_GROUP(sc, 24, 2);
|
||||
static DEFINE_GROUP(i2c, 26, 2);
|
||||
static DEFINE_GROUP(ps2, 28, 2);
|
||||
|
||||
static int group_irq_enable(struct group_irq *group_irq)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&groupirq_lock, flags);
|
||||
if (group_irq->enabled++ == 0)
|
||||
(group_irq->enable)(group_irq, 1);
|
||||
spin_unlock_irqrestore(&groupirq_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void group_irq_disable(struct group_irq *group_irq)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
WARN_ON(group_irq->enabled == 0);
|
||||
|
||||
spin_lock_irqsave(&groupirq_lock, flags);
|
||||
if (--group_irq->enabled == 0)
|
||||
(group_irq->enable)(group_irq, 0);
|
||||
spin_unlock_irqrestore(&groupirq_lock, flags);
|
||||
}
|
||||
|
||||
static void w90x900_group_enable(struct group_irq *gpirq, int enable)
|
||||
{
|
||||
unsigned int groupen = gpirq->gpen;
|
||||
unsigned long regval;
|
||||
|
||||
regval = __raw_readl(REG_AIC_GEN);
|
||||
|
||||
if (enable)
|
||||
regval |= groupen;
|
||||
else
|
||||
regval &= ~groupen;
|
||||
|
||||
__raw_writel(regval, REG_AIC_GEN);
|
||||
}
|
||||
|
||||
static void w90x900_irq_mask(unsigned int irq)
|
||||
{
|
||||
struct group_irq *group_irq;
|
||||
|
||||
group_irq = NULL;
|
||||
|
||||
__raw_writel(1 << irq, REG_AIC_MDCR);
|
||||
|
||||
switch (irq) {
|
||||
case IRQ_GROUP0:
|
||||
group_irq = &group_nirq0;
|
||||
break;
|
||||
|
||||
case IRQ_GROUP1:
|
||||
group_irq = &group_nirq1;
|
||||
break;
|
||||
|
||||
case IRQ_USBH:
|
||||
group_irq = &group_usbh;
|
||||
break;
|
||||
|
||||
case IRQ_T_INT_GROUP:
|
||||
group_irq = &group_ottimer;
|
||||
break;
|
||||
|
||||
case IRQ_GDMAGROUP:
|
||||
group_irq = &group_gdma;
|
||||
break;
|
||||
|
||||
case IRQ_SCGROUP:
|
||||
group_irq = &group_sc;
|
||||
break;
|
||||
|
||||
case IRQ_I2CGROUP:
|
||||
group_irq = &group_i2c;
|
||||
break;
|
||||
|
||||
case IRQ_P2SGROUP:
|
||||
group_irq = &group_ps2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (group_irq)
|
||||
group_irq_disable(group_irq);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -46,14 +150,48 @@ static void w90x900_irq_ack(unsigned int irq)
|
|||
|
||||
static void w90x900_irq_unmask(unsigned int irq)
|
||||
{
|
||||
unsigned long mask;
|
||||
struct group_irq *group_irq;
|
||||
|
||||
group_irq = NULL;
|
||||
|
||||
if (irq == IRQ_T_INT_GROUP) {
|
||||
mask = __raw_readl(REG_AIC_GEN);
|
||||
__raw_writel(TIME_GROUP_IRQ | mask, REG_AIC_GEN);
|
||||
__raw_writel(1 << IRQ_T_INT_GROUP, REG_AIC_MECR);
|
||||
}
|
||||
__raw_writel(1 << irq, REG_AIC_MECR);
|
||||
|
||||
switch (irq) {
|
||||
case IRQ_GROUP0:
|
||||
group_irq = &group_nirq0;
|
||||
break;
|
||||
|
||||
case IRQ_GROUP1:
|
||||
group_irq = &group_nirq1;
|
||||
break;
|
||||
|
||||
case IRQ_USBH:
|
||||
group_irq = &group_usbh;
|
||||
break;
|
||||
|
||||
case IRQ_T_INT_GROUP:
|
||||
group_irq = &group_ottimer;
|
||||
break;
|
||||
|
||||
case IRQ_GDMAGROUP:
|
||||
group_irq = &group_gdma;
|
||||
break;
|
||||
|
||||
case IRQ_SCGROUP:
|
||||
group_irq = &group_sc;
|
||||
break;
|
||||
|
||||
case IRQ_I2CGROUP:
|
||||
group_irq = &group_i2c;
|
||||
break;
|
||||
|
||||
case IRQ_P2SGROUP:
|
||||
group_irq = &group_ps2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (group_irq)
|
||||
group_irq_enable(group_irq);
|
||||
}
|
||||
|
||||
static struct irq_chip w90x900_irq_chip = {
|
||||
|
|
Loading…
Reference in a new issue