Commit 68abdbbb authored by Magnus Damm's avatar Magnus Damm Committed by Paul Mundt

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: default avatarMagnus Damm <damm@igel.co.jp>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 50f63f25
...@@ -15,46 +15,7 @@ ...@@ -15,46 +15,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/se.h> #include <asm/se.h>
/* static struct ipr_data ipr_irq_table[] = {
* 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[] = {
/* /*
* Super I/O (Just mimic PC): * Super I/O (Just mimic PC):
* 1: keyboard * 1: keyboard
...@@ -68,46 +29,67 @@ static struct ipr_data se770x_ipr_map[] = { ...@@ -68,46 +29,67 @@ static struct ipr_data se770x_ipr_map[] = {
*/ */
#if defined(CONFIG_CPU_SUBTYPE_SH7705) #if defined(CONFIG_CPU_SUBTYPE_SH7705)
/* This is default value */ /* This is default value */
{ 13, 0, 8, 0x0f-13 ,BCR_ILCRA}, { 13, 0, 8, 0x0f-13, },
{ 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA}, { 5 , 0, 4, 0x0f- 5, },
{ 10, 0, 0, 0x0f-10, BCR_ILCRB}, { 10, 1, 0, 0x0f-10, },
{ 7 , 0, 4, 0x0f- 7, BCR_ILCRC}, { 7 , 2, 4, 0x0f- 7, },
{ 3 , 0, 0, 0x0f- 3, BCR_ILCRC}, { 3 , 2, 0, 0x0f- 3, },
{ 1 , 0, 12, 0x0f- 1, BCR_ILCRD}, { 1 , 3, 12, 0x0f- 1, },
{ 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */ { 12, 3, 4, 0x0f-12, }, /* LAN */
{ 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */ { 2 , 4, 8, 0x0f- 2, }, /* PCIRQ2 */
{ 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */ { 6 , 4, 4, 0x0f- 6, }, /* PCIRQ1 */
{ 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */ { 14, 4, 0, 0x0f-14, }, /* PCIRQ0 */
{ 0 , 0, 12, 0x0f , BCR_ILCRF}, { 0 , 5, 12, 0x0f , },
{ 4 , 0, 4, 0x0f- 4, BCR_ILCRF}, { 4 , 5, 4, 0x0f- 4, },
{ 8 , 0, 12, 0x0f- 8, BCR_ILCRG}, { 8 , 6, 12, 0x0f- 8, },
{ 9 , 0, 8, 0x0f- 9, BCR_ILCRG}, { 9 , 6, 8, 0x0f- 9, },
{ 11, 0, 4, 0x0f-11, BCR_ILCRG}, { 11, 6, 4, 0x0f-11, },
#else #else
{ 14, 0, 8, 0x0f-14 ,BCR_ILCRA}, { 14, 0, 8, 0x0f-14, },
{ 12, 0, 4, 0x0f-12 ,BCR_ILCRA}, { 12, 0, 4, 0x0f-12, },
{ 8, 0, 4, 0x0f- 8 ,BCR_ILCRB}, { 8, 1, 4, 0x0f- 8, },
{ 6, 0, 12, 0x0f- 6 ,BCR_ILCRC}, { 6, 2, 12, 0x0f- 6, },
{ 5, 0, 8, 0x0f- 5 ,BCR_ILCRC}, { 5, 2, 8, 0x0f- 5, },
{ 4, 0, 4, 0x0f- 4 ,BCR_ILCRC}, { 4, 2, 4, 0x0f- 4, },
{ 3, 0, 0, 0x0f- 3 ,BCR_ILCRC}, { 3, 2, 0, 0x0f- 3, },
{ 1, 0, 12, 0x0f- 1 ,BCR_ILCRD}, { 1, 3, 12, 0x0f- 1, },
#if defined(CONFIG_STNIC) #if defined(CONFIG_STNIC)
/* ST NIC */ /* ST NIC */
{ 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */ { 10, 3, 4, 0x0f-10, }, /* LAN */
#endif #endif
/* MRSHPC IRQs setting */ /* MRSHPC IRQs setting */
{ 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */ { 0, 4, 12, 0x0f- 0, }, /* PCIRQ3 */
{ 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */ { 11, 4, 8, 0x0f-11, }, /* PCIRQ2 */
{ 9, 0, 4, 0x0f- 9 ,BCR_ILCRE}, /* PCIRQ1 */ { 9, 4, 4, 0x0f- 9, }, /* PCIRQ1 */
{ 7, 0, 0, 0x0f- 7 ,BCR_ILCRE}, /* PCIRQ0 */ { 7, 4, 0, 0x0f- 7, }, /* PCIRQ0 */
/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
/* NOTE: #2 and #13 are not used on PC */ /* NOTE: #2 and #13 are not used on PC */
{ 13, 0, 4, 0x0f-13 ,BCR_ILCRG}, /* SLOTIRQ2 */ { 13, 6, 4, 0x0f-13, }, /* SLOTIRQ2 */
{ 2, 0, 0, 0x0f- 2 ,BCR_ILCRG}, /* SLOTIRQ1 */ { 2, 6, 0, 0x0f- 2, }, /* SLOTIRQ1 */
#endif #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 * Initialize IRQ setting
*/ */
...@@ -122,5 +104,5 @@ void __init init_se_IRQ(void) ...@@ -122,5 +104,5 @@ void __init init_se_IRQ(void)
ctrl_outw(0, BCR_ILCRF); ctrl_outw(0, BCR_ILCRF);
ctrl_outw(0, BCR_ILCRG); ctrl_outw(0, BCR_ILCRG);
make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map)); register_ipr_controller(&ipr_irq_desc);
} }
...@@ -19,15 +19,24 @@ ...@@ -19,15 +19,24 @@
#define INTC_INTMSK0 0xFFD00044 #define INTC_INTMSK0 0xFFD00044
#define INTC_INTMSKCLR0 0xFFD00064 #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) 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 ); ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr );
} }
static void enable_se7722_irq(unsigned int irq) 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 ); ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr );
} }
...@@ -38,7 +47,7 @@ static struct irq_chip se7722_irq_chip __read_mostly = { ...@@ -38,7 +47,7 @@ static struct irq_chip se7722_irq_chip __read_mostly = {
.mask_ack = disable_se7722_irq, .mask_ack = disable_se7722_irq,
}; };
static struct ipr_data ipr_irq_table[] = { static struct se7722_data ipr_irq_table[] = {
/* irq ,idx,sft, priority , addr */ /* irq ,idx,sft, priority , addr */
{ MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } , { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } ,
{ MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } , { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } ,
......
...@@ -14,44 +14,31 @@ ...@@ -14,44 +14,31 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/se7751.h> #include <asm/se7751.h>
static struct ipr_data se7751_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
/* Leave old Solution Engine code in for reference. */ { 13, 3, 3, 2 },
#if defined(CONFIG_SH_SOLUTION_ENGINE) /* Add additional entries here as drivers are added and tested. */
/* };
* 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 },
{ 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 */ static struct ipr_desc ipr_irq_desc = {
{ 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */ .ipr_offsets = ipr_offsets,
{ 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */ .nr_offsets = ARRAY_SIZE(ipr_offsets),
{ 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */
/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ .ipr_data = ipr_irq_table,
/* NOTE: #2 and #13 are not used on PC */ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
{ 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */
{ 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */ .chip = {
#elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) .name = "IPR-se7751",
{ 13, BCR_ILCRD, 3, 2 }, },
/* Add additional entries here as drivers are added and tested. */
#endif
}; };
/* /*
...@@ -59,5 +46,5 @@ static struct ipr_data se7751_ipr_map[] = { ...@@ -59,5 +46,5 @@ static struct ipr_data se7751_ipr_map[] = {
*/ */
void __init init_7751se_IRQ(void) void __init init_7751se_IRQ(void)
{ {
make_ipr_irq(se7751_ipr_map, ARRAY_SIZE(se7751_ipr_map)); register_ipr_controller(&ipr_irq_desc);
} }
...@@ -15,17 +15,33 @@ ...@@ -15,17 +15,33 @@
#include <asm/sh03/sh03.h> #include <asm/sh03/sh03.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
static struct ipr_data sh03_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
{ IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY },
{ IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY },
{ IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY },
{ IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_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) static void __init init_sh03_IRQ(void)
{ {
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 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; extern void *cf_io_base;
......
...@@ -6,28 +6,44 @@ ...@@ -6,28 +6,44 @@
* SHMIN Support. * SHMIN Support.
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/irq.h>
#include <asm/machvec.h> #include <asm/machvec.h>
#include <asm/shmin.h> #include <asm/shmin.h>
#include <asm/clock.h> #include <asm/clock.h>
#include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#define PFC_PHCR 0xa400010eUL #define PFC_PHCR 0xa400010eUL
#define INTC_ICR1 0xa4000010UL #define INTC_ICR1 0xa4000010UL
#define INTC_IPRC 0xa4000016UL #define INTC_IPRC 0xa4000016UL
static struct ipr_data shmin_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
{ .irq=32, .addr=INTC_IPRC, .shift= 0, .priority=0 }, { 32, 0, 0, 0 },
{ .irq=33, .addr=INTC_IPRC, .shift= 4, .priority=0 }, { 33, 0, 4, 0 },
{ .irq=34, .addr=INTC_IPRC, .shift= 8, .priority=8 }, { 34, 0, 8, 8 },
{ .irq=35, .addr=INTC_IPRC, .shift=12, .priority=0 }, { 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) static void __init init_shmin_irq(void)
{ {
ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ
ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. 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) static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size)
......
...@@ -68,11 +68,27 @@ module_init(eraseconfig_init); ...@@ -68,11 +68,27 @@ module_init(eraseconfig_init);
* IRL3 = crypto * IRL3 = crypto
*/ */
static struct ipr_data snapgear_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY },
make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY },
make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY },
make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_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) static void __init init_snapgear_IRQ(void)
...@@ -82,7 +98,7 @@ static void __init init_snapgear_IRQ(void) ...@@ -82,7 +98,7 @@ static void __init init_snapgear_IRQ(void)
printk("Setup SnapGear IRQ/IPR ...\n"); printk("Setup SnapGear IRQ/IPR ...\n");
make_ipr_irq(snapgear_ipr_map, ARRAY_SIZE(snapgear_ipr_map)); register_ipr_controller(&ipr_irq_desc);
} }
/* /*
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <asm/titan.h> #include <asm/titan.h>
#include <asm/io.h> #include <asm/io.h>
static struct ipr_data titan_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR idx, shift, prio */ /* IRQ, IPR idx, shift, prio */
{ TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */ { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */
{ TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */ { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */
...@@ -20,12 +20,30 @@ static struct ipr_data titan_ipr_map[] = { ...@@ -20,12 +20,30 @@ static struct ipr_data titan_ipr_map[] = {
{ TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */ { 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) static void __init init_titan_irq(void)
{ {
/* enable individual interrupt mode for externals */ /* enable individual interrupt mode for externals */
ipr_irq_enable_irlm(); ipr_irq_enable_irlm();
/* register ipr irqs */ /* 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 = { static struct sh_machine_vector mv_titan __initmv = {
......
...@@ -22,58 +22,57 @@ ...@@ -22,58 +22,57 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/interrupt.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) static void disable_ipr_irq(unsigned int irq)
{ {
struct ipr_data *p = get_irq_chip_data(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 */ /* 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) static void enable_ipr_irq(unsigned int irq)
{ {
struct ipr_data *p = get_irq_chip_data(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 */ /* 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", * The shift value is now the number of bits to shift, not the number of
.mask = disable_ipr_irq, * bits/4. This is to make it easier to read the value directly from the
.unmask = enable_ipr_irq, * datasheets. The IPR address is calculated using the ipr_offset table.
.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;
}
void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) void register_ipr_controller(struct ipr_desc *desc)
{ {
int i; int i;
for (i = 0; i < nr_irqs; i++) { desc->chip.mask = disable_ipr_irq;
unsigned int irq = table[i].irq; desc->chip.unmask = enable_ipr_irq;
desc->chip.mask_ack = disable_ipr_irq;
if (!irq) for (i = 0; i < desc->nr_irqs; i++) {
irq = table[i].irq = i; struct ipr_data *p = desc->ipr_data + i;
/* could the IPR index be mapped, if not we ignore this */ BUG_ON(p->ipr_idx >= desc->nr_offsets);
if (!table[i].addr) { BUG_ON(!desc->ipr_offsets[p->ipr_idx]);
table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
if (!table[i].addr)
continue;
}
disable_irq_nosync(irq); disable_irq_nosync(p->irq);
set_irq_chip_and_handler_name(irq, &ipr_irq_chip, set_irq_chip_and_handler_name(p->irq, &desc->chip,
handle_level_irq, "level"); handle_level_irq, "level");
set_irq_chip_data(irq, &table[i]); set_irq_chip_data(p->irq, p);
enable_ipr_irq(irq); disable_ipr_irq(p->irq);
} }
} }
EXPORT_SYMBOL(make_ipr_irq);
EXPORT_SYMBOL(register_ipr_controller);
#if !defined(CONFIG_CPU_HAS_PINT_IRQ) #if !defined(CONFIG_CPU_HAS_PINT_IRQ)
int ipr_irq_demux(int irq) int ipr_irq_demux(int irq)
......
...@@ -52,7 +52,7 @@ static int __init sh7619_devices_setup(void) ...@@ -52,7 +52,7 @@ static int __init sh7619_devices_setup(void)
} }
__initcall(sh7619_devices_setup); __initcall(sh7619_devices_setup);
static struct ipr_data sh7619_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
{ 86, 0, 4, 2 }, /* CMI0 */ { 86, 0, 4, 2 }, /* CMI0 */
{ 88, 1, 12, 3 }, /* SCIF0_ERI */ { 88, 1, 12, 3 }, /* SCIF0_ERI */
{ 89, 1, 12, 3 }, /* SCIF0_RXI */ { 89, 1, 12, 3 }, /* SCIF0_RXI */
...@@ -68,7 +68,7 @@ static struct ipr_data sh7619_ipr_map[] = { ...@@ -68,7 +68,7 @@ static struct ipr_data sh7619_ipr_map[] = {
{ 99, 1, 4, 3 }, /* SCIF2_TXI */ { 99, 1, 4, 3 }, /* SCIF2_TXI */
}; };
static unsigned int ipr_offsets[] = { static unsigned long ipr_offsets[] = {
0xf8080000, /* IPRC */ 0xf8080000, /* IPRC */
0xf8080002, /* IPRD */ 0xf8080002, /* IPRD */
0xf8080004, /* IPRE */ 0xf8080004, /* IPRE */
...@@ -76,15 +76,19 @@ static unsigned int ipr_offsets[] = { ...@@ -76,15 +76,19 @@ static unsigned int ipr_offsets[] = {
0xf8080008, /* IPRG */ 0xf8080008, /* IPRG */
}; };
/* given the IPR index return the address of the IPR register */ static struct ipr_desc ipr_irq_desc = {
unsigned int map_ipridx_to_addr(int idx) .ipr_offsets = ipr_offsets,
{ .nr_offsets = ARRAY_SIZE(ipr_offsets),
if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
return 0; .ipr_data = ipr_irq_table,
return ipr_offsets[idx]; .nr_irqs = ARRAY_SIZE(ipr_irq_table),
}
.chip = {
.name = "IPR-sh7619",
},
};
void __init init_IRQ_ipr(void) void __init init_IRQ_ipr(void)
{ {
make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map)); register_ipr_controller(&ipr_irq_desc);
} }
...@@ -57,7 +57,7 @@ static int __init sh7206_devices_setup(void) ...@@ -57,7 +57,7 @@ static int __init sh7206_devices_setup(void)
} }
__initcall(sh7206_devices_setup); __initcall(sh7206_devices_setup);
static struct ipr_data sh7206_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
{ 140, 7, 12, 2 }, /* CMI0 */ { 140, 7, 12, 2 }, /* CMI0 */
{ 164, 8, 4, 2 }, /* MTU2_TGI1A */ { 164, 8, 4, 2 }, /* MTU2_TGI1A */
{ 240, 13, 12, 3 }, /* SCIF0_BRI */ { 240, 13, 12, 3 }, /* SCIF0_BRI */
...@@ -78,7 +78,7 @@ static struct ipr_data sh7206_ipr_map[] = { ...@@ -78,7 +78,7 @@ static struct ipr_data sh7206_ipr_map[] = {
{ 255, 13, 0, 3 }, /* SCIF3_TXI */ { 255, 13, 0, 3 }, /* SCIF3_TXI */
}; };
static unsigned int ipr_offsets[] = { static unsigned long ipr_offsets[] = {
0xfffe0818, /* IPR01 */ 0xfffe0818, /* IPR01 */
0xfffe081a, /* IPR02 */ 0xfffe081a, /* IPR02 */
0, /* unused */ 0, /* unused */
...@@ -95,15 +95,19 @@ static unsigned int ipr_offsets[] = { ...@@ -95,15 +95,19 @@ static unsigned int ipr_offsets[] = {
0xfffe0c10, /* IPR14 */ 0xfffe0c10, /* IPR14 */
}; };
/* given the IPR index return the address of the IPR register */ static struct ipr_desc ipr_irq_desc = {
unsigned int map_ipridx_to_addr(int idx) .ipr_offsets = ipr_offsets,
{ .nr_offsets = ARRAY_SIZE(ipr_offsets),
if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
return 0; .ipr_data = ipr_irq_table,
return ipr_offsets[idx]; .nr_irqs = ARRAY_SIZE(ipr_irq_table),
}
.chip = {
.name = "IPR-sh7206",
},
};
void __init init_IRQ_ipr(void) void __init init_IRQ_ipr(void)
{ {
make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map)); register_ipr_controller(&ipr_irq_desc);
} }
...@@ -48,7 +48,7 @@ static int __init sh7705_devices_setup(void) ...@@ -48,7 +48,7 @@ static int __init sh7705_devices_setup(void)
} }
__initcall(sh7705_devices_setup); __initcall(sh7705_devices_setup);
static struct ipr_data sh7705_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, priority */ /* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/ { 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 8, 2 }, /* TMU1 TUNI */ { 17, 0, 8, 2 }, /* TMU1 TUNI */
...@@ -70,25 +70,29 @@ static struct ipr_data sh7705_ipr_map[] = { ...@@ -70,25 +70,29 @@ static struct ipr_data sh7705_ipr_map[] = {
}; };
static unsigned long ipr_offsets[] = { static unsigned long ipr_offsets[] = {
0xFFFFFEE2 /* 0: IPRA */ 0xFFFFFEE2, /* 0: IPRA */
, 0xFFFFFEE4 /* 1: IPRB */ 0xFFFFFEE4, /* 1: IPRB */
, 0xA4000016 /* 2: IPRC */ 0xA4000016, /* 2: IPRC */
, 0xA4000018 /* 3: IPRD */ 0xA4000018, /* 3: IPRD */
, 0xA400001A /* 4: IPRE */ 0xA400001A, /* 4: IPRE */
, 0xA4080000 /* 5: IPRF */ 0xA4080000, /* 5: IPRF */
, 0xA4080002 /* 6: IPRG */ 0xA4080002, /* 6: IPRG */
, 0xA4080004 /* 7: IPRH */ 0xA4080004, /* 7: IPRH */
}; };
/* given the IPR index return the address of the IPR register */ static struct ipr_desc ipr_irq_desc = {
unsigned int map_ipridx_to_addr(int idx) .ipr_offsets = ipr_offsets,
{ .nr_offsets = ARRAY_SIZE(ipr_offsets),
if (idx >= ARRAY_SIZE(ipr_offsets))
return 0; .ipr_data = ipr_irq_table,
return ipr_offsets[idx]; .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);
} }
...@@ -52,32 +52,66 @@ static int __init sh7709_devices_setup(void) ...@@ -52,32 +52,66 @@ static int __init sh7709_devices_setup(void)
} }
__initcall(sh7709_devices_setup); __initcall(sh7709_devices_setup);
#define IPRx(A,N) .addr=A, .shift=N static struct ipr_data ipr_irq_table[] = {
#define IPRA(N) IPRx(0xfffffee2UL,N) { 16, 0, 12, 2 }, /* TMU TUNI0 */
#define IPRB(N) IPRx(0xfffffee4UL,N) { 17, 0, 8, 4 }, /* TMU TUNI1 */
#define IPRC(N) IPRx(0xa4000016UL,N) { 18, 0, 4, 1 }, /* TMU TUNI1 */
#define IPRD(N) IPRx(0xa4000018UL,N) { 19, 0, 4, 1 }, /* TMU TUNI1 */
#define IPRE(N) IPRx(0xa400001aUL,N) { 20, 0, 0, 2 }, /* RTC CUI */
{ 21, 0, 0, 2 }, /* RTC CUI */
static struct ipr_data sh7709_ipr_map[] = { { 22, 0, 0, 2 }, /* RTC CUI */
[16] = { IPRA(12), 2 }, /* TMU TUNI0 */
[17] = { IPRA(8), 4 }, /* TMU TUNI1 */ { 23, 1, 4, 3 }, /* SCI */
[18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */ { 24, 1, 4, 3 }, /* SCI */
[20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */ { 25, 1, 4, 3 }, /* SCI */
[23 ... 26] = { IPRB(4), 3 }, /* SCI */ { 26, 1, 4, 3 }, /* SCI */
[27] = { IPRB(12), 2 }, /* WDT ITI */ { 27, 1, 12, 3 }, /* WDT ITI */
[32] = { IPRC(0), 1 }, /* IRQ 0 */
[33] = { IPRC(4), 1 }, /* IRQ 1 */ { 32, 2, 0, 1 }, /* IRQ 0 */
[34] = { IPRC(8), 1 }, /* IRQ 2 APM */ { 33, 2, 4, 1 }, /* IRQ 1 */
[35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */ { 34, 2, 8, 1 }, /* IRQ 2 APM */
[36] = { IPRD(0), 1 }, /* IRQ 4 */ { 35, 2, 12, 1 }, /* IRQ 3 TOUCHSCREEN */
[37] = { IPRD(4), 1 }, /* IRQ 5 */
[48 ... 51] = { IPRE(12), 7 }, /* DMA */ { 36, 3, 0, 1 }, /* IRQ 4 */
[52 ... 55] = { IPRE(8), 3 }, /* IRDA */ { 37, 3, 4, 1 }, /* IRQ 5 */
[56 ... 59] = { IPRE(4), 3 }, /* SCIF */
{ 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);
} }
...@@ -49,7 +49,7 @@ static int __init sh7710_devices_setup(void) ...@@ -49,7 +49,7 @@ static int __init sh7710_devices_setup(void)
} }
__initcall(sh7710_devices_setup); __initcall(sh7710_devices_setup);
static struct ipr_data sh7710_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, priority */ /* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/ { 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 8, 2 }, /* TMU1 TUNI */ { 17, 0, 8, 2 }, /* TMU1 TUNI */
...@@ -78,26 +78,30 @@ static struct ipr_data sh7710_ipr_map[] = { ...@@ -78,26 +78,30 @@ static struct ipr_data sh7710_ipr_map[] = {
}; };
static unsigned long ipr_offsets[] = { static unsigned long ipr_offsets[] = {
0xA414FEE2 /* 0: IPRA */ 0xA414FEE2, /* 0: IPRA */
, 0xA414FEE4 /* 1: IPRB */ 0xA414FEE4, /* 1: IPRB */
, 0xA4140016 /* 2: IPRC */ 0xA4140016, /* 2: IPRC */
, 0xA4140018 /* 3: IPRD */ 0xA4140018, /* 3: IPRD */
, 0xA414001A /* 4: IPRE */ 0xA414001A, /* 4: IPRE */
, 0xA4080000 /* 5: IPRF */ 0xA4080000, /* 5: IPRF */
, 0xA4080002 /* 6: IPRG */ 0xA4080002, /* 6: IPRG */
, 0xA4080004 /* 7: IPRH */ 0xA4080004, /* 7: IPRH */
, 0xA4080006 /* 8: IPRI */ 0xA4080006, /* 8: IPRI */
}; };
/* given the IPR index return the address of the IPR register */ static struct ipr_desc ipr_irq_desc = {
unsigned int map_ipridx_to_addr(int idx) .ipr_offsets = ipr_offsets,
{ .nr_offsets = ARRAY_SIZE(ipr_offsets),
if (idx >= ARRAY_SIZE(ipr_offsets))
return 0; .ipr_data = ipr_irq_table,
return ipr_offsets[idx]; .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);
} }
...@@ -82,7 +82,7 @@ static int __init sh7750_devices_setup(void) ...@@ -82,7 +82,7 @@ static int __init sh7750_devices_setup(void)
} }
__initcall(sh7750_devices_setup); __initcall(sh7750_devices_setup);
static struct ipr_data sh7750_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, priority */ /* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/ { 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 12, 2 }, /* TMU1 TUNI */ { 17, 0, 12, 2 }, /* TMU1 TUNI */
...@@ -106,8 +106,27 @@ static struct ipr_data sh7750_ipr_map[] = { ...@@ -106,8 +106,27 @@ static struct ipr_data sh7750_ipr_map[] = {
{ 38, 2, 8, 7 }, /* DMAC DMAE */ { 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 #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 */ { 44, 2, 8, 7 }, /* DMAC DMTE4 */
{ 45, 2, 8, 7 }, /* DMAC DMTE5 */ { 45, 2, 8, 7 }, /* DMAC DMTE5 */
{ 46, 2, 8, 7 }, /* DMAC DMTE6 */ { 46, 2, 8, 7 }, /* DMAC DMTE6 */
...@@ -118,21 +137,26 @@ static struct ipr_data sh7751_ipr_map[] = { ...@@ -118,21 +137,26 @@ static struct ipr_data sh7751_ipr_map[] = {
/*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */
/*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
}; };
#endif
static unsigned long ipr_offsets[] = { static struct ipr_desc ipr_irq_desc_sh7751 = {
0xffd00004UL, /* 0: IPRA */ .ipr_offsets = ipr_offsets,
0xffd00008UL, /* 1: IPRB */ .nr_offsets = ARRAY_SIZE(ipr_offsets),
0xffd0000cUL, /* 2: IPRC */
0xffd00010UL, /* 3: IPRD */ .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 */ void __init init_IRQ_ipr(void)
unsigned int map_ipridx_to_addr(int idx)
{ {
if (idx >= ARRAY_SIZE(ipr_offsets)) register_ipr_controller(&ipr_irq_desc);
return 0; #ifdef CONFIG_CPU_SUBTYPE_SH7751
return ipr_offsets[idx]; register_ipr_controller(&ipr_irq_desc_sh7751);
#endif
} }
#define INTC_ICR 0xffd00000UL #define INTC_ICR 0xffd00000UL
...@@ -143,11 +167,3 @@ void ipr_irq_enable_irlm(void) ...@@ -143,11 +167,3 @@ void ipr_irq_enable_irlm(void)
{ {
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 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
}
...@@ -109,7 +109,12 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { ...@@ -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 */ /* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/ { 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 8, 2 }, /* TMU1 TUNI */ { 17, 0, 8, 2 }, /* TMU1 TUNI */
...@@ -146,20 +151,19 @@ static unsigned long ipr_offsets[] = { ...@@ -146,20 +151,19 @@ static unsigned long ipr_offsets[] = {
0xffd00010UL, /* 3: IPRD */ 0xffd00010UL, /* 3: IPRD */
}; };
/* given the IPR index return the address of the IPR register */ static struct ipr_desc ipr_irq_desc = {
unsigned int map_ipridx_to_addr(int idx) .ipr_offsets = ipr_offsets,
{ .nr_offsets = ARRAY_SIZE(ipr_offsets),
if (idx >= ARRAY_SIZE(ipr_offsets))
return 0;
return ipr_offsets[idx];
}
void __init init_IRQ_intc2(void) .ipr_data = ipr_irq_table,
{ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
register_intc2_controller(&intc2_irq_desc);
} .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);
} }
...@@ -44,7 +44,7 @@ static int __init sh7722_devices_setup(void) ...@@ -44,7 +44,7 @@ static int __init sh7722_devices_setup(void)
} }
__initcall(sh7722_devices_setup); __initcall(sh7722_devices_setup);
static struct ipr_data sh7722_ipr_map[] = { static struct ipr_data ipr_irq_table[] = {
/* IRQ, IPR-idx, shift, prio */ /* IRQ, IPR-idx, shift, prio */
{ 16, 0, 12, 2 }, /* TMU0 */ { 16, 0, 12, 2 }, /* TMU0 */
{ 17, 0, 8, 2 }, /* TMU1 */ { 17, 0, 8, 2 }, /* TMU1 */
...@@ -69,16 +69,21 @@ static unsigned long ipr_offsets[] = { ...@@ -69,16 +69,21 @@ static unsigned long ipr_offsets[] = {
0xa408002c, /* 11: IPRL */ 0xa408002c, /* 11: IPRL */
}; };
unsigned int map_ipridx_to_addr(int idx) static struct ipr_desc ipr_irq_desc = {
{ .ipr_offsets = ipr_offsets,
if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) .nr_offsets = ARRAY_SIZE(ipr_offsets),
return 0;
return ipr_offsets[idx]; .ipr_data = ipr_irq_table,
} .nr_irqs = ARRAY_SIZE(ipr_irq_table),
.chip = {
.name = "IPR-sh7722",
},
};
void __init init_IRQ_ipr(void) 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) void __init plat_mem_setup(void)
......
...@@ -24,4 +24,27 @@ struct intc2_desc { ...@@ -24,4 +24,27 @@ struct intc2_desc {
void register_intc2_controller(struct intc2_desc *); void register_intc2_controller(struct intc2_desc *);
void init_IRQ_intc2(void); 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 */ #endif /* __ASM_SH_HW_IRQ_H */
...@@ -31,37 +31,7 @@ extern unsigned short *irq_mask_register; ...@@ -31,37 +31,7 @@ extern unsigned short *irq_mask_register;
* PINT IRQs * PINT IRQs
*/ */
void init_IRQ_pint(void); 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 make_imask_irq(unsigned int irq);
void init_IRQ_ipr(void);
static inline int generic_irq_demux(int irq) static inline int generic_irq_demux(int irq)
{ {
......
...@@ -14,22 +14,18 @@ ...@@ -14,22 +14,18 @@
#define INTC_IPRD 0xffd00010UL #define INTC_IPRD 0xffd00010UL
#define IRL0_IRQ 2 #define IRL0_IRQ 2
#define IRL0_IPR_ADDR INTC_IPRD
#define IRL0_IPR_POS 3 #define IRL0_IPR_POS 3
#define IRL0_PRIORITY 13 #define IRL0_PRIORITY 13
#define IRL1_IRQ 5 #define IRL1_IRQ 5
#define IRL1_IPR_ADDR INTC_IPRD
#define IRL1_IPR_POS 2 #define IRL1_IPR_POS 2
#define IRL1_PRIORITY 10 #define IRL1_PRIORITY 10
#define IRL2_IRQ 8 #define IRL2_IRQ 8
#define IRL2_IPR_ADDR INTC_IPRD
#define IRL2_IPR_POS 1 #define IRL2_IPR_POS 1
#define IRL2_PRIORITY 7 #define IRL2_PRIORITY 7
#define IRL3_IRQ 11 #define IRL3_IRQ 11
#define IRL3_IPR_ADDR INTC_IPRD
#define IRL3_IPR_POS 0 #define IRL3_IPR_POS 0
#define IRL3_PRIORITY 4 #define IRL3_PRIORITY 4
......
...@@ -20,22 +20,18 @@ ...@@ -20,22 +20,18 @@
*/ */
#define IRL0_IRQ 2 #define IRL0_IRQ 2
#define IRL0_IPR_ADDR INTC_IPRD
#define IRL0_IPR_POS 3 #define IRL0_IPR_POS 3
#define IRL0_PRIORITY 13 #define IRL0_PRIORITY 13
#define IRL1_IRQ 5 #define IRL1_IRQ 5
#define IRL1_IPR_ADDR INTC_IPRD
#define IRL1_IPR_POS 2 #define IRL1_IPR_POS 2
#define IRL1_PRIORITY 10 #define IRL1_PRIORITY 10
#define IRL2_IRQ 8 #define IRL2_IRQ 8
#define IRL2_IPR_ADDR INTC_IPRD
#define IRL2_IPR_POS 1 #define IRL2_IPR_POS 1
#define IRL2_PRIORITY 7 #define IRL2_PRIORITY 7
#define IRL3_IRQ 11 #define IRL3_IRQ 11
#define IRL3_IPR_ADDR INTC_IPRD
#define IRL3_IPR_POS 0 #define IRL3_IPR_POS 0
#define IRL3_PRIORITY 4 #define IRL3_PRIORITY 4
#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