Path: blob/master/arch/sh/boards/mach-microdev/irq.c
15125 views
/*1* arch/sh/boards/superh/microdev/irq.c2*3* Copyright (C) 2003 Sean McGoogan ([email protected])4*5* SuperH SH4-202 MicroDev board support.6*7* May be copied or modified under the terms of the GNU General Public8* License. See linux/COPYING for more information.9*/1011#include <linux/init.h>12#include <linux/irq.h>13#include <linux/interrupt.h>14#include <asm/system.h>15#include <asm/io.h>16#include <mach/microdev.h>1718#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */1920static const struct {21unsigned char fpgaIrq;22unsigned char mapped;23const char *name;24} fpgaIrqTable[NUM_EXTERNAL_IRQS] = {25{ 0, 0, "unused" }, /* IRQ #0 IRL=15 0x200 */26{ MICRODEV_FPGA_IRQ_KEYBOARD, 1, "keyboard" }, /* IRQ #1 IRL=14 0x220 */27{ MICRODEV_FPGA_IRQ_SERIAL1, 1, "Serial #1"}, /* IRQ #2 IRL=13 0x240 */28{ MICRODEV_FPGA_IRQ_ETHERNET, 1, "Ethernet" }, /* IRQ #3 IRL=12 0x260 */29{ MICRODEV_FPGA_IRQ_SERIAL2, 0, "Serial #2"}, /* IRQ #4 IRL=11 0x280 */30{ 0, 0, "unused" }, /* IRQ #5 IRL=10 0x2a0 */31{ 0, 0, "unused" }, /* IRQ #6 IRL=9 0x2c0 */32{ MICRODEV_FPGA_IRQ_USB_HC, 1, "USB" }, /* IRQ #7 IRL=8 0x2e0 */33{ MICRODEV_IRQ_PCI_INTA, 1, "PCI INTA" }, /* IRQ #8 IRL=7 0x300 */34{ MICRODEV_IRQ_PCI_INTB, 1, "PCI INTB" }, /* IRQ #9 IRL=6 0x320 */35{ MICRODEV_IRQ_PCI_INTC, 1, "PCI INTC" }, /* IRQ #10 IRL=5 0x340 */36{ MICRODEV_IRQ_PCI_INTD, 1, "PCI INTD" }, /* IRQ #11 IRL=4 0x360 */37{ MICRODEV_FPGA_IRQ_MOUSE, 1, "mouse" }, /* IRQ #12 IRL=3 0x380 */38{ MICRODEV_FPGA_IRQ_IDE2, 1, "IDE #2" }, /* IRQ #13 IRL=2 0x3a0 */39{ MICRODEV_FPGA_IRQ_IDE1, 1, "IDE #1" }, /* IRQ #14 IRL=1 0x3c0 */40{ 0, 0, "unused" }, /* IRQ #15 IRL=0 0x3e0 */41};4243#if (MICRODEV_LINUX_IRQ_KEYBOARD != 1)44# error Inconsistancy in defining the IRQ# for Keyboard!45#endif4647#if (MICRODEV_LINUX_IRQ_ETHERNET != 3)48# error Inconsistancy in defining the IRQ# for Ethernet!49#endif5051#if (MICRODEV_LINUX_IRQ_USB_HC != 7)52# error Inconsistancy in defining the IRQ# for USB!53#endif5455#if (MICRODEV_LINUX_IRQ_MOUSE != 12)56# error Inconsistancy in defining the IRQ# for PS/2 Mouse!57#endif5859#if (MICRODEV_LINUX_IRQ_IDE2 != 13)60# error Inconsistancy in defining the IRQ# for secondary IDE!61#endif6263#if (MICRODEV_LINUX_IRQ_IDE1 != 14)64# error Inconsistancy in defining the IRQ# for primary IDE!65#endif6667static void disable_microdev_irq(struct irq_data *data)68{69unsigned int irq = data->irq;70unsigned int fpgaIrq;7172if (irq >= NUM_EXTERNAL_IRQS)73return;74if (!fpgaIrqTable[irq].mapped)75return;7677fpgaIrq = fpgaIrqTable[irq].fpgaIrq;7879/* disable interrupts on the FPGA INTC register */80__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);81}8283static void enable_microdev_irq(struct irq_data *data)84{85unsigned int irq = data->irq;86unsigned long priorityReg, priorities, pri;87unsigned int fpgaIrq;8889if (unlikely(irq >= NUM_EXTERNAL_IRQS))90return;91if (unlikely(!fpgaIrqTable[irq].mapped))92return;9394pri = 15 - irq;9596fpgaIrq = fpgaIrqTable[irq].fpgaIrq;97priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);9899/* set priority for the interrupt */100priorities = __raw_readl(priorityReg);101priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);102priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);103__raw_writel(priorities, priorityReg);104105/* enable interrupts on the FPGA INTC register */106__raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);107}108109static struct irq_chip microdev_irq_type = {110.name = "MicroDev-IRQ",111.irq_unmask = enable_microdev_irq,112.irq_mask = disable_microdev_irq,113};114115/* This function sets the desired irq handler to be a MicroDev type */116static void __init make_microdev_irq(unsigned int irq)117{118disable_irq_nosync(irq);119irq_set_chip_and_handler(irq, µdev_irq_type, handle_level_irq);120disable_microdev_irq(irq_get_irq_data(irq));121}122123extern void __init init_microdev_irq(void)124{125int i;126127/* disable interrupts on the FPGA INTC register */128__raw_writel(~0ul, MICRODEV_FPGA_INTDSB_REG);129130for (i = 0; i < NUM_EXTERNAL_IRQS; i++)131make_microdev_irq(i);132}133134extern void microdev_print_fpga_intc_status(void)135{136volatile unsigned int * const intenb = (unsigned int*)MICRODEV_FPGA_INTENB_REG;137volatile unsigned int * const intdsb = (unsigned int*)MICRODEV_FPGA_INTDSB_REG;138volatile unsigned int * const intpria = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(0);139volatile unsigned int * const intprib = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(8);140volatile unsigned int * const intpric = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(16);141volatile unsigned int * const intprid = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(24);142volatile unsigned int * const intsrc = (unsigned int*)MICRODEV_FPGA_INTSRC_REG;143volatile unsigned int * const intreq = (unsigned int*)MICRODEV_FPGA_INTREQ_REG;144145printk("-------------------------- microdev_print_fpga_intc_status() ------------------\n");146printk("FPGA_INTENB = 0x%08x\n", *intenb);147printk("FPGA_INTDSB = 0x%08x\n", *intdsb);148printk("FPGA_INTSRC = 0x%08x\n", *intsrc);149printk("FPGA_INTREQ = 0x%08x\n", *intreq);150printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria);151printk("-------------------------------------------------------------------------------\n");152}153154155