aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Damm2007-06-15 18:56:19 +0900
committerPaul Mundt2007-06-15 18:56:19 +0900
commit68abdbbb03476a60d932eeba0035dd5069afec38 (patch)
treede3854f76d6d9aec121c432a3cd276bb756003c9
parent50f63f2518ee68bc132d357d2b6fdb7f60ef79e0 (diff)
sh: rework ipr code
This patch reworks the ipr code by grouping the offset array together with the ipr_data structure in a new data structure called ipr_desc. This new structure also contains the name of the controller in struct irq_chip. The idea behind putting struct irq_chip in there is that we can use offsetof() to locate the base addresses in the irq_chip callbacks. This strategy has much in common with the recently merged intc2 code. One logic change has been made - the original ipr code enabled the interrupts by default but with this patch they are all disabled by default. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/boards/se/770x/irq.c124
-rw-r--r--arch/sh/boards/se/7722/irq.c15
-rw-r--r--arch/sh/boards/se/7751/irq.c59
-rw-r--r--arch/sh/boards/sh03/setup.c28
-rw-r--r--arch/sh/boards/shmin/setup.c30
-rw-r--r--arch/sh/boards/snapgear/setup.c28
-rw-r--r--arch/sh/boards/titan/setup.c22
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c59
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c24
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c24
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c40
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7709.c84
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c42
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c58
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c32
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c21
-rw-r--r--include/asm-sh/hw_irq.h23
-rw-r--r--include/asm-sh/irq.h30
-rw-r--r--include/asm-sh/sh03/io.h4
-rw-r--r--include/asm-sh/snapgear.h4
20 files changed, 427 insertions, 324 deletions
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c
index c8eccff77a04..cdb0807928a5 100644
--- a/arch/sh/boards/se/770x/irq.c
+++ b/arch/sh/boards/se/770x/irq.c
@@ -15,46 +15,7 @@
#include <asm/io.h>
#include <asm/se.h>
-/*
- * If the problem of make_ipr_irq is solved,
- * this code will become unnecessary. :-)
- */
-static void se770x_disable_ipr_irq(unsigned int irq)
-{
- struct ipr_data *p = get_irq_chip_data(irq);
-
- ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
-}
-
-static void se770x_enable_ipr_irq(unsigned int irq)
-{
- struct ipr_data *p = get_irq_chip_data(irq);
-
- ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
-}
-
-static struct irq_chip se770x_irq_chip = {
- .name = "MS770xSE-FPGA",
- .mask = se770x_disable_ipr_irq,
- .unmask = se770x_enable_ipr_irq,
- .mask_ack = se770x_disable_ipr_irq,
-};
-
-void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs)
-{
- int i;
-
- for (i = 0; i < nr_irqs; i++) {
- unsigned int irq = table[i].irq;
- disable_irq_nosync(irq);
- set_irq_chip_and_handler_name(irq, &se770x_irq_chip,
- handle_level_irq, "level");
- set_irq_chip_data(irq, &table[i]);
- se770x_enable_ipr_irq(irq);
- }
-}
-
-static struct ipr_data se770x_ipr_map[] = {
+static struct ipr_data ipr_irq_table[] = {
/*
* Super I/O (Just mimic PC):
* 1: keyboard
@@ -68,46 +29,67 @@ static struct ipr_data se770x_ipr_map[] = {
*/
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
/* This is default value */
- { 13, 0, 8, 0x0f-13 ,BCR_ILCRA},
- { 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA},
- { 10, 0, 0, 0x0f-10, BCR_ILCRB},
- { 7 , 0, 4, 0x0f- 7, BCR_ILCRC},
- { 3 , 0, 0, 0x0f- 3, BCR_ILCRC},
- { 1 , 0, 12, 0x0f- 1, BCR_ILCRD},
- { 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */
- { 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */
- { 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */
- { 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */
- { 0 , 0, 12, 0x0f , BCR_ILCRF},
- { 4 , 0, 4, 0x0f- 4, BCR_ILCRF},
- { 8 , 0, 12, 0x0f- 8, BCR_ILCRG},
- { 9 , 0, 8, 0x0f- 9, BCR_ILCRG},
- { 11, 0, 4, 0x0f-11, BCR_ILCRG},
+ { 13, 0, 8, 0x0f-13, },
+ { 5 , 0, 4, 0x0f- 5, },
+ { 10, 1, 0, 0x0f-10, },
+ { 7 , 2, 4, 0x0f- 7, },
+ { 3 , 2, 0, 0x0f- 3, },
+ { 1 , 3, 12, 0x0f- 1, },
+ { 12, 3, 4, 0x0f-12, }, /* LAN */
+ { 2 , 4, 8, 0x0f- 2, }, /* PCIRQ2 */
+ { 6 , 4, 4, 0x0f- 6, }, /* PCIRQ1 */
+ { 14, 4, 0, 0x0f-14, }, /* PCIRQ0 */
+ { 0 , 5, 12, 0x0f , },
+ { 4 , 5, 4, 0x0f- 4, },
+ { 8 , 6, 12, 0x0f- 8, },
+ { 9 , 6, 8, 0x0f- 9, },
+ { 11, 6, 4, 0x0f-11, },
#else
- { 14, 0, 8, 0x0f-14 ,BCR_ILCRA},
- { 12, 0, 4, 0x0f-12 ,BCR_ILCRA},
- { 8, 0, 4, 0x0f- 8 ,BCR_ILCRB},
- { 6, 0, 12, 0x0f- 6 ,BCR_ILCRC},
- { 5, 0, 8, 0x0f- 5 ,BCR_ILCRC},
- { 4, 0, 4, 0x0f- 4 ,BCR_ILCRC},
- { 3, 0, 0, 0x0f- 3 ,BCR_ILCRC},
- { 1, 0, 12, 0x0f- 1 ,BCR_ILCRD},
+ { 14, 0, 8, 0x0f-14, },
+ { 12, 0, 4, 0x0f-12, },
+ { 8, 1, 4, 0x0f- 8, },
+ { 6, 2, 12, 0x0f- 6, },
+ { 5, 2, 8, 0x0f- 5, },
+ { 4, 2, 4, 0x0f- 4, },
+ { 3, 2, 0, 0x0f- 3, },
+ { 1, 3, 12, 0x0f- 1, },
#if defined(CONFIG_STNIC)
/* ST NIC */
- { 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */
+ { 10, 3, 4, 0x0f-10, }, /* LAN */
#endif
/* MRSHPC IRQs setting */
- { 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */
- { 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */
- { 9, 0, 4, 0x0f- 9 ,BCR_ILCRE}, /* PCIRQ1 */
- { 7, 0, 0, 0x0f- 7 ,BCR_ILCRE}, /* PCIRQ0 */
+ { 0, 4, 12, 0x0f- 0, }, /* PCIRQ3 */
+ { 11, 4, 8, 0x0f-11, }, /* PCIRQ2 */
+ { 9, 4, 4, 0x0f- 9, }, /* PCIRQ1 */
+ { 7, 4, 0, 0x0f- 7, }, /* PCIRQ0 */
/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
/* NOTE: #2 and #13 are not used on PC */
- { 13, 0, 4, 0x0f-13 ,BCR_ILCRG}, /* SLOTIRQ2 */
- { 2, 0, 0, 0x0f- 2 ,BCR_ILCRG}, /* SLOTIRQ1 */
+ { 13, 6, 4, 0x0f-13, }, /* SLOTIRQ2 */
+ { 2, 6, 0, 0x0f- 2, }, /* SLOTIRQ1 */
#endif
};
+static unsigned long ipr_offsets[] = {
+ BCR_ILCRA,
+ BCR_ILCRB,
+ BCR_ILCRC,
+ BCR_ILCRD,
+ BCR_ILCRE,
+ BCR_ILCRF,
+ BCR_ILCRG,
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+ .chip = {
+ .name = "IPR-se770x",
+ },
+};
+
/*
* Initialize IRQ setting
*/
@@ -122,5 +104,5 @@ void __init init_se_IRQ(void)
ctrl_outw(0, BCR_ILCRF);
ctrl_outw(0, BCR_ILCRG);
- make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/boards/se/7722/irq.c b/arch/sh/boards/se/7722/irq.c
index 099e5deb77f8..26cff0efda40 100644
--- a/arch/sh/boards/se/7722/irq.c
+++ b/arch/sh/boards/se/7722/irq.c
@@ -19,15 +19,24 @@
#define INTC_INTMSK0 0xFFD00044
#define INTC_INTMSKCLR0 0xFFD00064
+struct se7722_data {
+ unsigned char irq;
+ unsigned char ipr_idx;
+ unsigned char shift;
+ unsigned short priority;
+ unsigned long addr;
+};
+
+
static void disable_se7722_irq(unsigned int irq)
{
- struct ipr_data *p = get_irq_chip_data(irq);
+ struct se7722_data *p = get_irq_chip_data(irq);
ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr );
}
static void enable_se7722_irq(unsigned int irq)
{
- struct ipr_data *p = get_irq_chip_data(irq);
+ struct se7722_data *p = get_irq_chip_data(irq);
ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr );
}
@@ -38,7 +47,7 @@ static struct irq_chip se7722_irq_chip __read_mostly = {
.mask_ack = disable_se7722_irq,
};
-static struct ipr_data ipr_irq_table[] = {
+static struct se7722_data ipr_irq_table[] = {
/* irq ,idx,sft, priority , addr */
{ MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } ,
{ MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } ,
diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c
index e4c63a48296c..c3d12590e5db 100644
--- a/arch/sh/boards/se/7751/irq.c
+++ b/arch/sh/boards/se/7751/irq.c
@@ -14,44 +14,31 @@
#include <asm/irq.h>
#include <asm/se7751.h>
-static struct ipr_data se7751_ipr_map[] = {
- /* Leave old Solution Engine code in for reference. */
-#if defined(CONFIG_SH_SOLUTION_ENGINE)
- /*
- * Super I/O (Just mimic PC):
- * 1: keyboard
- * 3: serial 0
- * 4: serial 1
- * 5: printer
- * 6: floppy
- * 8: rtc
- * 12: mouse
- * 14: ide0
- */
- { 14, BCR_ILCRA, 2, 0x0f-14 },
- { 12, BCR_ILCRA, 1, 0x0f-12 },
- { 8, BCR_ILCRB, 1, 0x0f- 8 },
- { 6, BCR_ILCRC, 3, 0x0f- 6 },
- { 5, BCR_ILCRC, 2, 0x0f- 5 },
- { 4, BCR_ILCRC, 1, 0x0f- 4 },
- { 3, BCR_ILCRC, 0, 0x0f- 3 },
- { 1, BCR_ILCRD, 3, 0x0f- 1 },
+static struct ipr_data ipr_irq_table[] = {
+ { 13, 3, 3, 2 },
+ /* Add additional entries here as drivers are added and tested. */
+};
- { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */
+static unsigned long ipr_offsets[] = {
+ BCR_ILCRA,
+ BCR_ILCRB,
+ BCR_ILCRC,
+ BCR_ILCRD,
+ BCR_ILCRE,
+ BCR_ILCRF,
+ BCR_ILCRG,
+};
- { 0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */
- { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */
- { 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */
- { 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
- /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
- /* NOTE: #2 and #13 are not used on PC */
- { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */
- { 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */
-#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
- { 13, BCR_ILCRD, 3, 2 },
- /* Add additional entries here as drivers are added and tested. */
-#endif
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-se7751",
+ },
};
/*
@@ -59,5 +46,5 @@ static struct ipr_data se7751_ipr_map[] = {
*/
void __init init_7751se_IRQ(void)
{
- make_ipr_irq(se7751_ipr_map, ARRAY_SIZE(se7751_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c
index d7867c190a96..9c031a8c0a1c 100644
--- a/arch/sh/boards/sh03/setup.c
+++ b/arch/sh/boards/sh03/setup.c
@@ -15,17 +15,33 @@
#include <asm/sh03/sh03.h>
#include <asm/addrspace.h>
-static struct ipr_data sh03_ipr_map[] = {
- { IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY },
- { IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY },
- { IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY },
- { IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY },
+static struct ipr_data ipr_irq_table[] = {
+ { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY },
+ { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY },
+ { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY },
+ { IRL3_IRQ, 0, IRL3_IPR_POS, IRL3_PRIORITY },
+};
+
+static unsigned long ipr_offsets[] = {
+ INTC_IPRD,
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh03",
+ },
};
static void __init init_sh03_IRQ(void)
{
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
- make_ipr_irq(sh03_ipr_map, ARRAY_SIZE(sh03_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
extern void *cf_io_base;
diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c
index 9c8bb51eb4bb..dfd124509f42 100644
--- a/arch/sh/boards/shmin/setup.c
+++ b/arch/sh/boards/shmin/setup.c
@@ -6,28 +6,44 @@
* SHMIN Support.
*/
#include <linux/init.h>
+#include <linux/irq.h>
#include <asm/machvec.h>
#include <asm/shmin.h>
#include <asm/clock.h>
-#include <asm/irq.h>
#include <asm/io.h>
#define PFC_PHCR 0xa400010eUL
#define INTC_ICR1 0xa4000010UL
#define INTC_IPRC 0xa4000016UL
-static struct ipr_data shmin_ipr_map[] = {
- { .irq=32, .addr=INTC_IPRC, .shift= 0, .priority=0 },
- { .irq=33, .addr=INTC_IPRC, .shift= 4, .priority=0 },
- { .irq=34, .addr=INTC_IPRC, .shift= 8, .priority=8 },
- { .irq=35, .addr=INTC_IPRC, .shift=12, .priority=0 },
+static struct ipr_data ipr_irq_table[] = {
+ { 32, 0, 0, 0 },
+ { 33, 0, 4, 0 },
+ { 34, 0, 8, 8 },
+ { 35, 0, 12, 0 },
+};
+
+static unsigned long ipr_offsets[] = {
+ INTC_IPRC,
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-shmin",
+ },
};
static void __init init_shmin_irq(void)
{
ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ
ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active.
- make_ipr_irq(shmin_ipr_map, ARRAY_SIZE(shmin_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size)
diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c
index b40124c092f5..84271d85a8dd 100644
--- a/arch/sh/boards/snapgear/setup.c
+++ b/arch/sh/boards/snapgear/setup.c
@@ -68,11 +68,27 @@ module_init(eraseconfig_init);
* IRL3 = crypto
*/
-static struct ipr_data snapgear_ipr_map[] = {
- make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
- make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
- make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
- make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
+static struct ipr_data ipr_irq_table[] = {
+ { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY },
+ { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY },
+ { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY },
+ { IRL3_IRQ, 0, IRL3_IPR_POS, IRL3_PRIORITY },
+};
+
+static unsigned long ipr_offsets[] = {
+ INTC_IPRD,
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-snapgear",
+ },
};
static void __init init_snapgear_IRQ(void)
@@ -82,7 +98,7 @@ static void __init init_snapgear_IRQ(void)
printk("Setup SnapGear IRQ/IPR ...\n");
- make_ipr_irq(snapgear_ipr_map, ARRAY_SIZE(snapgear_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
/*
diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c
index 630f62f69a36..606d25a4b870 100644
--- a/arch/sh/boards/titan/setup.c
+++ b/arch/sh/boards/titan/setup.c
@@ -12,7 +12,7 @@
#include <asm/titan.h>
#include <asm/io.h>
-static struct ipr_data titan_ipr_map[] = {
+static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR idx, shift, prio */
{ TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */
{ TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */
@@ -20,12 +20,30 @@ static struct ipr_data titan_ipr_map[] = {
{ TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */
};
+static unsigned long ipr_offsets[] = { /* stolen from setup-sh7750.c */
+ 0xffd00004UL, /* 0: IPRA */
+ 0xffd00008UL, /* 1: IPRB */
+ 0xffd0000cUL, /* 2: IPRC */
+ 0xffd00010UL, /* 3: IPRD */
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-titan",
+ },
+};
static void __init init_titan_irq(void)
{
/* enable individual interrupt mode for externals */
ipr_irq_enable_irlm();
/* register ipr irqs */
- make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
static struct sh_machine_vector mv_titan __initmv = {
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 210280b6fddf..98e84f40c713 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -22,58 +22,57 @@
#include <linux/io.h>
#include <linux/interrupt.h>
+static inline struct ipr_desc *get_ipr_desc(unsigned int irq)
+{
+ struct irq_chip *chip = get_irq_chip(irq);
+ return (void *)((char *)chip - offsetof(struct ipr_desc, chip));
+}
+
static void disable_ipr_irq(unsigned int irq)
{
struct ipr_data *p = get_irq_chip_data(irq);
+ unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
/* Set the priority in IPR to 0 */
- ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
+ ctrl_outw(ctrl_inw(addr) & (0xffff ^ (0xf << p->shift)), addr);
}
static void enable_ipr_irq(unsigned int irq)
{
struct ipr_data *p = get_irq_chip_data(irq);
+ unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
/* Set priority in IPR back to original value */
- ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
+ ctrl_outw(ctrl_inw(addr) | (p->priority << p->shift), addr);
}
-static struct irq_chip ipr_irq_chip = {
- .name = "IPR",
- .mask = disable_ipr_irq,
- .unmask = enable_ipr_irq,
- .mask_ack = disable_ipr_irq,
-};
-
-unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak));
-unsigned int map_ipridx_to_addr(int idx)
-{
- return 0;
-}
+/*
+ * The shift value is now the number of bits to shift, not the number of
+ * bits/4. This is to make it easier to read the value directly from the
+ * datasheets. The IPR address is calculated using the ipr_offset table.
+ */
-void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
+void register_ipr_controller(struct ipr_desc *desc)
{
int i;
- for (i = 0; i < nr_irqs; i++) {
- unsigned int irq = table[i].irq;
+ desc->chip.mask = disable_ipr_irq;
+ desc->chip.unmask = enable_ipr_irq;
+ desc->chip.mask_ack = disable_ipr_irq;
- if (!irq)
- irq = table[i].irq = i;
+ for (i = 0; i < desc->nr_irqs; i++) {
+ struct ipr_data *p = desc->ipr_data + i;
- /* could the IPR index be mapped, if not we ignore this */
- if (!table[i].addr) {
- table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
- if (!table[i].addr)
- continue;
- }
+ BUG_ON(p->ipr_idx >= desc->nr_offsets);
+ BUG_ON(!desc->ipr_offsets[p->ipr_idx]);
- disable_irq_nosync(irq);
- set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
+ disable_irq_nosync(p->irq);
+ set_irq_chip_and_handler_name(p->irq, &desc->chip,
handle_level_irq, "level");
- set_irq_chip_data(irq, &table[i]);
- enable_ipr_irq(irq);
+ set_irq_chip_data(p->irq, p);
+ disable_ipr_irq(p->irq);
}
}
-EXPORT_SYMBOL(make_ipr_irq);
+
+EXPORT_SYMBOL(register_ipr_controller);
#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
int ipr_irq_demux(int irq)
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index f83ff8a68f35..1a107fe22dde 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -52,7 +52,7 @@ static int __init sh7619_devices_setup(void)
}
__initcall(sh7619_devices_setup);
-static struct ipr_data sh7619_ipr_map[] = {
+static struct ipr_data ipr_irq_table[] = {
{ 86, 0, 4, 2 }, /* CMI0 */
{ 88, 1, 12, 3 }, /* SCIF0_ERI */
{ 89, 1, 12, 3 }, /* SCIF0_RXI */
@@ -68,7 +68,7 @@ static struct ipr_data sh7619_ipr_map[] = {
{ 99, 1, 4, 3 }, /* SCIF2_TXI */
};
-static unsigned int ipr_offsets[] = {
+static unsigned long ipr_offsets[] = {
0xf8080000, /* IPRC */
0xf8080002, /* IPRD */
0xf8080004, /* IPRE */
@@ -76,15 +76,19 @@ static unsigned int ipr_offsets[] = {
0xf8080008, /* IPRG */
};
-/* given the IPR index return the address of the IPR register */
-unsigned int map_ipridx_to_addr(int idx)
-{
- if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
- return 0;
- return ipr_offsets[idx];
-}
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh7619",
+ },
+};
void __init init_IRQ_ipr(void)
{
- make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index 4ed9110632bc..b6e3a6351fa6 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -57,7 +57,7 @@ static int __init sh7206_devices_setup(void)
}
__initcall(sh7206_devices_setup);
-static struct ipr_data sh7206_ipr_map[] = {
+static struct ipr_data ipr_irq_table[] = {
{ 140, 7, 12, 2 }, /* CMI0 */
{ 164, 8, 4, 2 }, /* MTU2_TGI1A */
{ 240, 13, 12, 3 }, /* SCIF0_BRI */
@@ -78,7 +78,7 @@ static struct ipr_data sh7206_ipr_map[] = {
{ 255, 13, 0, 3 }, /* SCIF3_TXI */
};
-static unsigned int ipr_offsets[] = {
+static unsigned long ipr_offsets[] = {
0xfffe0818, /* IPR01 */
0xfffe081a, /* IPR02 */
0, /* unused */
@@ -95,15 +95,19 @@ static unsigned int ipr_offsets[] = {
0xfffe0c10, /* IPR14 */
};
-/* given the IPR index return the address of the IPR register */
-unsigned int map_ipridx_to_addr(int idx)
-{
- if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
- return 0;
- return ipr_offsets[idx];
-}
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh7206",
+ },
+};
void __init init_IRQ_ipr(void)
{
- make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index 1983fb7ad6ea..a55b8ce2c54c 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -48,7 +48,7 @@ static int __init sh7705_devices_setup(void)
}
__initcall(sh7705_devices_setup);
-static struct ipr_data sh7705_ipr_map[] = {
+static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
@@ -70,25 +70,29 @@ static struct ipr_data sh7705_ipr_map[] = {
};
static unsigned long ipr_offsets[] = {
- 0xFFFFFEE2 /* 0: IPRA */
-, 0xFFFFFEE4 /* 1: IPRB */
-, 0xA4000016 /* 2: IPRC */
-, 0xA4000018 /* 3: IPRD */
-, 0xA400001A /* 4: IPRE */
-, 0xA4080000 /* 5: IPRF */
-, 0xA4080002 /* 6: IPRG */
-, 0xA4080004 /* 7: IPRH */
+ 0xFFFFFEE2, /* 0: IPRA */
+ 0xFFFFFEE4, /* 1: IPRB */
+ 0xA4000016, /* 2: IPRC */
+ 0xA4000018, /* 3: IPRD */
+ 0xA400001A, /* 4: IPRE */
+ 0xA4080000, /* 5: IPRF */
+ 0xA4080002, /* 6: IPRG */
+ 0xA4080004, /* 7: IPRH */
};
-/* given the IPR index return the address of the IPR register */
-unsigned int map_ipridx_to_addr(int idx)
-{
- if (idx >= ARRAY_SIZE(ipr_offsets))
- return 0;
- return ipr_offsets[idx];
-}
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh7705",
+ },
+};
-void __init init_IRQ_ipr()
+void __init init_IRQ_ipr(void)
{
- make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
index c7d7c35fc834..c0265a96e7d3 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
@@ -52,32 +52,66 @@ static int __init sh7709_devices_setup(void)
}
__initcall(sh7709_devices_setup);
-#define IPRx(A,N) .addr=A, .shift=N
-#define IPRA(N) IPRx(0xfffffee2UL,N)
-#define IPRB(N) IPRx(0xfffffee4UL,N)
-#define IPRC(N) IPRx(0xa4000016UL,N)
-#define IPRD(N) IPRx(0xa4000018UL,N)
-#define IPRE(N) IPRx(0xa400001aUL,N)
-
-static struct ipr_data sh7709_ipr_map[] = {
- [16] = { IPRA(12), 2 }, /* TMU TUNI0 */
- [17] = { IPRA(8), 4 }, /* TMU TUNI1 */
- [18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */
- [20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */
- [23 ... 26] = { IPRB(4), 3 }, /* SCI */
- [27] = { IPRB(12), 2 }, /* WDT ITI */
- [32] = { IPRC(0), 1 }, /* IRQ 0 */
- [33] = { IPRC(4), 1 }, /* IRQ 1 */
- [34] = { IPRC(8), 1 }, /* IRQ 2 APM */
- [35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */
- [36] = { IPRD(0), 1 }, /* IRQ 4 */
- [37] = { IPRD(4), 1 }, /* IRQ 5 */
- [48 ... 51] = { IPRE(12), 7 }, /* DMA */
- [52 ... 55] = { IPRE(8), 3 }, /* IRDA */
- [56 ... 59] = { IPRE(4), 3 }, /* SCIF */
+static struct ipr_data ipr_irq_table[] = {
+ { 16, 0, 12, 2 }, /* TMU TUNI0 */
+ { 17, 0, 8, 4 }, /* TMU TUNI1 */
+ { 18, 0, 4, 1 }, /* TMU TUNI1 */
+ { 19, 0, 4, 1 }, /* TMU TUNI1 */
+ { 20, 0, 0, 2 }, /* RTC CUI */
+ { 21, 0, 0, 2 }, /* RTC CUI */
+ { 22, 0, 0, 2 }, /* RTC CUI */
+
+ { 23, 1, 4, 3 }, /* SCI */
+ { 24, 1, 4, 3 }, /* SCI */
+ { 25, 1, 4, 3 }, /* SCI */
+ { 26, 1, 4, 3 }, /* SCI */
+ { 27, 1, 12, 3 }, /* WDT ITI */
+
+ { 32, 2, 0, 1 }, /* IRQ 0 */
+ { 33, 2, 4, 1 }, /* IRQ 1 */
+ { 34, 2, 8, 1 }, /* IRQ 2 APM */
+ { 35, 2, 12, 1 }, /* IRQ 3 TOUCHSCREEN */
+
+ { 36, 3, 0, 1 }, /* IRQ 4 */
+ { 37, 3, 4, 1 }, /* IRQ 5 */
+
+ { 48, 4, 12, 7 }, /* DMA */
+ { 49, 4, 12, 7 }, /* DMA */
+ { 50, 4, 12, 7 }, /* DMA */
+ { 51, 4, 12, 7 }, /* DMA */
+
+ { 52, 4, 8, 3 }, /* IRDA */
+ { 53, 4, 8, 3 }, /* IRDA */
+ { 54, 4, 8, 3 }, /* IRDA */
+ { 55, 4, 8, 3 }, /* IRDA */
+
+ { 56, 4, 4, 3 }, /* SCIF */
+ { 57, 4, 4, 3 }, /* SCIF */
+ { 58, 4, 4, 3 }, /* SCIF */
+ { 59, 4, 4, 3 }, /* SCIF */
+};
+
+static unsigned long ipr_offsets[] = {
+ 0xfffffee2, /* 0: IPRA */
+ 0xfffffee4, /* 1: IPRB */
+ 0xa4000016, /* 2: IPRC */
+ 0xa4000018, /* 3: IPRD */
+ 0xa400001a, /* 4: IPRE */
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh7709",
+ },
};
-void __init init_IRQ_ipr()
+void __init init_IRQ_ipr(void)
{
- make_ipr_irq(sh7709_ipr_map, ARRAY_SIZE(sh7709_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 51760a7e7f1c..f40e6dac337d 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -49,7 +49,7 @@ static int __init sh7710_devices_setup(void)
}
__initcall(sh7710_devices_setup);
-static struct ipr_data sh7710_ipr_map[] = {
+static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
@@ -78,26 +78,30 @@ static struct ipr_data sh7710_ipr_map[] = {
};
static unsigned long ipr_offsets[] = {
- 0xA414FEE2 /* 0: IPRA */
-, 0xA414FEE4 /* 1: IPRB */
-, 0xA4140016 /* 2: IPRC */
-, 0xA4140018 /* 3: IPRD */
-, 0xA414001A /* 4: IPRE */
-, 0xA4080000 /* 5: IPRF */
-, 0xA4080002 /* 6: IPRG */
-, 0xA4080004 /* 7: IPRH */
-, 0xA4080006 /* 8: IPRI */
+ 0xA414FEE2, /* 0: IPRA */
+ 0xA414FEE4, /* 1: IPRB */
+ 0xA4140016, /* 2: IPRC */
+ 0xA4140018, /* 3: IPRD */
+ 0xA414001A, /* 4: IPRE */
+ 0xA4080000, /* 5: IPRF */
+ 0xA4080002, /* 6: IPRG */
+ 0xA4080004, /* 7: IPRH */
+ 0xA4080006, /* 8: IPRI */
};
-/* given the IPR index return the address of the IPR register */
-unsigned int map_ipridx_to_addr(int idx)
-{
- if (idx >= ARRAY_SIZE(ipr_offsets))
- return 0;
- return ipr_offsets[idx];
-}
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh7710",
+ },
+};
-void __init init_IRQ_ipr()
+void __init init_IRQ_ipr(void)
{
- make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index 03b14cf78ddf..da153bcdfeb2 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -82,7 +82,7 @@ static int __init sh7750_devices_setup(void)
}
__initcall(sh7750_devices_setup);
-static struct ipr_data sh7750_ipr_map[] = {
+static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 12, 2 }, /* TMU1 TUNI */
@@ -106,8 +106,27 @@ static struct ipr_data sh7750_ipr_map[] = {
{ 38, 2, 8, 7 }, /* DMAC DMAE */
};
+static unsigned long ipr_offsets[] = {
+ 0xffd00004UL, /* 0: IPRA */
+ 0xffd00008UL, /* 1: IPRB */
+ 0xffd0000cUL, /* 2: IPRC */
+ 0xffd00010UL, /* 3: IPRD */
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh7750",
+ },
+};
+
#ifdef CONFIG_CPU_SUBTYPE_SH7751
-static struct ipr_data sh7751_ipr_map[] = {
+static struct ipr_data ipr_irq_table_sh7751[] = {
{ 44, 2, 8, 7 }, /* DMAC DMTE4 */
{ 45, 2, 8, 7 }, /* DMAC DMTE5 */
{ 46, 2, 8, 7 }, /* DMAC DMTE6 */
@@ -118,21 +137,26 @@ static struct ipr_data sh7751_ipr_map[] = {
/*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */
/*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
};
-#endif
-static unsigned long ipr_offsets[] = {
- 0xffd00004UL, /* 0: IPRA */
- 0xffd00008UL, /* 1: IPRB */
- 0xffd0000cUL, /* 2: IPRC */
- 0xffd00010UL, /* 3: IPRD */
+static struct ipr_desc ipr_irq_desc_sh7751 = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table_sh7751,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table_sh7751),
+
+ .chip = {
+ .name = "IPR-sh7751",
+ },
};
+#endif
-/* given the IPR index return the address of the IPR register */
-unsigned int map_ipridx_to_addr(int idx)
+void __init init_IRQ_ipr(void)
{
- if (idx >= ARRAY_SIZE(ipr_offsets))
- return 0;
- return ipr_offsets[idx];
+ register_ipr_controller(&ipr_irq_desc);
+#ifdef CONFIG_CPU_SUBTYPE_SH7751
+ register_ipr_controller(&ipr_irq_desc_sh7751);
+#endif
}
#define INTC_ICR 0xffd00000UL
@@ -143,11 +167,3 @@ void ipr_irq_enable_irlm(void)
{
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
}
-
-void __init init_IRQ_ipr()
-{
- make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map));
-#ifdef CONFIG_CPU_SUBTYPE_SH7751
- make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map));
-#endif
-}
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 6d3c91897774..3df169755673 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -109,7 +109,12 @@ static struct intc2_desc intc2_irq_desc __read_mostly = {
},
};
-static struct ipr_data sh7760_ipr_map[] = {
+void __init init_IRQ_intc2(void)
+{
+ register_intc2_controller(&intc2_irq_desc);
+}
+
+static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
@@ -146,20 +151,19 @@ static unsigned long ipr_offsets[] = {
0xffd00010UL, /* 3: IPRD */
};
-/* given the IPR index return the address of the IPR register */
-unsigned int map_ipridx_to_addr(int idx)
-{
- if (idx >= ARRAY_SIZE(ipr_offsets))
- return 0;
- return ipr_offsets[idx];
-}
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
-void __init init_IRQ_intc2(void)
-{
- register_intc2_controller(&intc2_irq_desc);
-}
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh7760",
+ },
+};
-void __init init_IRQ_ipr(void)
+void __init init_IRQ_ipr(void)
{
- make_ipr_irq(sh7760_ipr_map, ARRAY_SIZE(sh7760_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index fa07fab4797f..a3e159ef6dfe 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -44,7 +44,7 @@ static int __init sh7722_devices_setup(void)
}
__initcall(sh7722_devices_setup);
-static struct ipr_data sh7722_ipr_map[] = {
+static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, prio */
{ 16, 0, 12, 2 }, /* TMU0 */
{ 17, 0, 8, 2 }, /* TMU1 */
@@ -69,16 +69,21 @@ static unsigned long ipr_offsets[] = {
0xa408002c, /* 11: IPRL */
};
-unsigned int map_ipridx_to_addr(int idx)
-{
- if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
- return 0;
- return ipr_offsets[idx];
-}
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+
+ .chip = {
+ .name = "IPR-sh7722",
+ },
+};
void __init init_IRQ_ipr(void)
{
- make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map));
+ register_ipr_controller(&ipr_irq_desc);
}
void __init plat_mem_setup(void)
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h
index f9dfdc04aef5..4ca3f765bacc 100644
--- a/include/asm-sh/hw_irq.h
+++ b/include/asm-sh/hw_irq.h
@@ -24,4 +24,27 @@ struct intc2_desc {
void register_intc2_controller(struct intc2_desc *);
void init_IRQ_intc2(void);
+struct ipr_data {
+ unsigned char irq;
+ unsigned char ipr_idx; /* Index for the IPR registered */
+ unsigned char shift; /* Number of bits to shift the data */
+ unsigned char priority; /* The priority */
+};
+
+struct ipr_desc {
+ unsigned long *ipr_offsets;
+ unsigned int nr_offsets;
+ struct ipr_data *ipr_data;
+ unsigned int nr_irqs;
+ struct irq_chip chip;
+};
+
+void register_ipr_controller(struct ipr_desc *);
+void init_IRQ_ipr(void);
+
+/*
+ * Enable individual interrupt mode for external IPR IRQs.
+ */
+void ipr_irq_enable_irlm(void);
+
#endif /* __ASM_SH_HW_IRQ_H */
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index c247b733a7d6..c61d902b8bff 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -31,37 +31,7 @@ extern unsigned short *irq_mask_register;
* PINT IRQs
*/
void init_IRQ_pint(void);
-
-/*
- * The shift value is now the number of bits to shift, not the number of
- * bits/4. This is to make it easier to read the value directly from the
- * datasheets. The IPR address, addr, will be set from ipr_idx via the
- * map_ipridx_to_addr function.
- */
-struct ipr_data {
- unsigned int irq;
- int ipr_idx; /* Index for the IPR registered */
- int shift; /* Number of bits to shift the data */
- int priority; /* The priority */
- unsigned int addr; /* Address of Interrupt Priority Register */
-};
-
-/*
- * Given an IPR IDX, map the value to an IPR register address.
- */
-unsigned int map_ipridx_to_addr(int idx);
-
-/*
- * Enable individual interrupt mode for external IPR IRQs.
- */
-void ipr_irq_enable_irlm(void);
-
-/*
- * Function for "on chip support modules".
- */
-void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs);
void make_imask_irq(unsigned int irq);
-void init_IRQ_ipr(void);
static inline int generic_irq_demux(int irq)
{
diff --git a/include/asm-sh/sh03/io.h b/include/asm-sh/sh03/io.h
index df3b187ef883..4ff1eb900301 100644
--- a/include/asm-sh/sh03/io.h
+++ b/include/asm-sh/sh03/io.h
@@ -14,22 +14,18 @@
#define INTC_IPRD 0xffd00010UL
#define IRL0_IRQ 2
-#define IRL0_IPR_ADDR INTC_IPRD
#define IRL0_IPR_POS 3
#define IRL0_PRIORITY 13
#define IRL1_IRQ 5
-#define IRL1_IPR_ADDR INTC_IPRD
#define IRL1_IPR_POS 2
#define IRL1_PRIORITY 10
#define IRL2_IRQ 8
-#define IRL2_IPR_ADDR INTC_IPRD
#define IRL2_IPR_POS 1
#define IRL2_PRIORITY 7
#define IRL3_IRQ 11
-#define IRL3_IPR_ADDR INTC_IPRD
#define IRL3_IPR_POS 0
#define IRL3_PRIORITY 4
diff --git a/include/asm-sh/snapgear.h b/include/asm-sh/snapgear.h
index 2d712e72c9e5..3554e3a74e99 100644
--- a/include/asm-sh/snapgear.h
+++ b/include/asm-sh/snapgear.h
@@ -20,22 +20,18 @@
*/
#define IRL0_IRQ 2
-#define IRL0_IPR_ADDR INTC_IPRD
#define IRL0_IPR_POS 3
#define IRL0_PRIORITY 13
#define IRL1_IRQ 5
-#define IRL1_IPR_ADDR INTC_IPRD
#define IRL1_IPR_POS 2
#define IRL1_PRIORITY 10
#define IRL2_IRQ 8
-#define IRL2_IPR_ADDR INTC_IPRD
#define IRL2_IPR_POS 1
#define IRL2_PRIORITY 7
#define IRL3_IRQ 11
-#define IRL3_IPR_ADDR INTC_IPRD
#define IRL3_IPR_POS 0
#define IRL3_PRIORITY 4
#endif