⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irq.c

📁 LINUX 2.6.17.4的源码
💻 C
字号:
/* * linux/arch/sh/boards/ec3104/irq.c * EC3104 companion chip support * * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * */#include <asm/io.h>#include <asm/irq.h>#include <asm/ec3104/ec3104.h>/* This is for debugging mostly;  here's the table that I intend to keep * in here: * *   index      function        base addr       power           interrupt bit *       0      power           b0ec0000        ---             00000001 (unused) *       1      irqs            b0ec1000        ---             00000002 (unused) *       2      ??              b0ec2000        b0ec0008        00000004 *       3      PS2 (1)         b0ec3000        b0ec000c        00000008 *       4      PS2 (2)         b0ec4000        b0ec0010        00000010 *       5      ??              b0ec5000        b0ec0014        00000020 *       6      I2C             b0ec6000        b0ec0018        00000040 *       7      serial (1)      b0ec7000        b0ec001c        00000080 *       8      serial (2)      b0ec8000        b0ec0020        00000100 *       9      serial (3)      b0ec9000        b0ec0024        00000200 *      10      serial (4)      b0eca000        b0ec0028        00000400 *      12      GPIO (1)        b0ecc000        b0ec0030 *      13      GPIO (2)        b0ecc000        b0ec0030 *      16      pcmcia (1)      b0ed0000        b0ec0040        00010000 *      17      pcmcia (2)      b0ed1000        b0ec0044        00020000 *//* I used the register names from another interrupt controller I worked with, * since it seems to be identical to the ec3104 except that all bits are * inverted: * * IRR: Interrupt Request Register (pending and enabled interrupts) * IMR: Interrupt Mask Register (which interrupts are enabled) * IPR: Interrupt Pending Register (pending interrupts, even disabled ones) * * 0 bits mean pending or enabled, 1 bits mean not pending or disabled.  all * IRQs seem to be level-triggered. */#define EC3104_IRR (EC3104_BASE + 0x1000)#define EC3104_IMR (EC3104_BASE + 0x1004)#define EC3104_IPR (EC3104_BASE + 0x1008)#define ctrl_readl(addr) (*(volatile u32 *)(addr))#define ctrl_writel(data,addr) (*(volatile u32 *)(addr) = (data))#define ctrl_readb(addr) (*(volatile u8 *)(addr))static char *ec3104_name(unsigned index){        switch(index) {        case 0:                return "power management";        case 1:                return "interrupts";        case 3:                return "PS2 (1)";        case 4:                return "PS2 (2)";        case 5:                return "I2C (1)";        case 6:                return "I2C (2)";        case 7:                return "serial (1)";        case 8:                return "serial (2)";        case 9:                return "serial (3)";        case 10:                return "serial (4)";        case 16:                return "pcmcia (1)";        case 17:                return "pcmcia (2)";        default: {                static char buf[32];                sprintf(buf, "unknown (%d)", index);                return buf;                }        }}int get_pending_interrupts(char *buf){        u32 ipr;        u32 bit;        char *p = buf;        p += sprintf(p, "pending: (");        ipr = ctrl_inl(EC3104_IPR);        for (bit = 1; bit < 32; bit++)                if (!(ipr & (1<<bit)))                        p += sprintf(p, "%s ", ec3104_name(bit));        p += sprintf(p, ")\n");        return p - buf;}static inline u32 ec3104_irq2mask(unsigned int irq){        return (1 << (irq - EC3104_IRQBASE));}static inline void mask_ec3104_irq(unsigned int irq){        u32 mask;        mask = ctrl_readl(EC3104_IMR);        mask |= ec3104_irq2mask(irq);        ctrl_writel(mask, EC3104_IMR);}static inline void unmask_ec3104_irq(unsigned int irq){        u32 mask;        mask = ctrl_readl(EC3104_IMR);        mask &= ~ec3104_irq2mask(irq);        ctrl_writel(mask, EC3104_IMR);}static void disable_ec3104_irq(unsigned int irq){        mask_ec3104_irq(irq);}static void enable_ec3104_irq(unsigned int irq){        unmask_ec3104_irq(irq);}static void mask_and_ack_ec3104_irq(unsigned int irq){        mask_ec3104_irq(irq);}static void end_ec3104_irq(unsigned int irq){        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))                unmask_ec3104_irq(irq);}static unsigned int startup_ec3104_irq(unsigned int irq){        unmask_ec3104_irq(irq);        return 0;}static void shutdown_ec3104_irq(unsigned int irq){        mask_ec3104_irq(irq);}static struct hw_interrupt_type ec3104_int = {        .typename       = "EC3104",        .enable         = enable_ec3104_irq,        .disable        = disable_ec3104_irq,        .ack            = mask_and_ack_ec3104_irq,        .end            = end_ec3104_irq,        .startup        = startup_ec3104_irq,        .shutdown       = shutdown_ec3104_irq,};/* Yuck.  the _demux API is ugly */int ec3104_irq_demux(int irq){        if (irq == EC3104_IRQ) {                unsigned int mask;                mask = ctrl_readl(EC3104_IRR);                if (mask == 0xffffffff)                        return EC3104_IRQ;                else                        return EC3104_IRQBASE + ffz(mask);        }        return irq;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -