Skip to content

Commit

Permalink
sh: mach-se: Convert SE7343 FPGA to dynamic IRQ allocation.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Mundt committed Jan 12, 2010
1 parent 8c0b813 commit 53e6d8e
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 50 deletions.
35 changes: 21 additions & 14 deletions arch/sh/boards/mach-se/7343/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@
#include <linux/io.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)
{
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);
}

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);
}

Expand All @@ -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)
{
unsigned short intv = ctrl_inw(PA_CPLD_ST);
struct irq_desc *ext_desc;
unsigned int ext_irq = SE7343_FPGA_IRQ_BASE;
unsigned int ext_irq = 0;

intv &= (1 << SE7343_FPGA_IRQ_NR) - 1;

while (intv) {
if (intv & 1) {
ext_desc = irq_desc + ext_irq;
handle_level_irq(ext_irq, ext_desc);
}
intv >>= 1;
ext_irq++;
for (; intv; intv >>= 1, ext_irq++) {
if (!(intv & 1))
continue;

generic_handle_irq(se7343_fpga_irq[ext_irq]);
}
}

Expand All @@ -58,16 +57,24 @@ static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc)
*/
void __init init_7343se_IRQ(void)
{
int i;
int i, irq;

ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */
ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */

for (i = 0; i < SE7343_FPGA_IRQ_NR; i++)
set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i,
for (i = 0; i < SE7343_FPGA_IRQ_NR; 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,
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_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux);
Expand Down
16 changes: 10 additions & 6 deletions arch/sh/boards/mach-se/7343/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,13 @@ static struct plat_serial8250_port serial_platform_data[] = {
.mapbase = 0x16000000,
.regshift = 1,
.flags = ST16C2550C_FLAGS,
.irq = UARTA_IRQ,
.uartclk = 7372800,
},
[1] = {
.iotype = UPIO_MEM,
.mapbase = 0x17000000,
.regshift = 1,
.flags = ST16C2550C_FLAGS,
.irq = UARTB_IRQ,
.uartclk = 7372800,
},
{ },
Expand Down Expand Up @@ -121,7 +119,7 @@ static struct resource usb_resources[] = {
.flags = IORESOURCE_MEM,
},
[2] = {
.start = USB_IRQ,
/* Filled in later */
.flags = IORESOURCE_IRQ,
},
};
Expand All @@ -138,8 +136,8 @@ static struct isp116x_platform_data usb_platform_data = {
static struct platform_device usb_device = {
.name = "isp116x-hcd",
.id = -1,
.num_resources = ARRAY_SIZE(usb_resources),
.resource = usb_resources,
.num_resources = ARRAY_SIZE(usb_resources),
.resource = usb_resources,
.dev = {
.platform_data = &usb_platform_data,
},
Expand All @@ -155,6 +153,13 @@ static struct platform_device *sh7343se_platform_devices[] __initdata = {

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,
ARRAY_SIZE(sh7343se_platform_devices));
}
Expand All @@ -179,6 +184,5 @@ static void __init sh7343se_setup(char **cmdline_p)
static struct sh_machine_vector mv_7343se __initmv = {
.mv_name = "SolutionEngine 7343",
.mv_setup = sh7343se_setup,
.mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR,
.mv_init_irq = init_7343se_IRQ,
};
52 changes: 22 additions & 30 deletions arch/sh/include/mach-se/mach/se7343.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,26 +94,26 @@

#define PORT_DRVCR 0xA4050180

#define PORT_PADR 0xA4050120
#define PORT_PBDR 0xA4050122
#define PORT_PCDR 0xA4050124
#define PORT_PDDR 0xA4050126
#define PORT_PEDR 0xA4050128
#define PORT_PFDR 0xA405012A
#define PORT_PGDR 0xA405012C
#define PORT_PHDR 0xA405012E
#define PORT_PJDR 0xA4050130
#define PORT_PKDR 0xA4050132
#define PORT_PLDR 0xA4050134
#define PORT_PMDR 0xA4050136
#define PORT_PNDR 0xA4050138
#define PORT_PQDR 0xA405013A
#define PORT_PRDR 0xA405013C
#define PORT_PTDR 0xA4050160
#define PORT_PUDR 0xA4050162
#define PORT_PVDR 0xA4050164
#define PORT_PWDR 0xA4050166
#define PORT_PYDR 0xA4050168
#define PORT_PADR 0xA4050120
#define PORT_PBDR 0xA4050122
#define PORT_PCDR 0xA4050124
#define PORT_PDDR 0xA4050126
#define PORT_PEDR 0xA4050128
#define PORT_PFDR 0xA405012A
#define PORT_PGDR 0xA405012C
#define PORT_PHDR 0xA405012E
#define PORT_PJDR 0xA4050130
#define PORT_PKDR 0xA4050132
#define PORT_PLDR 0xA4050134
#define PORT_PMDR 0xA4050136
#define PORT_PNDR 0xA4050138
#define PORT_PQDR 0xA405013A
#define PORT_PRDR 0xA405013C
#define PORT_PTDR 0xA4050160
#define PORT_PUDR 0xA4050162
#define PORT_PVDR 0xA4050164
#define PORT_PWDR 0xA4050166
#define PORT_PYDR 0xA4050168

#define FPGA_IN 0xb1400000
#define FPGA_OUT 0xb1400002
Expand All @@ -133,18 +133,10 @@
#define SE7343_FPGA_IRQ_UARTB 11

#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 */
extern unsigned int se7343_fpga_irq[];

void init_7343se_IRQ(void);

#endif /* __ASM_SH_HITACHI_SE7343_H */

0 comments on commit 53e6d8e

Please sign in to comment.