setup_cqreek.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
- /* $Id: setup_cqreek.c,v 1.9 2001/07/30 12:43:28 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>
- #include <asm/rtc.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 0xA4A00000UL
- static 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;
- disable_cqreek_irq(irq);
- /* Clear IRQ (it might be edge IRQ) */
- inw(stat_port);
- outw_p(bit, stat_port);
- }
- static void end_cqreek_irq(unsigned int irq)
- {
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- 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)
- {
- int i;
- /* udelay is not available at setup time yet... */
- #define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
- 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)...donen", 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,
- mv_ioremap: generic_ioremap,
- mv_iounmap: generic_iounmap,
- mv_rtc_gettimeofday: sh_rtc_gettimeofday,
- mv_rtc_settimeofday: sh_rtc_settimeofday,
- };
- ALIAS_MV(cqreek)