?? irq.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 + -