patch-2.4.0-test6 linux/arch/sh/kernel/setup_cqreek.c
Next file: linux/arch/sh/kernel/setup_hd64461.c
Previous file: linux/arch/sh/kernel/setup.c
Back to the patch index
Back to the overall index
- Lines: 225
- Date:
Wed Aug 9 13:59:04 2000
- Orig file:
v2.4.0-test5/linux/arch/sh/kernel/setup_cqreek.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.0-test5/linux/arch/sh/kernel/setup_cqreek.c linux/arch/sh/kernel/setup_cqreek.c
@@ -0,0 +1,224 @@
+/* $Id: setup_cqreek.c,v 1.1 2000/08/05 06:25:23 gniibe Exp $
+ *
+ * arch/sh/kernel/setup_cqreek.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ *
+ * CqREEK IDE/ISA Bridge Support.
+ *
+ */
+
+#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 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;
+}
+
+static void disable_cqreek_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned short mask;
+
+ save_and_cli(flags);
+ /* Disable IRQ */
+ mask = inw(BRIDGE_ISA_INTR_MASK) & ~(1 << irq);
+ outw_p(mask, BRIDGE_ISA_INTR_MASK);
+ restore_flags(flags);
+}
+
+static void enable_cqreek_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned short mask;
+
+ save_and_cli(flags);
+ /* Enable IRQ */
+ mask = inw(BRIDGE_ISA_INTR_MASK) | (1 << irq);
+ outw_p(mask, BRIDGE_ISA_INTR_MASK);
+ restore_flags(flags);
+}
+
+#define CLEAR_AT_ACCEPT
+
+static void mask_and_ack_cqreek(unsigned int irq)
+{
+ inw(BRIDGE_ISA_INTR_STAT);
+ disable_cqreek_irq(irq);
+#ifdef CLEAR_AT_ACCEPT
+ /* Clear IRQ (it might be edge IRQ) */
+ outw_p((1<<irq), BRIDGE_ISA_INTR_STAT);
+#endif
+}
+
+static void end_cqreek_irq(unsigned int irq)
+{
+#ifndef CLEAR_AT_ACCEPT
+ /* Clear IRQ (it might be edge IRQ) */
+ outw_p((1<<irq), BRIDGE_ISA_INTR_STAT);
+#endif
+ 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)
+ make_ipr_irq(14, IDE_OFFSET+BRIDGE_IDE_INTR_LVL, 0, 0x0f-14);
+
+ if (has_isa) {
+ /* 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)...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_port2addr: cqreek_port2addr,
+ mv_isa_port2addr: cqreek_port2addr,
+};
+ALIAS_MV(cqreek)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)