📄 setup_cqreek.c
字号:
/* $Id: setup_cqreek.c,v 1.5 2000/09/18 05:51:24 gniibe Exp $ * * arch/sh/kernel/setup_cqreek.c * * Copyright (C) 2000 Niibe Yutaka * * CqREEK IDE/ISA Bridge Support. * */#include <linux/config.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/irq.h>#include <asm/io.h>#include <asm/io_generic.h>#include <asm/irq.h>#include <asm/machvec.h>#include <asm/machvec_init.h>#define BRIDGE_FEATURE 0x0002#define BRIDGE_IDE_CTRL 0x0018#define BRIDGE_IDE_INTR_LVL 0x001A#define BRIDGE_IDE_INTR_MASK 0x001C#define BRIDGE_IDE_INTR_STAT 0x001E#define BRIDGE_ISA_CTRL 0x0028#define BRIDGE_ISA_INTR_LVL 0x002A#define BRIDGE_ISA_INTR_MASK 0x002C#define BRIDGE_ISA_INTR_STAT 0x002E#define IDE_OFFSET 0xA4000000UL#define ISA_OFFSET 0xA4A00000ULstatic unsigned long cqreek_port2addr(unsigned long port){ if (0x0000<=port && port<=0x0040) return IDE_OFFSET + port; if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6) return IDE_OFFSET + port; return ISA_OFFSET + port;}struct cqreek_irq_data { unsigned short mask_port; /* Port of Interrupt Mask Register */ unsigned short stat_port; /* Port of Interrupt Status Register */ unsigned short bit; /* Value of the bit */};static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];static void disable_cqreek_irq(unsigned int irq){ unsigned long flags; unsigned short mask; unsigned short mask_port = cqreek_irq_data[irq].mask_port; unsigned short bit = cqreek_irq_data[irq].bit; save_and_cli(flags); /* Disable IRQ */ mask = inw(mask_port) & ~bit; outw_p(mask, mask_port); restore_flags(flags);}static void enable_cqreek_irq(unsigned int irq){ unsigned long flags; unsigned short mask; unsigned short mask_port = cqreek_irq_data[irq].mask_port; unsigned short bit = cqreek_irq_data[irq].bit; save_and_cli(flags); /* Enable IRQ */ mask = inw(mask_port) | bit; outw_p(mask, mask_port); restore_flags(flags);}static void mask_and_ack_cqreek(unsigned int irq){ unsigned short stat_port = cqreek_irq_data[irq].stat_port; unsigned short bit = cqreek_irq_data[irq].bit; inw(stat_port); disable_cqreek_irq(irq); /* Clear IRQ (it might be edge IRQ) */ outw_p(bit, stat_port);}static void end_cqreek_irq(unsigned int irq){ enable_cqreek_irq(irq);}static unsigned int startup_cqreek_irq(unsigned int irq){ enable_cqreek_irq(irq); return 0;}static void shutdown_cqreek_irq(unsigned int irq){ disable_cqreek_irq(irq);}static struct hw_interrupt_type cqreek_irq_type = { "CqREEK-IRQ", startup_cqreek_irq, shutdown_cqreek_irq, enable_cqreek_irq, disable_cqreek_irq, mask_and_ack_cqreek, end_cqreek_irq};static int has_ide, has_isa;/* XXX: This is just for test for my NE2000 ISA board What we really need is virtualized IRQ and demultiplexer like HP600 port */void __init init_cqreek_IRQ(void){ if (has_ide) { cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK; cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; cqreek_irq_data[14].bit = 1; irq_desc[14].handler = &cqreek_irq_type; irq_desc[14].status = IRQ_DISABLED; irq_desc[14].action = 0; irq_desc[14].depth = 1; disable_cqreek_irq(14); } if (has_isa) { cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK; cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT; cqreek_irq_data[10].bit = (1 << 10); /* XXX: Err... we may need demultiplexer for ISA irq... */ irq_desc[10].handler = &cqreek_irq_type; irq_desc[10].status = IRQ_DISABLED; irq_desc[10].action = 0; irq_desc[10].depth = 1; disable_cqreek_irq(10); }}/* * Initialize the board */void __init setup_cqreek(void){ extern void disable_hlt(void); int i;/* udelay is not available at setup time yet... */#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0) /* * XXX: I don't know the reason, but it becomes so fragile with * "sleep", so we need to stop sleeping. */ disable_hlt(); if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */ outw_p(0, BRIDGE_IDE_INTR_LVL); outw_p(0, BRIDGE_IDE_INTR_MASK); outw_p(0, BRIDGE_IDE_CTRL); DELAY(); outw_p(0x8000, BRIDGE_IDE_CTRL); DELAY(); outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */ outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */ outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */ has_ide=1; } if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */ outw_p(0, BRIDGE_ISA_INTR_LVL); outw_p(0, BRIDGE_ISA_INTR_MASK); outw_p(0, BRIDGE_ISA_CTRL); DELAY(); outw_p(0x8000, BRIDGE_ISA_CTRL); DELAY(); outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */ outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */ outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */ has_isa=1; } printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", has_ide, has_isa);}/* * The Machine Vector */struct sh_machine_vector mv_cqreek __initmv = { mv_name: "CqREEK",#if defined(__SH4__) mv_nr_irqs: 48,#elif defined(CONFIG_CPU_SUBTYPE_SH7708) mv_nr_irqs: 32,#elif defined(CONFIG_CPU_SUBTYPE_SH7709) mv_nr_irqs: 61,#endif mv_inb: generic_inb, mv_inw: generic_inw, mv_inl: generic_inl, mv_outb: generic_outb, mv_outw: generic_outw, mv_outl: generic_outl, mv_inb_p: generic_inb_p, mv_inw_p: generic_inw_p, mv_inl_p: generic_inl_p, mv_outb_p: generic_outb_p, mv_outw_p: generic_outw_p, mv_outl_p: generic_outl_p, mv_insb: generic_insb, mv_insw: generic_insw, mv_insl: generic_insl, mv_outsb: generic_outsb, mv_outsw: generic_outsw, mv_outsl: generic_outsl, mv_readb: generic_readb, mv_readw: generic_readw, mv_readl: generic_readl, mv_writeb: generic_writeb, mv_writew: generic_writew, mv_writel: generic_writel, mv_init_arch: setup_cqreek, mv_init_irq: init_cqreek_IRQ, mv_isa_port2addr: cqreek_port2addr,};ALIAS_MV(cqreek)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -