[ARM] pxa: integrate low IRQ chip (ICIP) and high IRQ chip (ICIP2) into one
This makes the code better organized and simplified a bit. The change will lose a bit of performance when performing IRQ ack/mask/unmask,but that's not too much after checking the result binary. This patch also removes the ugly #ifdef CONFIG_PXA27x .. #endif by carefully not to access those pxa{27x,3xx} specific registers, this is done by keeping an internal IRQ number variable. The pxa-regs.h is also modified so registers for IRQ > PXA_IRQ(31) are made public even if CONFIG_PXA{27x,3xx} isn't defined (for pxa25x's sake) The incorrect assumption in the original code that internal irq starts from 0 is also corrected by comparing with PXA_IRQ(0). "struct sys_device" for the IRQ are reduced into one single device on pxa{27x,3xx}. Signed-off-by: eric miao <eric.miao@marvell.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
e3630db1fa
commit
f6fb7af476
@ -12,8 +12,7 @@
|
|||||||
struct sys_timer;
|
struct sys_timer;
|
||||||
|
|
||||||
extern struct sys_timer pxa_timer;
|
extern struct sys_timer pxa_timer;
|
||||||
extern void __init pxa_init_irq_low(void);
|
extern void __init pxa_init_irq(int irq_nr);
|
||||||
extern void __init pxa_init_irq_high(void);
|
|
||||||
extern void __init pxa_init_irq_gpio(int gpio_nr);
|
extern void __init pxa_init_irq_gpio(int gpio_nr);
|
||||||
extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
|
extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
|
||||||
extern void __init pxa_init_gpio_set_wake(int (*set_wake)(unsigned int, unsigned int));
|
extern void __init pxa_init_gpio_set_wake(int (*set_wake)(unsigned int, unsigned int));
|
||||||
|
@ -24,92 +24,57 @@
|
|||||||
|
|
||||||
#include "generic.h"
|
#include "generic.h"
|
||||||
|
|
||||||
|
#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
|
||||||
|
#define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
|
||||||
|
#define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is for peripheral IRQs internal to the PXA chip.
|
* This is for peripheral IRQs internal to the PXA chip.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void pxa_mask_low_irq(unsigned int irq)
|
static int pxa_internal_irq_nr;
|
||||||
|
|
||||||
|
static void pxa_mask_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
ICMR &= ~(1 << irq);
|
_ICMR(irq) &= ~(1 << IRQ_BIT(irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pxa_unmask_low_irq(unsigned int irq)
|
static void pxa_unmask_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
ICMR |= (1 << irq);
|
_ICMR(irq) |= 1 << IRQ_BIT(irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct irq_chip pxa_internal_chip_low = {
|
static struct irq_chip pxa_internal_irq_chip = {
|
||||||
.name = "SC",
|
.name = "SC",
|
||||||
.ack = pxa_mask_low_irq,
|
.ack = pxa_mask_irq,
|
||||||
.mask = pxa_mask_low_irq,
|
.mask = pxa_mask_irq,
|
||||||
.unmask = pxa_unmask_low_irq,
|
.unmask = pxa_unmask_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init pxa_init_irq_low(void)
|
void __init pxa_init_irq(int irq_nr)
|
||||||
{
|
{
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
/* disable all IRQs */
|
pxa_internal_irq_nr = irq_nr;
|
||||||
ICMR = 0;
|
|
||||||
|
|
||||||
/* all IRQs are IRQ, not FIQ */
|
for (irq = 0; irq < irq_nr; irq += 32) {
|
||||||
ICLR = 0;
|
_ICMR(irq) = 0; /* disable all IRQs */
|
||||||
|
_ICLR(irq) = 0; /* all IRQs are IRQ, not FIQ */
|
||||||
|
}
|
||||||
|
|
||||||
/* only unmasked interrupts kick us out of idle */
|
/* only unmasked interrupts kick us out of idle */
|
||||||
ICCR = 1;
|
ICCR = 1;
|
||||||
|
|
||||||
for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
|
for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
|
||||||
set_irq_chip(irq, &pxa_internal_chip_low);
|
set_irq_chip(irq, &pxa_internal_irq_chip);
|
||||||
set_irq_handler(irq, handle_level_irq);
|
set_irq_handler(irq, handle_level_irq);
|
||||||
set_irq_flags(irq, IRQF_VALID);
|
set_irq_flags(irq, IRQF_VALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is for the second set of internal IRQs as found on the PXA27x.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void pxa_mask_high_irq(unsigned int irq)
|
|
||||||
{
|
|
||||||
ICMR2 &= ~(1 << (irq - 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pxa_unmask_high_irq(unsigned int irq)
|
|
||||||
{
|
|
||||||
ICMR2 |= (1 << (irq - 32));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct irq_chip pxa_internal_chip_high = {
|
|
||||||
.name = "SC-hi",
|
|
||||||
.ack = pxa_mask_high_irq,
|
|
||||||
.mask = pxa_mask_high_irq,
|
|
||||||
.unmask = pxa_unmask_high_irq,
|
|
||||||
};
|
|
||||||
|
|
||||||
void __init pxa_init_irq_high(void)
|
|
||||||
{
|
|
||||||
int irq;
|
|
||||||
|
|
||||||
ICMR2 = 0;
|
|
||||||
ICLR2 = 0;
|
|
||||||
|
|
||||||
for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
|
|
||||||
set_irq_chip(irq, &pxa_internal_chip_high);
|
|
||||||
set_irq_handler(irq, handle_level_irq);
|
|
||||||
set_irq_flags(irq, IRQF_VALID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
|
void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
|
||||||
{
|
{
|
||||||
pxa_internal_chip_low.set_wake = set_wake;
|
pxa_internal_irq_chip.set_wake = set_wake;
|
||||||
#ifdef CONFIG_PXA27x
|
|
||||||
pxa_internal_chip_high.set_wake = set_wake;
|
|
||||||
#endif
|
|
||||||
pxa_init_gpio_set_wake(set_wake);
|
pxa_init_gpio_set_wake(set_wake);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,19 +83,11 @@ static unsigned long saved_icmr[2];
|
|||||||
|
|
||||||
static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
|
static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
|
||||||
{
|
{
|
||||||
switch (dev->id) {
|
int i, irq = PXA_IRQ(0);
|
||||||
case 0:
|
|
||||||
saved_icmr[0] = ICMR;
|
for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
|
||||||
ICMR = 0;
|
saved_icmr[i] = _ICMR(irq);
|
||||||
break;
|
_ICMR(irq) = 0;
|
||||||
#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
|
|
||||||
case 1:
|
|
||||||
saved_icmr[1] = ICMR2;
|
|
||||||
ICMR2 = 0;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -138,22 +95,14 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
|
|||||||
|
|
||||||
static int pxa_irq_resume(struct sys_device *dev)
|
static int pxa_irq_resume(struct sys_device *dev)
|
||||||
{
|
{
|
||||||
switch (dev->id) {
|
int i, irq = PXA_IRQ(0);
|
||||||
case 0:
|
|
||||||
ICMR = saved_icmr[0];
|
for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
|
||||||
ICLR = 0;
|
_ICMR(irq) = saved_icmr[i];
|
||||||
ICCR = 1;
|
_ICLR(irq) = 0;
|
||||||
break;
|
|
||||||
#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
|
|
||||||
case 1:
|
|
||||||
ICMR2 = saved_icmr[1];
|
|
||||||
ICLR2 = 0;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ICCR = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -267,7 +267,7 @@ set_pwer:
|
|||||||
|
|
||||||
void __init pxa25x_init_irq(void)
|
void __init pxa25x_init_irq(void)
|
||||||
{
|
{
|
||||||
pxa_init_irq_low();
|
pxa_init_irq(32);
|
||||||
pxa_init_irq_gpio(85);
|
pxa_init_irq_gpio(85);
|
||||||
pxa_init_irq_set_wake(pxa25x_set_wake);
|
pxa_init_irq_set_wake(pxa25x_set_wake);
|
||||||
}
|
}
|
||||||
|
@ -340,8 +340,7 @@ set_pwer:
|
|||||||
|
|
||||||
void __init pxa27x_init_irq(void)
|
void __init pxa27x_init_irq(void)
|
||||||
{
|
{
|
||||||
pxa_init_irq_low();
|
pxa_init_irq(34);
|
||||||
pxa_init_irq_high();
|
|
||||||
pxa_init_irq_gpio(128);
|
pxa_init_irq_gpio(128);
|
||||||
pxa_init_irq_set_wake(pxa27x_set_wake);
|
pxa_init_irq_set_wake(pxa27x_set_wake);
|
||||||
}
|
}
|
||||||
@ -389,10 +388,6 @@ static struct platform_device *devices[] __initdata = {
|
|||||||
|
|
||||||
static struct sys_device pxa27x_sysdev[] = {
|
static struct sys_device pxa27x_sysdev[] = {
|
||||||
{
|
{
|
||||||
.id = 0,
|
|
||||||
.cls = &pxa_irq_sysclass,
|
|
||||||
}, {
|
|
||||||
.id = 1,
|
|
||||||
.cls = &pxa_irq_sysclass,
|
.cls = &pxa_irq_sysclass,
|
||||||
}, {
|
}, {
|
||||||
.cls = &pxa_gpio_sysclass,
|
.cls = &pxa_gpio_sysclass,
|
||||||
|
@ -513,8 +513,7 @@ void __init pxa3xx_init_irq(void)
|
|||||||
value |= (1 << 6);
|
value |= (1 << 6);
|
||||||
__asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
|
__asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
|
||||||
|
|
||||||
pxa_init_irq_low();
|
pxa_init_irq(56);
|
||||||
pxa_init_irq_high();
|
|
||||||
pxa_init_irq_gpio(128);
|
pxa_init_irq_gpio(128);
|
||||||
pxa3xx_init_irq_pm();
|
pxa3xx_init_irq_pm();
|
||||||
}
|
}
|
||||||
@ -538,10 +537,6 @@ static struct platform_device *devices[] __initdata = {
|
|||||||
|
|
||||||
static struct sys_device pxa3xx_sysdev[] = {
|
static struct sys_device pxa3xx_sysdev[] = {
|
||||||
{
|
{
|
||||||
.id = 0,
|
|
||||||
.cls = &pxa_irq_sysclass,
|
|
||||||
}, {
|
|
||||||
.id = 1,
|
|
||||||
.cls = &pxa_irq_sysclass,
|
.cls = &pxa_irq_sysclass,
|
||||||
}, {
|
}, {
|
||||||
.cls = &pxa_gpio_sysclass,
|
.cls = &pxa_gpio_sysclass,
|
||||||
|
@ -1129,6 +1129,11 @@
|
|||||||
#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
|
#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
|
||||||
#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */
|
#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */
|
||||||
|
|
||||||
|
#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */
|
||||||
|
#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */
|
||||||
|
#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */
|
||||||
|
#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */
|
||||||
|
#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* General Purpose I/O
|
* General Purpose I/O
|
||||||
@ -1200,12 +1205,6 @@
|
|||||||
|
|
||||||
/* Interrupt Controller */
|
/* Interrupt Controller */
|
||||||
|
|
||||||
#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */
|
|
||||||
#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */
|
|
||||||
#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */
|
|
||||||
#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */
|
|
||||||
#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */
|
|
||||||
|
|
||||||
#define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3)
|
#define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3)
|
||||||
#define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3)
|
#define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3)
|
||||||
#define _GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3)
|
#define _GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3)
|
||||||
|
Loading…
Reference in New Issue
Block a user