sh: mach-se: Convert SE7343 FPGA to dynamic IRQ allocation.
This gets rid of the arbitrary set of vectors used by the SE7722 FPGA interrupt controller and switches over to a completely dynamic set. No assumptions regarding a contiguous range are made, and the platform resources themselves need to be filled in lazily. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
8c0b8139c8
commit
53e6d8e006
|
@ -16,15 +16,17 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <mach-se/mach/se7343.h>
|
#include <mach-se/mach/se7343.h>
|
||||||
|
|
||||||
|
unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, };
|
||||||
|
|
||||||
static void disable_se7343_irq(unsigned int irq)
|
static void disable_se7343_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
unsigned int bit = irq - SE7343_FPGA_IRQ_BASE;
|
unsigned int bit = (unsigned int)get_irq_chip_data(irq);
|
||||||
ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
|
ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_se7343_irq(unsigned int irq)
|
static void enable_se7343_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
unsigned int bit = irq - SE7343_FPGA_IRQ_BASE;
|
unsigned int bit = (unsigned int)get_irq_chip_data(irq);
|
||||||
ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
|
ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,18 +40,15 @@ static struct irq_chip se7343_irq_chip __read_mostly = {
|
||||||
static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
|
static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
|
||||||
{
|
{
|
||||||
unsigned short intv = ctrl_inw(PA_CPLD_ST);
|
unsigned short intv = ctrl_inw(PA_CPLD_ST);
|
||||||
struct irq_desc *ext_desc;
|
unsigned int ext_irq = 0;
|
||||||
unsigned int ext_irq = SE7343_FPGA_IRQ_BASE;
|
|
||||||
|
|
||||||
intv &= (1 << SE7343_FPGA_IRQ_NR) - 1;
|
intv &= (1 << SE7343_FPGA_IRQ_NR) - 1;
|
||||||
|
|
||||||
while (intv) {
|
for (; intv; intv >>= 1, ext_irq++) {
|
||||||
if (intv & 1) {
|
if (!(intv & 1))
|
||||||
ext_desc = irq_desc + ext_irq;
|
continue;
|
||||||
handle_level_irq(ext_irq, ext_desc);
|
|
||||||
}
|
generic_handle_irq(se7343_fpga_irq[ext_irq]);
|
||||||
intv >>= 1;
|
|
||||||
ext_irq++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,16 +57,24 @@ static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
|
||||||
*/
|
*/
|
||||||
void __init init_7343se_IRQ(void)
|
void __init init_7343se_IRQ(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i, irq;
|
||||||
|
|
||||||
ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */
|
ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */
|
||||||
ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
|
ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
|
||||||
|
|
||||||
for (i = 0; i < SE7343_FPGA_IRQ_NR; i++)
|
for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) {
|
||||||
set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i,
|
irq = create_irq();
|
||||||
|
if (irq < 0)
|
||||||
|
return;
|
||||||
|
se7343_fpga_irq[i] = irq;
|
||||||
|
|
||||||
|
set_irq_chip_and_handler_name(se7343_fpga_irq[i],
|
||||||
&se7343_irq_chip,
|
&se7343_irq_chip,
|
||||||
handle_level_irq, "level");
|
handle_level_irq, "level");
|
||||||
|
|
||||||
|
set_irq_chip_data(se7343_fpga_irq[i], (void *)i);
|
||||||
|
}
|
||||||
|
|
||||||
set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux);
|
set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux);
|
||||||
set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
|
set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
|
||||||
set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux);
|
set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux);
|
||||||
|
|
|
@ -82,7 +82,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
|
||||||
.mapbase = 0x16000000,
|
.mapbase = 0x16000000,
|
||||||
.regshift = 1,
|
.regshift = 1,
|
||||||
.flags = ST16C2550C_FLAGS,
|
.flags = ST16C2550C_FLAGS,
|
||||||
.irq = UARTA_IRQ,
|
|
||||||
.uartclk = 7372800,
|
.uartclk = 7372800,
|
||||||
},
|
},
|
||||||
[1] = {
|
[1] = {
|
||||||
|
@ -90,7 +89,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
|
||||||
.mapbase = 0x17000000,
|
.mapbase = 0x17000000,
|
||||||
.regshift = 1,
|
.regshift = 1,
|
||||||
.flags = ST16C2550C_FLAGS,
|
.flags = ST16C2550C_FLAGS,
|
||||||
.irq = UARTB_IRQ,
|
|
||||||
.uartclk = 7372800,
|
.uartclk = 7372800,
|
||||||
},
|
},
|
||||||
{ },
|
{ },
|
||||||
|
@ -121,7 +119,7 @@ static struct resource usb_resources[] = {
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
[2] = {
|
[2] = {
|
||||||
.start = USB_IRQ,
|
/* Filled in later */
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -138,8 +136,8 @@ static struct isp116x_platform_data usb_platform_data = {
|
||||||
static struct platform_device usb_device = {
|
static struct platform_device usb_device = {
|
||||||
.name = "isp116x-hcd",
|
.name = "isp116x-hcd",
|
||||||
.id = -1,
|
.id = -1,
|
||||||
.num_resources = ARRAY_SIZE(usb_resources),
|
.num_resources = ARRAY_SIZE(usb_resources),
|
||||||
.resource = usb_resources,
|
.resource = usb_resources,
|
||||||
.dev = {
|
.dev = {
|
||||||
.platform_data = &usb_platform_data,
|
.platform_data = &usb_platform_data,
|
||||||
},
|
},
|
||||||
|
@ -155,6 +153,13 @@ static struct platform_device *sh7343se_platform_devices[] __initdata = {
|
||||||
|
|
||||||
static int __init sh7343se_devices_setup(void)
|
static int __init sh7343se_devices_setup(void)
|
||||||
{
|
{
|
||||||
|
/* Wire-up dynamic vectors */
|
||||||
|
serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA];
|
||||||
|
serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB];
|
||||||
|
|
||||||
|
usb_resources[2].start = usb_resources[2].end =
|
||||||
|
se7343_fpga_irq[SE7343_FPGA_IRQ_USB];
|
||||||
|
|
||||||
return platform_add_devices(sh7343se_platform_devices,
|
return platform_add_devices(sh7343se_platform_devices,
|
||||||
ARRAY_SIZE(sh7343se_platform_devices));
|
ARRAY_SIZE(sh7343se_platform_devices));
|
||||||
}
|
}
|
||||||
|
@ -179,6 +184,5 @@ static void __init sh7343se_setup(char **cmdline_p)
|
||||||
static struct sh_machine_vector mv_7343se __initmv = {
|
static struct sh_machine_vector mv_7343se __initmv = {
|
||||||
.mv_name = "SolutionEngine 7343",
|
.mv_name = "SolutionEngine 7343",
|
||||||
.mv_setup = sh7343se_setup,
|
.mv_setup = sh7343se_setup,
|
||||||
.mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR,
|
|
||||||
.mv_init_irq = init_7343se_IRQ,
|
.mv_init_irq = init_7343se_IRQ,
|
||||||
};
|
};
|
||||||
|
|
|
@ -94,26 +94,26 @@
|
||||||
|
|
||||||
#define PORT_DRVCR 0xA4050180
|
#define PORT_DRVCR 0xA4050180
|
||||||
|
|
||||||
#define PORT_PADR 0xA4050120
|
#define PORT_PADR 0xA4050120
|
||||||
#define PORT_PBDR 0xA4050122
|
#define PORT_PBDR 0xA4050122
|
||||||
#define PORT_PCDR 0xA4050124
|
#define PORT_PCDR 0xA4050124
|
||||||
#define PORT_PDDR 0xA4050126
|
#define PORT_PDDR 0xA4050126
|
||||||
#define PORT_PEDR 0xA4050128
|
#define PORT_PEDR 0xA4050128
|
||||||
#define PORT_PFDR 0xA405012A
|
#define PORT_PFDR 0xA405012A
|
||||||
#define PORT_PGDR 0xA405012C
|
#define PORT_PGDR 0xA405012C
|
||||||
#define PORT_PHDR 0xA405012E
|
#define PORT_PHDR 0xA405012E
|
||||||
#define PORT_PJDR 0xA4050130
|
#define PORT_PJDR 0xA4050130
|
||||||
#define PORT_PKDR 0xA4050132
|
#define PORT_PKDR 0xA4050132
|
||||||
#define PORT_PLDR 0xA4050134
|
#define PORT_PLDR 0xA4050134
|
||||||
#define PORT_PMDR 0xA4050136
|
#define PORT_PMDR 0xA4050136
|
||||||
#define PORT_PNDR 0xA4050138
|
#define PORT_PNDR 0xA4050138
|
||||||
#define PORT_PQDR 0xA405013A
|
#define PORT_PQDR 0xA405013A
|
||||||
#define PORT_PRDR 0xA405013C
|
#define PORT_PRDR 0xA405013C
|
||||||
#define PORT_PTDR 0xA4050160
|
#define PORT_PTDR 0xA4050160
|
||||||
#define PORT_PUDR 0xA4050162
|
#define PORT_PUDR 0xA4050162
|
||||||
#define PORT_PVDR 0xA4050164
|
#define PORT_PVDR 0xA4050164
|
||||||
#define PORT_PWDR 0xA4050166
|
#define PORT_PWDR 0xA4050166
|
||||||
#define PORT_PYDR 0xA4050168
|
#define PORT_PYDR 0xA4050168
|
||||||
|
|
||||||
#define FPGA_IN 0xb1400000
|
#define FPGA_IN 0xb1400000
|
||||||
#define FPGA_OUT 0xb1400002
|
#define FPGA_OUT 0xb1400002
|
||||||
|
@ -133,18 +133,10 @@
|
||||||
#define SE7343_FPGA_IRQ_UARTB 11
|
#define SE7343_FPGA_IRQ_UARTB 11
|
||||||
|
|
||||||
#define SE7343_FPGA_IRQ_NR 12
|
#define SE7343_FPGA_IRQ_NR 12
|
||||||
#define SE7343_FPGA_IRQ_BASE 120
|
|
||||||
|
|
||||||
#define MRSHPC_IRQ3 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3)
|
|
||||||
#define MRSHPC_IRQ2 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC2)
|
|
||||||
#define MRSHPC_IRQ1 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC1)
|
|
||||||
#define MRSHPC_IRQ0 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0)
|
|
||||||
#define SMC_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC)
|
|
||||||
#define USB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB)
|
|
||||||
#define UARTA_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA)
|
|
||||||
#define UARTB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB)
|
|
||||||
|
|
||||||
/* arch/sh/boards/se/7343/irq.c */
|
/* arch/sh/boards/se/7343/irq.c */
|
||||||
|
extern unsigned int se7343_fpga_irq[];
|
||||||
|
|
||||||
void init_7343se_IRQ(void);
|
void init_7343se_IRQ(void);
|
||||||
|
|
||||||
#endif /* __ASM_SH_HITACHI_SE7343_H */
|
#endif /* __ASM_SH_HITACHI_SE7343_H */
|
||||||
|
|
Loading…
Reference in a new issue