Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6fb7af4 authored by eric miao's avatar eric miao Committed by Russell King
Browse files

[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: default avatareric miao <eric.miao@marvell.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent e3630db1
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -12,8 +12,7 @@
struct sys_timer;

extern struct sys_timer pxa_timer;
extern void __init pxa_init_irq_low(void);
extern void __init pxa_init_irq_high(void);
extern void __init pxa_init_irq(int irq_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_gpio_set_wake(int (*set_wake)(unsigned int, unsigned int));
+33 −84
Original line number Diff line number Diff line
@@ -24,92 +24,57 @@

#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.
 */

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",
	.ack		= pxa_mask_low_irq,
	.mask		= pxa_mask_low_irq,
	.unmask		= pxa_unmask_low_irq,
	.ack		= pxa_mask_irq,
	.mask		= pxa_mask_irq,
	.unmask		= pxa_unmask_irq,
};

void __init pxa_init_irq_low(void)
void __init pxa_init_irq(int irq_nr)
{
	int irq;

	/* disable all IRQs */
	ICMR = 0;
	pxa_internal_irq_nr = irq_nr;

	/* all IRQs are IRQ, not FIQ */
	ICLR = 0;
	for (irq = 0; irq < irq_nr; irq += 32) {
		_ICMR(irq) = 0;	/* disable all IRQs */
		_ICLR(irq) = 0;	/* all IRQs are IRQ, not FIQ */
	}

	/* only unmasked interrupts kick us out of idle */
	ICCR = 1;

	for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
		set_irq_chip(irq, &pxa_internal_chip_low);
	for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
		set_irq_chip(irq, &pxa_internal_irq_chip);
		set_irq_handler(irq, handle_level_irq);
		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))
{
	pxa_internal_chip_low.set_wake = set_wake;
#ifdef CONFIG_PXA27x
	pxa_internal_chip_high.set_wake = set_wake;
#endif
	pxa_internal_irq_chip.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)
{
	switch (dev->id) {
	case 0:
		saved_icmr[0] = ICMR;
		ICMR = 0;
		break;
#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
	case 1:
		saved_icmr[1] = ICMR2;
		ICMR2 = 0;
		break;
#endif
	default:
		return -EINVAL;
	int i, irq = PXA_IRQ(0);

	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
		saved_icmr[i] = _ICMR(irq);
		_ICMR(irq) = 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)
{
	switch (dev->id) {
	case 0:
		ICMR = saved_icmr[0];
		ICLR = 0;
		ICCR = 1;
		break;
#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
	case 1:
		ICMR2 = saved_icmr[1];
		ICLR2 = 0;
		break;
#endif
	default:
		return -EINVAL;
	int i, irq = PXA_IRQ(0);

	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
		_ICMR(irq) = saved_icmr[i];
		_ICLR(irq) = 0;
	}

	ICCR = 1;
	return 0;
}
#else
+1 −1
Original line number Diff line number Diff line
@@ -267,7 +267,7 @@ static int pxa25x_set_wake(unsigned int irq, unsigned int on)

void __init pxa25x_init_irq(void)
{
	pxa_init_irq_low();
	pxa_init_irq(32);
	pxa_init_irq_gpio(85);
	pxa_init_irq_set_wake(pxa25x_set_wake);
}
+1 −6
Original line number Diff line number Diff line
@@ -340,8 +340,7 @@ static int pxa27x_set_wake(unsigned int irq, unsigned int on)

void __init pxa27x_init_irq(void)
{
	pxa_init_irq_low();
	pxa_init_irq_high();
	pxa_init_irq(34);
	pxa_init_irq_gpio(128);
	pxa_init_irq_set_wake(pxa27x_set_wake);
}
@@ -389,10 +388,6 @@ static struct platform_device *devices[] __initdata = {

static struct sys_device pxa27x_sysdev[] = {
	{
		.id	= 0,
		.cls	= &pxa_irq_sysclass,
	}, {
		.id	= 1,
		.cls	= &pxa_irq_sysclass,
	}, {
		.cls	= &pxa_gpio_sysclass,
+1 −6
Original line number Diff line number Diff line
@@ -513,8 +513,7 @@ void __init pxa3xx_init_irq(void)
	value |= (1 << 6);
	__asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));

	pxa_init_irq_low();
	pxa_init_irq_high();
	pxa_init_irq(56);
	pxa_init_irq_gpio(128);
	pxa3xx_init_irq_pm();
}
@@ -538,10 +537,6 @@ static struct platform_device *devices[] __initdata = {

static struct sys_device pxa3xx_sysdev[] = {
	{
		.id	= 0,
		.cls	= &pxa_irq_sysclass,
	}, {
		.id	= 1,
		.cls	= &pxa_irq_sysclass,
	}, {
		.cls	= &pxa_gpio_sysclass,
Loading