`-- sh
         `-- cchips
             `-- hd6446x
-                |-- hd64461
-                |   `-- cchip-specific files
-                `-- hd64465
+                `-- hd64461
                     `-- cchip-specific files
 
 ... and so on. Headers for the companion chips are treated the same way as
 
          Say Y if you want support for the HD64461.
          Otherwise, say N.
 
-config HD64465
-       bool "Hitachi HD64465 companion chip support"
-       ---help---
-         The Hitachi HD64465 provides an interface for
-         the SH7750 CPU, supporting a LCD controller,
-         CRT color controller, IrDA, USB, PCMCIA,
-         keyboard controller, and a printer interface.
-
-         More information is available at
-         <http://global.hitachi.com/New/cnews/E/1998/981019B.html>.
-
-         Say Y if you want support for the HD64465.
-         Otherwise, say N.
-
 endchoice
 
 # These will also be split into the Kconfig's below
          via the HD64461 companion chip.
          Otherwise, say N.
 
-config HD64465_IOBASE
-       hex "HD64465 start address"
-       depends on HD64465
-       default "0xb0000000"
-       help
-         The default setting of the HD64465 IO base address is 0xb0000000.
-
-         Do not change this unless you know what you are doing.
-
-config HD64465_IRQ
-       int "HD64465 IRQ"
-       depends on HD64465
-       default "5"
-       help
-         The default setting of the HD64465 IRQ is 5.
-
-         Do not change this unless you know what you are doing.
-
 endmenu
-
 
 obj-$(CONFIG_HD64461)  += hd64461.o
-obj-$(CONFIG_HD64465)  += hd64465/
 
 EXTRA_CFLAGS += -Werror
 
+++ /dev/null
-#
-# Makefile for the HD64465
-#
-
-obj-y   := setup.o io.o gpio.o
-
 
+++ /dev/null
-/*
- * $Id: gpio.c,v 1.4 2003/05/19 22:24:18 lethal Exp $
- * by Greg Banks <gbanks@pocketpenguins.com>
- * (c) 2000 PocketPenguins Inc
- *
- * GPIO pin support for HD64465 companion chip.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/hd64465/gpio.h>
-
-#define _PORTOF(portpin)    (((portpin)>>3)&0x7)
-#define _PINOF(portpin)     ((portpin)&0x7)
-
-/* Register addresses parametrised on port */
-#define GPIO_CR(port)      (HD64465_REG_GPACR+((port)<<1))
-#define GPIO_DR(port)      (HD64465_REG_GPADR+((port)<<1))
-#define GPIO_ICR(port)     (HD64465_REG_GPAICR+((port)<<1))
-#define GPIO_ISR(port)     (HD64465_REG_GPAISR+((port)<<1))
-
-#define GPIO_NPORTS 5
-
-#define MODNAME "hd64465_gpio"
-
-EXPORT_SYMBOL(hd64465_gpio_configure);
-EXPORT_SYMBOL(hd64465_gpio_get_pin);
-EXPORT_SYMBOL(hd64465_gpio_get_port);
-EXPORT_SYMBOL(hd64465_gpio_register_irq);
-EXPORT_SYMBOL(hd64465_gpio_set_pin);
-EXPORT_SYMBOL(hd64465_gpio_set_port);
-EXPORT_SYMBOL(hd64465_gpio_unregister_irq);
-
-/* TODO: each port should be protected with a spinlock */
-
-
-void hd64465_gpio_configure(int portpin, int direction)
-{
-       unsigned short cr;
-       unsigned int shift = (_PINOF(portpin)<<1);
-
-       cr = inw(GPIO_CR(_PORTOF(portpin)));
-       cr &= ~(3<<shift);
-       cr |= direction<<shift;
-       outw(cr, GPIO_CR(_PORTOF(portpin)));
-}
-
-void hd64465_gpio_set_pin(int portpin, unsigned int value)
-{
-       unsigned short d;
-       unsigned short mask = 1<<(_PINOF(portpin));
-       
-       d = inw(GPIO_DR(_PORTOF(portpin)));
-       if (value)
-           d |= mask;
-       else
-           d &= ~mask;
-       outw(d, GPIO_DR(_PORTOF(portpin)));
-}
-
-unsigned int hd64465_gpio_get_pin(int portpin)
-{
-       return inw(GPIO_DR(_PORTOF(portpin))) & (1<<(_PINOF(portpin)));
-}
-
-/* TODO: for cleaner atomicity semantics, add a mask to this routine */
-
-void hd64465_gpio_set_port(int port, unsigned int value)
-{
-       outw(value, GPIO_DR(port));
-}
-
-unsigned int hd64465_gpio_get_port(int port)
-{
-       return inw(GPIO_DR(port));
-}
-
-
-static struct {
-    void (*func)(int portpin, void *dev);
-    void *dev;
-} handlers[GPIO_NPORTS * 8];
-
-static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev)
-{
-       unsigned short port, pin, isr, mask, portpin;
-       
-       for (port=0 ; port<GPIO_NPORTS ; port++) {
-           isr = inw(GPIO_ISR(port));
-           
-           for (pin=0 ; pin<8 ; pin++) {
-               mask = 1<<pin;
-               if (isr & mask) {
-                   portpin = (port<<3)|pin;
-                   if (handlers[portpin].func != 0)
-                       handlers[portpin].func(portpin, handlers[portpin].dev);
-                   else
-                       printk(KERN_NOTICE "unexpected GPIO interrupt, pin %c%d\n",
-                           port+'A', (int)pin);
-               }
-           }
-           
-           /* Write 1s back to ISR to clear it?  That's what the manual says.. */
-           outw(isr, GPIO_ISR(port));
-       }
-
-       return IRQ_HANDLED;
-}
-
-void hd64465_gpio_register_irq(int portpin, int mode,
-       void (*handler)(int portpin, void *dev), void *dev)
-{
-       unsigned long flags;
-       unsigned short icr, mask;
-
-       if (handler == 0)
-           return;
-           
-       local_irq_save(flags);
-       
-       handlers[portpin].func = handler;
-       handlers[portpin].dev = dev;
-
-       /*
-        * Configure Interrupt Control Register
-        */
-       icr = inw(GPIO_ICR(_PORTOF(portpin)));
-       mask = (1<<_PINOF(portpin));
-       
-       /* unmask interrupt */
-       icr &= ~mask;
-       
-       /* set TS bit */
-       mask <<= 8;
-       icr &= ~mask;
-       if (mode == HD64465_GPIO_RISING)
-           icr |= mask;
-           
-       outw(icr, GPIO_ICR(_PORTOF(portpin)));
-
-       local_irq_restore(flags);
-}
-
-void hd64465_gpio_unregister_irq(int portpin)
-{
-       unsigned long flags;
-       unsigned short icr;
-       
-       local_irq_save(flags);
-
-       /*
-        * Configure Interrupt Control Register
-        */
-       icr = inw(GPIO_ICR(_PORTOF(portpin)));
-       icr |= (1<<_PINOF(portpin));    /* mask interrupt */
-       outw(icr, GPIO_ICR(_PORTOF(portpin)));
-
-       handlers[portpin].func = 0;
-       handlers[portpin].dev = 0;
-       
-       local_irq_restore(flags);
-}
-
-static int __init hd64465_gpio_init(void)
-{
-       if (!request_region(HD64465_REG_GPACR, 0x1000, MODNAME))
-               return -EBUSY;
-       if (request_irq(HD64465_IRQ_GPIO, hd64465_gpio_interrupt,
-                       IRQF_DISABLED, MODNAME, 0))
-               goto out_irqfailed;
-
-       printk("HD64465 GPIO layer on irq %d\n", HD64465_IRQ_GPIO);
-
-       return 0;
-
-out_irqfailed:
-       release_region(HD64465_REG_GPACR, 0x1000);
-
-       return -EINVAL;
-}
-
-static void __exit hd64465_gpio_exit(void)
-{
-       release_region(HD64465_REG_GPACR, 0x1000);
-       free_irq(HD64465_IRQ_GPIO, 0);
-}
-
-module_init(hd64465_gpio_init);
-module_exit(hd64465_gpio_exit);
-
-MODULE_LICENSE("GPL");
-
 
+++ /dev/null
-/*
- * $Id: io.c,v 1.4 2003/08/03 03:05:10 lethal Exp $
- * by Greg Banks <gbanks@pocketpenguins.com>
- * (c) 2000 PocketPenguins Inc
- *
- * Derived from io_hd64461.c, which bore the message:
- * Copyright (C) 2000 YAEGASHI Takeshi
- *
- * Typical I/O routines for HD64465 system.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <asm/hd64465/hd64465.h>
-
-
-#define HD64465_DEBUG 0
-
-#if HD64465_DEBUG
-#define DPRINTK(args...)       printk(args)
-#define DIPRINTK(n, args...)   if (hd64465_io_debug>(n)) printk(args)
-#else
-#define DPRINTK(args...)
-#define DIPRINTK(n, args...)
-#endif
-
-
-
-/* This is a hack suitable only for debugging IO port problems */
-int hd64465_io_debug;
-EXPORT_SYMBOL(hd64465_io_debug);
-
-/* Low iomap maps port 0-1K to addresses in 8byte chunks */
-#define HD64465_IOMAP_LO_THRESH 0x400
-#define HD64465_IOMAP_LO_SHIFT 3
-#define HD64465_IOMAP_LO_MASK  ((1<<HD64465_IOMAP_LO_SHIFT)-1)
-#define HD64465_IOMAP_LO_NMAP  (HD64465_IOMAP_LO_THRESH>>HD64465_IOMAP_LO_SHIFT)
-static unsigned long   hd64465_iomap_lo[HD64465_IOMAP_LO_NMAP];
-static unsigned char   hd64465_iomap_lo_shift[HD64465_IOMAP_LO_NMAP];
-
-/* High iomap maps port 1K-64K to addresses in 1K chunks */
-#define HD64465_IOMAP_HI_THRESH 0x10000
-#define HD64465_IOMAP_HI_SHIFT 10
-#define HD64465_IOMAP_HI_MASK  ((1<<HD64465_IOMAP_HI_SHIFT)-1)
-#define HD64465_IOMAP_HI_NMAP  (HD64465_IOMAP_HI_THRESH>>HD64465_IOMAP_HI_SHIFT)
-static unsigned long   hd64465_iomap_hi[HD64465_IOMAP_HI_NMAP];
-static unsigned char   hd64465_iomap_hi_shift[HD64465_IOMAP_HI_NMAP];
-
-#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
-
-void hd64465_port_map(unsigned short baseport, unsigned int nports,
-                     unsigned long addr, unsigned char shift)
-{
-       unsigned int port, endport = baseport + nports;
-
-       DPRINTK("hd64465_port_map(base=0x%04hx, n=0x%04hx, addr=0x%08lx,endport=0x%04x)\n",
-           baseport, nports, addr,endport);
-           
-       for (port = baseport ;
-            port < endport && port < HD64465_IOMAP_LO_THRESH ;
-            port += (1<<HD64465_IOMAP_LO_SHIFT)) {
-           DPRINTK("    maplo[0x%x] = 0x%08lx\n", port, addr);
-           hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = addr;
-           hd64465_iomap_lo_shift[port>>HD64465_IOMAP_LO_SHIFT] = shift;
-           addr += (1<<(HD64465_IOMAP_LO_SHIFT));
-       }
-
-       for (port = max_t(unsigned int, baseport, HD64465_IOMAP_LO_THRESH);
-            port < endport && port < HD64465_IOMAP_HI_THRESH ;
-            port += (1<<HD64465_IOMAP_HI_SHIFT)) {
-           DPRINTK("    maphi[0x%x] = 0x%08lx\n", port, addr);
-           hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = addr;
-           hd64465_iomap_hi_shift[port>>HD64465_IOMAP_HI_SHIFT] = shift;
-           addr += (1<<(HD64465_IOMAP_HI_SHIFT));
-       }
-}
-EXPORT_SYMBOL(hd64465_port_map);
-
-void hd64465_port_unmap(unsigned short baseport, unsigned int nports)
-{
-       unsigned int port, endport = baseport + nports;
-       
-       DPRINTK("hd64465_port_unmap(base=0x%04hx, n=0x%04hx)\n",
-           baseport, nports);
-
-       for (port = baseport ;
-            port < endport && port < HD64465_IOMAP_LO_THRESH ;
-            port += (1<<HD64465_IOMAP_LO_SHIFT)) {
-           hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = 0;
-       }
-
-       for (port = max_t(unsigned int, baseport, HD64465_IOMAP_LO_THRESH);
-            port < endport && port < HD64465_IOMAP_HI_THRESH ;
-            port += (1<<HD64465_IOMAP_HI_SHIFT)) {
-           hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = 0;
-       }
-}
-EXPORT_SYMBOL(hd64465_port_unmap);
-
-unsigned long hd64465_isa_port2addr(unsigned long port)
-{
-       unsigned long addr = 0;
-       unsigned char shift;
-
-       /* handle remapping of low IO ports */
-       if (port < HD64465_IOMAP_LO_THRESH) {
-           addr = hd64465_iomap_lo[port >> HD64465_IOMAP_LO_SHIFT];
-           shift = hd64465_iomap_lo_shift[port >> HD64465_IOMAP_LO_SHIFT];
-           if (addr != 0)
-               addr += (port & HD64465_IOMAP_LO_MASK) << shift;
-           else
-               printk(KERN_NOTICE "io_hd64465: access to un-mapped port %lx\n", port);
-       } else if (port < HD64465_IOMAP_HI_THRESH) {
-           addr = hd64465_iomap_hi[port >> HD64465_IOMAP_HI_SHIFT];
-           shift = hd64465_iomap_hi_shift[port >> HD64465_IOMAP_HI_SHIFT];
-           if (addr != 0)
-               addr += (port & HD64465_IOMAP_HI_MASK) << shift;
-           else
-               printk(KERN_NOTICE "io_hd64465: access to un-mapped port %lx\n", port);
-       }
-               
-       /* HD64465 internal devices (0xb0000000) */
-       else if (port < 0x20000)
-           addr = CONFIG_HD64465_IOBASE + port - 0x10000;
-
-       /* Whole physical address space (0xa0000000) */
-       else
-           addr = P2SEGADDR(port);
-
-       DIPRINTK(2, "PORT2ADDR(0x%08lx) = 0x%08lx\n", port, addr);
-
-       return addr;
-}
-
-static inline void delay(void)
-{
-       ctrl_inw(0xa0000000);
-}
-
-unsigned char hd64465_inb(unsigned long port)
-{
-       unsigned long addr = PORT2ADDR(port);
-       unsigned long b = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
-
-       DIPRINTK(0, "inb(%08lx) = %02x\n", addr, (unsigned)b);
-       return b;
-}
-
-unsigned char hd64465_inb_p(unsigned long port)
-{
-       unsigned long v;
-       unsigned long addr = PORT2ADDR(port);
-
-       v = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
-       delay();
-       DIPRINTK(0, "inb_p(%08lx) = %02x\n", addr, (unsigned)v);
-       return v;
-}
-
-unsigned short hd64465_inw(unsigned long port)
-{
-       unsigned long addr = PORT2ADDR(port);
-       unsigned long b = (addr == 0 ? 0 : *(volatile unsigned short*)addr);
-       DIPRINTK(0, "inw(%08lx) = %04lx\n", addr, b);
-       return b;
-}
-
-unsigned int hd64465_inl(unsigned long port)
-{
-       unsigned long addr = PORT2ADDR(port);
-       unsigned int b = (addr == 0 ? 0 : *(volatile unsigned long*)addr);
-       DIPRINTK(0, "inl(%08lx) = %08x\n", addr, b);
-       return b;
-}
-
-void hd64465_outb(unsigned char b, unsigned long port)
-{
-       unsigned long addr = PORT2ADDR(port);
-
-       DIPRINTK(0, "outb(%02x, %08lx)\n", (unsigned)b, addr);
-       if (addr != 0)
-           *(volatile unsigned char*)addr = b;
-}
-
-void hd64465_outb_p(unsigned char b, unsigned long port)
-{
-       unsigned long addr = PORT2ADDR(port);
-
-       DIPRINTK(0, "outb_p(%02x, %08lx)\n", (unsigned)b, addr);
-       if (addr != 0)
-           *(volatile unsigned char*)addr = b;
-       delay();
-}
-
-void hd64465_outw(unsigned short b, unsigned long port)
-{
-       unsigned long addr = PORT2ADDR(port);
-       DIPRINTK(0, "outw(%04x, %08lx)\n", (unsigned)b, addr);
-       if (addr != 0)
-           *(volatile unsigned short*)addr = b;
-}
-
-void hd64465_outl(unsigned int b, unsigned long port)
-{
-       unsigned long addr = PORT2ADDR(port);
-       DIPRINTK(0, "outl(%08x, %08lx)\n", b, addr);
-       if (addr != 0)
-            *(volatile unsigned long*)addr = b;
-}
-
 
+++ /dev/null
-/*
- * $Id: setup.c,v 1.4 2003/08/03 03:05:10 lethal Exp $
- *
- * Setup and IRQ handling code for the HD64465 companion chip.
- * by Greg Banks <gbanks@pocketpenguins.com>
- * Copyright (c) 2000 PocketPenguins Inc
- *
- * Derived from setup_hd64461.c which bore the message:
- * Copyright (C) 2000 YAEGASHI Takeshi
- */
-
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/hd64465/hd64465.h>
-
-static void disable_hd64465_irq(unsigned int irq)
-{
-       unsigned short nimr;
-       unsigned short mask = 1 << (irq - HD64465_IRQ_BASE);
-
-       pr_debug("disable_hd64465_irq(%d): mask=%x\n", irq, mask);
-       nimr = inw(HD64465_REG_NIMR);
-       nimr |= mask;
-       outw(nimr, HD64465_REG_NIMR);
-}
-
-static void enable_hd64465_irq(unsigned int irq)
-{
-       unsigned short nimr;
-       unsigned short mask = 1 << (irq - HD64465_IRQ_BASE);
-
-       pr_debug("enable_hd64465_irq(%d): mask=%x\n", irq, mask);
-       nimr = inw(HD64465_REG_NIMR);
-       nimr &= ~mask;
-       outw(nimr, HD64465_REG_NIMR);
-}
-
-static void mask_and_ack_hd64465(unsigned int irq)
-{
-       disable_hd64465_irq(irq);
-}
-
-static void end_hd64465_irq(unsigned int irq)
-{
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-               enable_hd64465_irq(irq);
-}
-
-static unsigned int startup_hd64465_irq(unsigned int irq)
-{
-       enable_hd64465_irq(irq);
-       return 0;
-}
-
-static void shutdown_hd64465_irq(unsigned int irq)
-{
-       disable_hd64465_irq(irq);
-}
-
-static struct hw_interrupt_type hd64465_irq_type = {
-       .typename       = "HD64465-IRQ",
-       .startup        = startup_hd64465_irq,
-       .shutdown       = shutdown_hd64465_irq,
-       .enable         = enable_hd64465_irq,
-       .disable        = disable_hd64465_irq,
-       .ack            = mask_and_ack_hd64465,
-       .end            = end_hd64465_irq,
-};
-
-static irqreturn_t hd64465_interrupt(int irq, void *dev_id)
-{
-       printk(KERN_INFO
-              "HD64465: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
-              inw(HD64465_REG_NIRR), inw(HD64465_REG_NIMR));
-
-       return IRQ_NONE;
-}
-
-/*
- * Support for a secondary IRQ demux step.  This is necessary
- * because the HD64465 presents a very thin interface to the
- * PCMCIA bus; a lot of features (such as remapping interrupts)
- * normally done in hardware by other PCMCIA host bridges is
- * instead done in software.
- */
-static struct {
-    int (*func)(int, void *);
-    void *dev;
-} hd64465_demux[HD64465_IRQ_NUM];
-
-void hd64465_register_irq_demux(int irq,
-               int (*demux)(int irq, void *dev), void *dev)
-{
-       hd64465_demux[irq - HD64465_IRQ_BASE].func = demux;
-       hd64465_demux[irq - HD64465_IRQ_BASE].dev = dev;
-}
-EXPORT_SYMBOL(hd64465_register_irq_demux);
-
-void hd64465_unregister_irq_demux(int irq)
-{
-       hd64465_demux[irq - HD64465_IRQ_BASE].func = 0;
-}
-EXPORT_SYMBOL(hd64465_unregister_irq_demux);
-
-int hd64465_irq_demux(int irq)
-{
-       if (irq == CONFIG_HD64465_IRQ) {
-               unsigned short i, bit;
-               unsigned short nirr = inw(HD64465_REG_NIRR);
-               unsigned short nimr = inw(HD64465_REG_NIMR);
-
-               pr_debug("hd64465_irq_demux, nirr=%04x, nimr=%04x\n", nirr, nimr);
-               nirr &= ~nimr;
-               for (bit = 1, i = 0 ; i < HD64465_IRQ_NUM ; bit <<= 1, i++)
-                   if (nirr & bit)
-                       break;
-
-               if (i < HD64465_IRQ_NUM) {
-                   irq = HD64465_IRQ_BASE + i;
-                   if (hd64465_demux[i].func != 0)
-                       irq = hd64465_demux[i].func(irq, hd64465_demux[i].dev);
-               }
-       }
-       return irq;
-}
-
-static struct irqaction irq0  = {
-       .handler = hd64465_interrupt,
-       .flags = IRQF_DISABLED,
-       .mask = CPU_MASK_NONE,
-       .name = "HD64465",
-};
-
-static int __init setup_hd64465(void)
-{
-       int i;
-       unsigned short rev;
-       unsigned short smscr;
-
-       if (!MACH_HD64465)
-               return 0;
-
-       printk(KERN_INFO "HD64465 configured at 0x%x on irq %d(mapped into %d to %d)\n",
-              CONFIG_HD64465_IOBASE,
-              CONFIG_HD64465_IRQ,
-              HD64465_IRQ_BASE,
-              HD64465_IRQ_BASE+HD64465_IRQ_NUM-1);
-
-       if (inw(HD64465_REG_SDID) != HD64465_SDID) {
-               printk(KERN_ERR "HD64465 device ID not found, check base address\n");
-       }
-
-       rev = inw(HD64465_REG_SRR);
-       printk(KERN_INFO "HD64465 hardware revision %d.%d\n", (rev >> 8) & 0xff, rev & 0xff);
-
-       outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */
-
-       for (i = 0; i < HD64465_IRQ_NUM ; i++) {
-               irq_desc[HD64465_IRQ_BASE + i].chip = &hd64465_irq_type;
-       }
-
-       setup_irq(CONFIG_HD64465_IRQ, &irq0);
-
-       /* wake up the UART from STANDBY at this point */
-       smscr = inw(HD64465_REG_SMSCR);
-       outw(smscr & (~HD64465_SMSCR_UARTST), HD64465_REG_SMSCR);
-
-       /* remap IO ports for first ISA serial port to HD64465 UART */
-       hd64465_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
-
-       return 0;
-}
-module_init(setup_hd64465);
 
+++ /dev/null
-#ifndef _ASM_SH_HD64465_GPIO_
-#define _ASM_SH_HD64465_GPIO_ 1
-/*
- * $Id: gpio.h,v 1.3 2003/05/04 19:30:14 lethal Exp $
- *
- * Hitachi HD64465 companion chip: General Purpose IO pins support.
- * This layer enables other device drivers to configure GPIO
- * pins, get and set their values, and register an interrupt
- * routine for when input pins change in hardware.
- *
- * by Greg Banks <gbanks@pocketpenguins.com>
- * (c) 2000 PocketPenguins Inc.
- */
-#include <asm/hd64465.h>
-
-/* Macro to construct a portpin number (used in all
- * subsequent functions) from a port letter and a pin
- * number, e.g. HD64465_GPIO_PORTPIN('A', 5).
- */
-#define HD64465_GPIO_PORTPIN(port,pin) (((port)-'A')<<3|(pin))
-
-/* Pin configuration constants for _configure() */
-#define HD64465_GPIO_FUNCTION2 0       /* use the pin's *other* function */
-#define HD64465_GPIO_OUT       1       /* output */
-#define HD64465_GPIO_IN_PULLUP 2       /* input, pull-up MOS on */
-#define HD64465_GPIO_IN                3       /* input */
-
-/* Configure a pin's direction */
-extern void hd64465_gpio_configure(int portpin, int direction);
-
-/* Get, set value */
-extern void hd64465_gpio_set_pin(int portpin, unsigned int value);
-extern unsigned int hd64465_gpio_get_pin(int portpin);
-extern void hd64465_gpio_set_port(int port, unsigned int value);
-extern unsigned int hd64465_gpio_get_port(int port);
-
-/* mode constants for _register_irq() */
-#define HD64465_GPIO_FALLING   0
-#define HD64465_GPIO_RISING    1
-
-/* Interrupt on external value change */
-extern void hd64465_gpio_register_irq(int portpin, int mode,
-       void (*handler)(int portpin, void *dev), void *dev);
-extern void hd64465_gpio_unregister_irq(int portpin);
-
-#endif /* _ASM_SH_HD64465_GPIO_  */
 
+++ /dev/null
-#ifndef _ASM_SH_HD64465_
-#define _ASM_SH_HD64465_ 1
-/*
- * $Id: hd64465.h,v 1.3 2003/05/04 19:30:15 lethal Exp $
- *
- * Hitachi HD64465 companion chip support
- *
- * by Greg Banks <gbanks@pocketpenguins.com>
- * (c) 2000 PocketPenguins Inc.
- *
- * Derived from <asm/hd64461.h> which bore the message:
- * Copyright (C) 2000 YAEGASHI Takeshi
- */
-#include <asm/io.h>
-#include <asm/irq.h>
-
-/*
- * Note that registers are defined here as virtual port numbers,
- * which have no meaning except to get translated by hd64465_isa_port2addr()
- * to an address in the range 0xb0000000-0xb3ffffff.  Note that
- * this translation happens to consist of adding the lower 16 bits
- * of the virtual port number to 0xb0000000.  Note also that the manual
- * shows addresses as absolute physical addresses starting at 0x10000000,
- * so e.g. the NIRR register is listed as 0x15000 here, 0x10005000 in the
- * manual, and accessed using address 0xb0005000 - Greg.
- */
-
-/* System registers */
-#define HD64465_REG_SRR     0x1000c    /* System Revision Register */
-#define HD64465_REG_SDID    0x10010    /* System Device ID Reg */
-#define     HD64465_SDID            0x8122  /* 64465 device ID */
-
-/* Power Management registers */
-#define HD64465_REG_SMSCR   0x10000    /* System Module Standby Control Reg */
-#define            HD64465_SMSCR_PS2ST     0x4000  /* PS/2 Standby */
-#define            HD64465_SMSCR_ADCST     0x1000  /* ADC Standby */
-#define            HD64465_SMSCR_UARTST    0x0800  /* UART Standby */
-#define            HD64465_SMSCR_SCDIST    0x0200  /* Serial Codec Standby */
-#define            HD64465_SMSCR_PPST      0x0100  /* Parallel Port Standby */
-#define            HD64465_SMSCR_PC0ST     0x0040  /* PCMCIA0 Standby */
-#define            HD64465_SMSCR_PC1ST     0x0020  /* PCMCIA1 Standby */
-#define            HD64465_SMSCR_AFEST     0x0010  /* AFE Standby */
-#define            HD64465_SMSCR_TM0ST     0x0008  /* Timer0 Standby */
-#define            HD64465_SMSCR_TM1ST     0x0004  /* Timer1 Standby */
-#define            HD64465_SMSCR_IRDAST    0x0002  /* IRDA Standby */
-#define            HD64465_SMSCR_KBCST     0x0001  /* Keyboard Controller Standby */
- 
-/* Interrupt Controller registers */
-#define HD64465_REG_NIRR    0x15000    /* Interrupt Request Register */
-#define HD64465_REG_NIMR    0x15002    /* Interrupt Mask Register */
-#define HD64465_REG_NITR    0x15004    /* Interrupt Trigger Mode Register */
-
-/* Timer registers */
-#define HD64465_REG_TCVR1   0x16000    /* Timer 1 constant value register  */
-#define HD64465_REG_TCVR0   0x16002    /* Timer 0 constant value register  */
-#define HD64465_REG_TRVR1   0x16004    /* Timer 1 read value register  */
-#define HD64465_REG_TRVR0   0x16006    /* Timer 0 read value register  */
-#define HD64465_REG_TCR1    0x16008    /* Timer 1 control register  */
-#define HD64465_REG_TCR0    0x1600A    /* Timer 0 control register  */
-#define            HD64465_TCR_EADT    0x10        /* Enable ADTRIG# signal */
-#define            HD64465_TCR_ETMO    0x08        /* Enable TMO signal */
-#define            HD64465_TCR_PST_MASK 0x06       /* Clock Prescale */
-#define            HD64465_TCR_PST_1   0x06        /* 1:1 */
-#define            HD64465_TCR_PST_4   0x04        /* 1:4 */
-#define            HD64465_TCR_PST_8   0x02        /* 1:8 */
-#define            HD64465_TCR_PST_16  0x00        /* 1:16 */
-#define            HD64465_TCR_TSTP    0x01        /* Start/Stop timer */
-#define HD64465_REG_TIRR    0x1600C    /* Timer interrupt request register  */
-#define HD64465_REG_TIDR    0x1600E    /* Timer interrupt disable register  */
-#define HD64465_REG_PWM1CS  0x16010    /* PWM 1 clock scale register  */
-#define HD64465_REG_PWM1LPC 0x16012    /* PWM 1 low pulse width counter register  */
-#define HD64465_REG_PWM1HPC 0x16014    /* PWM 1 high pulse width counter register  */
-#define HD64465_REG_PWM0CS  0x16018    /* PWM 0 clock scale register  */
-#define HD64465_REG_PWM0LPC 0x1601A    /* PWM 0 low pulse width counter register  */
-#define HD64465_REG_PWM0HPC 0x1601C    /* PWM 0 high pulse width counter register  */
-
-/* Analog/Digital Converter registers */
-#define HD64465_REG_ADDRA   0x1E000    /* A/D data register A */
-#define HD64465_REG_ADDRB   0x1E002    /* A/D data register B */
-#define HD64465_REG_ADDRC   0x1E004    /* A/D data register C */
-#define HD64465_REG_ADDRD   0x1E006    /* A/D data register D */
-#define HD64465_REG_ADCSR   0x1E008    /* A/D control/status register */
-#define     HD64465_ADCSR_ADF      0x80    /* A/D End Flag */
-#define     HD64465_ADCSR_ADST     0x40    /* A/D Start Flag */
-#define     HD64465_ADCSR_ADIS     0x20    /* A/D Interrupt Status */
-#define     HD64465_ADCSR_TRGE     0x10    /* A/D Trigger Enable */
-#define     HD64465_ADCSR_ADIE     0x08    /* A/D Interrupt Enable */
-#define     HD64465_ADCSR_SCAN     0x04    /* A/D Scan Mode */
-#define     HD64465_ADCSR_CH_MASK   0x03    /* A/D Channel */
-#define HD64465_REG_ADCALCR 0x1E00A    /* A/D calibration sample control */
-#define HD64465_REG_ADCAL   0x1E00C    /* A/D calibration data register */
-
-
-/* General Purpose I/O ports registers */
-#define HD64465_REG_GPACR   0x14000    /* Port A Control Register */
-#define HD64465_REG_GPBCR   0x14002    /* Port B Control Register */
-#define HD64465_REG_GPCCR   0x14004    /* Port C Control Register */
-#define HD64465_REG_GPDCR   0x14006    /* Port D Control Register */
-#define HD64465_REG_GPECR   0x14008    /* Port E Control Register */
-#define HD64465_REG_GPADR   0x14010    /* Port A Data Register */
-#define HD64465_REG_GPBDR   0x14012    /* Port B Data Register */
-#define HD64465_REG_GPCDR   0x14014    /* Port C Data Register */
-#define HD64465_REG_GPDDR   0x14016    /* Port D Data Register */
-#define HD64465_REG_GPEDR   0x14018    /* Port E Data Register */
-#define HD64465_REG_GPAICR  0x14020    /* Port A Interrupt Control Register */
-#define HD64465_REG_GPBICR  0x14022    /* Port B Interrupt Control Register */
-#define HD64465_REG_GPCICR  0x14024    /* Port C Interrupt Control Register */
-#define HD64465_REG_GPDICR  0x14026    /* Port D Interrupt Control Register */
-#define HD64465_REG_GPEICR  0x14028    /* Port E Interrupt Control Register */
-#define HD64465_REG_GPAISR  0x14040    /* Port A Interrupt Status Register */
-#define HD64465_REG_GPBISR  0x14042    /* Port B Interrupt Status Register */
-#define HD64465_REG_GPCISR  0x14044    /* Port C Interrupt Status Register */
-#define HD64465_REG_GPDISR  0x14046    /* Port D Interrupt Status Register */
-#define HD64465_REG_GPEISR  0x14048    /* Port E Interrupt Status Register */
-
-/* PCMCIA bridge interface */
-#define HD64465_REG_PCC0ISR    0x12000 /* socket 0 interface status */ 
-#define     HD64465_PCCISR_PREADY       0x80    /* mem card ready / io card IREQ */
-#define     HD64465_PCCISR_PIREQ        0x80
-#define     HD64465_PCCISR_PMWP         0x40    /* mem card write-protected */
-#define     HD64465_PCCISR_PVS2         0x20    /* voltage select pin 2 */
-#define     HD64465_PCCISR_PVS1         0x10    /* voltage select pin 1 */
-#define     HD64465_PCCISR_PCD_MASK     0x0c    /* card detect */
-#define     HD64465_PCCISR_PBVD_MASK     0x03    /* battery voltage */
-#define     HD64465_PCCISR_PBVD_BATGOOD  0x03    /* battery good */
-#define     HD64465_PCCISR_PBVD_BATWARN  0x01    /* battery low warning */
-#define     HD64465_PCCISR_PBVD_BATDEAD1 0x02    /* battery dead */
-#define     HD64465_PCCISR_PBVD_BATDEAD2 0x00    /* battery dead */
-#define HD64465_REG_PCC0GCR    0x12002 /* socket 0 general control */ 
-#define     HD64465_PCCGCR_PDRV         0x80    /* output drive */
-#define     HD64465_PCCGCR_PCCR         0x40    /* PC card reset */
-#define     HD64465_PCCGCR_PCCT         0x20    /* PC card type, 1=IO&mem, 0=mem */
-#define     HD64465_PCCGCR_PVCC0        0x10    /* voltage control pin VCC0SEL0 */
-#define     HD64465_PCCGCR_PMMOD        0x08    /* memory mode */
-#define     HD64465_PCCGCR_PPA25        0x04    /* pin A25 */
-#define     HD64465_PCCGCR_PPA24        0x02    /* pin A24 */
-#define     HD64465_PCCGCR_PREG         0x01    /* ping PCC0REG# */
-#define HD64465_REG_PCC0CSCR   0x12004 /* socket 0 card status change */ 
-#define     HD64465_PCCCSCR_PSCDI       0x80    /* sw card detect intr */
-#define     HD64465_PCCCSCR_PSWSEL      0x40    /* power select */
-#define     HD64465_PCCCSCR_PIREQ       0x20    /* IREQ intr req */
-#define     HD64465_PCCCSCR_PSC         0x10    /* STSCHG (status change) pin */
-#define     HD64465_PCCCSCR_PCDC        0x08    /* CD (card detect) change */
-#define     HD64465_PCCCSCR_PRC         0x04    /* ready change */
-#define     HD64465_PCCCSCR_PBW         0x02    /* battery warning change */
-#define     HD64465_PCCCSCR_PBD         0x01    /* battery dead change */
-#define HD64465_REG_PCC0CSCIER 0x12006 /* socket 0 card status change interrupt enable */ 
-#define     HD64465_PCCCSCIER_PCRE      0x80    /* change reset enable */
-#define     HD64465_PCCCSCIER_PIREQE_MASK      0x60   /* IREQ enable */
-#define     HD64465_PCCCSCIER_PIREQE_DISABLED  0x00   /* IREQ disabled */
-#define     HD64465_PCCCSCIER_PIREQE_LEVEL     0x20   /* IREQ level-triggered */
-#define     HD64465_PCCCSCIER_PIREQE_FALLING   0x40   /* IREQ falling-edge-trig */
-#define     HD64465_PCCCSCIER_PIREQE_RISING    0x60   /* IREQ rising-edge-trig */
-#define     HD64465_PCCCSCIER_PSCE      0x10    /* status change enable */
-#define     HD64465_PCCCSCIER_PCDE      0x08    /* card detect change enable */
-#define     HD64465_PCCCSCIER_PRE       0x04    /* ready change enable */
-#define     HD64465_PCCCSCIER_PBWE      0x02    /* battery warn change enable */
-#define     HD64465_PCCCSCIER_PBDE      0x01    /* battery dead change enable*/
-#define HD64465_REG_PCC0SCR    0x12008 /* socket 0 software control */ 
-#define     HD64465_PCCSCR_SHDN         0x10    /* TPS2206 SHutDowN pin */
-#define     HD64465_PCCSCR_SWP          0x01    /* write protect */
-#define HD64465_REG_PCCPSR     0x1200A /* serial power switch control */ 
-#define HD64465_REG_PCC1ISR    0x12010 /* socket 1 interface status */ 
-#define HD64465_REG_PCC1GCR    0x12012 /* socket 1 general control */ 
-#define HD64465_REG_PCC1CSCR   0x12014 /* socket 1 card status change */ 
-#define HD64465_REG_PCC1CSCIER 0x12016 /* socket 1 card status change interrupt enable */ 
-#define HD64465_REG_PCC1SCR    0x12018 /* socket 1 software control */ 
-
-
-/* PS/2 Keyboard and mouse controller -- *not* register compatible */
-#define HD64465_REG_KBCSR      0x1dc00 /* Keyboard Control/Status reg */
-#define     HD64465_KBCSR_KBCIE         0x8000    /* KBCK Input Enable */
-#define     HD64465_KBCSR_KBCOE         0x4000    /* KBCK Output Enable */
-#define     HD64465_KBCSR_KBDOE         0x2000    /* KB DATA Output Enable */
-#define     HD64465_KBCSR_KBCD          0x1000    /* KBCK Driven */
-#define     HD64465_KBCSR_KBDD          0x0800    /* KB DATA Driven */
-#define     HD64465_KBCSR_KBCS          0x0400    /* KBCK pin Status */
-#define     HD64465_KBCSR_KBDS          0x0200    /* KB DATA pin Status */
-#define     HD64465_KBCSR_KBDP          0x0100    /* KB DATA Parity bit */
-#define     HD64465_KBCSR_KBD_MASK      0x00ff    /* KD DATA shift reg */
-#define HD64465_REG_KBISR      0x1dc04 /* Keyboard Interrupt Status reg */
-#define     HD64465_KBISR_KBRDF         0x0001    /* KB Received Data Full */
-#define HD64465_REG_MSCSR      0x1dc10 /* Mouse Control/Status reg */
-#define HD64465_REG_MSISR      0x1dc14 /* Mouse Interrupt Status reg */
-
-
-/*
- * Logical address at which the HD64465 is mapped.  Note that this
- * should always be in the P2 segment (uncached and untranslated).
- */
-#ifndef CONFIG_HD64465_IOBASE
-#define CONFIG_HD64465_IOBASE  0xb0000000
-#endif
-/*
- * The HD64465 multiplexes all its modules' interrupts onto
- * this single interrupt.
- */
-#ifndef CONFIG_HD64465_IRQ
-#define CONFIG_HD64465_IRQ     5
-#endif
-
-
-#define _HD64465_IO_MASK       0xf8000000
-#define is_hd64465_addr(addr) \
-       ((addr & _HD64465_IO_MASK) == (CONFIG_HD64465_IOBASE & _HD64465_IO_MASK))
-
-/*
- * A range of 16 virtual interrupts generated by
- * demuxing the HD64465 muxed interrupt.
- */
-#define HD64465_IRQ_BASE       OFFCHIP_IRQ_BASE
-#define HD64465_IRQ_NUM        16
-#define HD64465_IRQ_ADC        (HD64465_IRQ_BASE+0)
-#define HD64465_IRQ_USB        (HD64465_IRQ_BASE+1)
-#define HD64465_IRQ_SCDI       (HD64465_IRQ_BASE+2)
-#define HD64465_IRQ_PARALLEL   (HD64465_IRQ_BASE+3)
-/* bit 4 is reserved */
-#define HD64465_IRQ_UART       (HD64465_IRQ_BASE+5)
-#define HD64465_IRQ_IRDA       (HD64465_IRQ_BASE+6)
-#define HD64465_IRQ_PS2MOUSE   (HD64465_IRQ_BASE+7)
-#define HD64465_IRQ_KBC        (HD64465_IRQ_BASE+8)
-#define HD64465_IRQ_TIMER1     (HD64465_IRQ_BASE+9)
-#define HD64465_IRQ_TIMER0     (HD64465_IRQ_BASE+10)
-#define HD64465_IRQ_GPIO       (HD64465_IRQ_BASE+11)
-#define HD64465_IRQ_AFE        (HD64465_IRQ_BASE+12)
-#define HD64465_IRQ_PCMCIA1    (HD64465_IRQ_BASE+13)
-#define HD64465_IRQ_PCMCIA0    (HD64465_IRQ_BASE+14)
-#define HD64465_IRQ_PS2KBD             (HD64465_IRQ_BASE+15)
-
-/* Constants for PCMCIA mappings */
-#define HD64465_PCC_WINDOW     0x01000000
-
-#define HD64465_PCC0_BASE      0xb8000000      /* area 6 */
-#define HD64465_PCC0_ATTR      (HD64465_PCC0_BASE)
-#define HD64465_PCC0_COMM      (HD64465_PCC0_BASE+HD64465_PCC_WINDOW)
-#define HD64465_PCC0_IO                (HD64465_PCC0_BASE+2*HD64465_PCC_WINDOW)
-
-#define HD64465_PCC1_BASE      0xb4000000      /* area 5 */
-#define HD64465_PCC1_ATTR      (HD64465_PCC1_BASE)
-#define HD64465_PCC1_COMM      (HD64465_PCC1_BASE+HD64465_PCC_WINDOW)
-#define HD64465_PCC1_IO                (HD64465_PCC1_BASE+2*HD64465_PCC_WINDOW)
-
-/*
- * Base of USB controller interface (as memory)
- */
-#define HD64465_USB_BASE       (CONFIG_HD64465_IOBASE+0xb000)
-#define HD64465_USB_LEN        0x1000
-/*
- * Base of embedded SRAM, used for USB controller.
- */
-#define HD64465_SRAM_BASE      (CONFIG_HD64465_IOBASE+0x9000)
-#define HD64465_SRAM_LEN       0x1000
-
-
-
-#endif /* _ASM_SH_HD64465_  */
 
+++ /dev/null
-/*
- * include/asm-sh/hd64465/io.h
- *
- * By Greg Banks <gbanks@pocketpenguins.com>
- * (c) 2000 PocketPenguins Inc.
- *
- * Derived from io_hd64461.h, which bore the message:
- * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for an HD64465 "Windows CE Intelligent Peripheral Controller".
- */
-
-#ifndef _ASM_SH_IO_HD64465_H
-#define _ASM_SH_IO_HD64465_H
-
-extern unsigned char hd64465_inb(unsigned long port);
-extern unsigned short hd64465_inw(unsigned long port);
-extern unsigned int hd64465_inl(unsigned long port);
-
-extern void hd64465_outb(unsigned char value, unsigned long port);
-extern void hd64465_outw(unsigned short value, unsigned long port);
-extern void hd64465_outl(unsigned int value, unsigned long port);
-
-extern unsigned char hd64465_inb_p(unsigned long port);
-extern void hd64465_outb_p(unsigned char value, unsigned long port);
-
-extern unsigned long hd64465_isa_port2addr(unsigned long offset);
-extern int hd64465_irq_demux(int irq);
-/* Provision for generic secondary demux step -- used by PCMCIA code */
-extern void hd64465_register_irq_demux(int irq,
-               int (*demux)(int irq, void *dev), void *dev);
-extern void hd64465_unregister_irq_demux(int irq);
-/* Set this variable to 1 to see port traffic */
-extern int hd64465_io_debug;
-/* Map a range of ports to a range of kernel virtual memory.
- */
-extern void hd64465_port_map(unsigned short baseport, unsigned int nports,
-                            unsigned long addr, unsigned char shift);
-extern void hd64465_port_unmap(unsigned short baseport, unsigned int nports);
-
-#endif /* _ASM_SH_IO_HD64465_H */
 
 #ifndef _ASM_SERIAL_H
 #define _ASM_SERIAL_H
 
-#include <linux/kernel.h>
-
 /*
  * This assumes you have a 1.8432 MHz clock for your UART.
  *
  */
 #define BASE_BAUD ( 1843200 / 16 )
 
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-#ifdef CONFIG_HD64465
-#include <asm/hd64465/hd64465.h>
-
-#define SERIAL_PORT_DFNS                   \
-        /* UART CLK   PORT IRQ     FLAGS        */                      \
-        { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS }  /* ttyS0 */
-
-#else
-
-#define SERIAL_PORT_DFNS
-
-#endif
-
 #endif /* _ASM_SERIAL_H */
 
 # List of companion chips / MFDs.
 #
 HD64461                        HD64461
-HD64465                        HD64465
 
 #
 # List of boards.
 
 
          This driver is also available as a module called m8xx_pcmcia.
 
-config HD64465_PCMCIA
-       tristate "HD64465 host bridge support"
-       depends on HD64465 && PCMCIA
-
 config PCMCIA_AU1X00
        tristate "Au1x00 pcmcia support"
        depends on SOC_AU1X00 && PCMCIA
 
 obj-$(CONFIG_I82092)                           += i82092.o
 obj-$(CONFIG_TCIC)                             += tcic.o
 obj-$(CONFIG_PCMCIA_M8XX)                      += m8xx_pcmcia.o
-obj-$(CONFIG_HD64465_PCMCIA)                   += hd64465_ss.o
 obj-$(CONFIG_PCMCIA_SA1100)                    += sa11xx_core.o sa1100_cs.o
 obj-$(CONFIG_PCMCIA_SA1111)                    += sa11xx_core.o sa1111_cs.o
 obj-$(CONFIG_M32R_PCC)                         += m32r_pcc.o
 
+++ /dev/null
-/*
- * Device driver for the PCMCIA controller module of the
- * Hitachi HD64465 handheld companion chip.
- *
- * Note that the HD64465 provides a very thin PCMCIA host bridge
- * layer, requiring a lot of the work of supporting cards to be
- * performed by the processor.  For example: mapping of card
- * interrupts to processor IRQs is done by IRQ demuxing software;
- * IO and memory mappings are fixed; setting voltages according
- * to card Voltage Select pins etc is done in software.
- *
- * Note also that this driver uses only the simple, fixed,
- * 16MB, 16-bit wide mappings to PCMCIA spaces defined by the
- * HD64465.  Larger mappings, smaller mappings, or mappings of
- * different width to the same socket, are all possible only by
- * involving the SH7750's MMU, which is considered unnecessary here.
- * The downside is that it may be possible for some drivers to
- * break because they need or expect 8-bit mappings.
- *
- * This driver currently supports only the following configuration:
- * SH7750 CPU, HD64465, TPS2206 voltage control chip.
- *
- * by Greg Banks <gbanks@pocketpenguins.com>
- * (c) 2000 PocketPenguins Inc
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <asm/errno.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-
-#include <asm/io.h>
-#include <asm/hd64465/hd64465.h>
-#include <asm/hd64465/io.h>
-
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/ss.h>
-
-#define MODNAME "hd64465_ss"
-
-/* #define HD64465_DEBUG 1 */
-
-#if HD64465_DEBUG
-#define DPRINTK(args...)       printk(MODNAME ": " args)
-#else
-#define DPRINTK(args...)
-#endif
-
-extern int hd64465_io_debug;
-extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
-extern void p3_iounmap(void *addr);
-
-/*============================================================*/
-
-#define HS_IO_MAP_SIZE         (64*1024)
-
-typedef struct hs_socket_t
-{
-    unsigned int       number;
-    u_int              irq;
-    u_long             mem_base;
-    void               *io_base;
-    u_long             mem_length;
-    u_int              ctrl_base;
-    socket_state_t     state;
-    pccard_io_map      io_maps[MAX_IO_WIN];
-    pccard_mem_map     mem_maps[MAX_WIN];
-    struct pcmcia_socket       socket;
-} hs_socket_t;
-
-
-
-#define HS_MAX_SOCKETS 2
-static hs_socket_t hs_sockets[HS_MAX_SOCKETS];
-
-#define hs_in(sp, r)       inb((sp)->ctrl_base + (r))
-#define hs_out(sp, v, r)    outb(v, (sp)->ctrl_base + (r))
-
-
-/* translate a boolean value to a bit in a register */
-#define bool_to_regbit(sp, r, bi, bo)          \
-    do {                                       \
-       unsigned short v = hs_in(sp, r);        \
-       if (bo)                                 \
-           v |= (bi);                          \
-       else                                    \
-           v &= ~(bi);                         \
-       hs_out(sp, v, r);                       \
-    } while(0)
-    
-/* register offsets from HD64465_REG_PCC[01]ISR */
-#define ISR    0x0
-#define GCR    0x2
-#define CSCR   0x4
-#define CSCIER         0x6
-#define SCR    0x8
-
-
-/* Mask and values for CSCIER register */
-#define IER_MASK    0x80
-#define IER_ON     0x3f        /* interrupts on */
-#define IER_OFF     0x00       /* interrupts off */
-
-/*============================================================*/
-
-#if HD64465_DEBUG > 10
-
-static void cis_hex_dump(const unsigned char *x, int len)
-{
-       int i;
-       
-       for (i=0 ; i<len ; i++)
-       {
-           if (!(i & 0xf))
-               printk("\n%08x", (unsigned)(x + i));
-           printk(" %02x", *(volatile unsigned short*)x);
-           x += 2;
-       }
-       printk("\n");
-}
-
-#endif
-/*============================================================*/
-
-/*
- * This code helps create the illusion that the IREQ line from
- * the PC card is mapped to one of the CPU's IRQ lines by the
- * host bridge hardware (which is how every host bridge *except*
- * the HD64465 works).  In particular, it supports enabling
- * and disabling the IREQ line by code which knows nothing
- * about the host bridge (e.g. device drivers, IDE code) using
- * the request_irq(), free_irq(), probe_irq_on() and probe_irq_off()
- * functions.  Also, it supports sharing the mapped IRQ with
- * real hardware IRQs from the -IRL0-3 lines.
- */
-
-#define HS_NUM_MAPPED_IRQS  16 /* Limitation of the PCMCIA code */
-static struct
-{
-    /* index is mapped irq number */
-    hs_socket_t *sock;
-    hw_irq_controller *old_handler;
-} hs_mapped_irq[HS_NUM_MAPPED_IRQS];
-
-static void hs_socket_enable_ireq(hs_socket_t *sp)
-{
-       unsigned short cscier;
-       
-       DPRINTK("hs_socket_enable_ireq(sock=%d)\n", sp->number);
-
-       cscier = hs_in(sp, CSCIER);
-       cscier &= ~HD64465_PCCCSCIER_PIREQE_MASK;
-       cscier |= HD64465_PCCCSCIER_PIREQE_LEVEL;
-       hs_out(sp, cscier, CSCIER);
-}
-
-static void hs_socket_disable_ireq(hs_socket_t *sp)
-{
-       unsigned short cscier;
-       
-       DPRINTK("hs_socket_disable_ireq(sock=%d)\n", sp->number);
-       
-       cscier = hs_in(sp, CSCIER);
-       cscier &= ~HD64465_PCCCSCIER_PIREQE_MASK;
-       hs_out(sp, cscier, CSCIER);
-}
-
-static unsigned int hs_startup_irq(unsigned int irq)
-{
-       hs_socket_enable_ireq(hs_mapped_irq[irq].sock);
-       hs_mapped_irq[irq].old_handler->startup(irq);
-       return 0;
-}
-
-static void hs_shutdown_irq(unsigned int irq)
-{
-       hs_socket_disable_ireq(hs_mapped_irq[irq].sock);
-       hs_mapped_irq[irq].old_handler->shutdown(irq);
-}
-
-static void hs_enable_irq(unsigned int irq)
-{
-       hs_socket_enable_ireq(hs_mapped_irq[irq].sock);
-       hs_mapped_irq[irq].old_handler->enable(irq);
-}
-
-static void hs_disable_irq(unsigned int irq)
-{
-       hs_socket_disable_ireq(hs_mapped_irq[irq].sock);
-       hs_mapped_irq[irq].old_handler->disable(irq);
-}
-
-extern struct hw_interrupt_type no_irq_type;
-
-static void hs_mask_and_ack_irq(unsigned int irq)
-{
-       hs_socket_disable_ireq(hs_mapped_irq[irq].sock);
-       /* ack_none() spuriously complains about an unexpected IRQ */
-       if (hs_mapped_irq[irq].old_handler != &no_irq_type)
-           hs_mapped_irq[irq].old_handler->ack(irq);
-}
-
-static void hs_end_irq(unsigned int irq)
-{
-       hs_socket_enable_ireq(hs_mapped_irq[irq].sock);
-       hs_mapped_irq[irq].old_handler->end(irq);
-}
-
-
-static struct hw_interrupt_type hd64465_ss_irq_type = {
-       .typename       = "PCMCIA-IRQ",
-       .startup        = hs_startup_irq,
-       .shutdown       = hs_shutdown_irq,
-       .enable         = hs_enable_irq,
-       .disable        = hs_disable_irq,
-       .ack            = hs_mask_and_ack_irq,
-       .end            = hs_end_irq
-};
-
-/* 
- * This function should only ever be called with interrupts disabled.
- */
-static void hs_map_irq(hs_socket_t *sp, unsigned int irq)
-{
-       struct irq_desc *desc;
-
-       DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq);
-       
-       if (irq >= HS_NUM_MAPPED_IRQS)
-           return;
-
-       desc = irq_to_desc(irq);
-       hs_mapped_irq[irq].sock = sp;
-       /* insert ourselves as the irq controller */
-       hs_mapped_irq[irq].old_handler = desc->chip;
-       desc->chip = &hd64465_ss_irq_type;
-}
-
-
-/* 
- * This function should only ever be called with interrupts disabled.
- */
-static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq)
-{
-       struct irq_desc *desc;
-
-       DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq);
-       
-       if (irq >= HS_NUM_MAPPED_IRQS)
-           return;
-               
-       desc = irq_to_desc(irq);
-       /* restore the original irq controller */
-       desc->chip = hs_mapped_irq[irq].old_handler;
-}
-
-/*============================================================*/
-
-
-/*
- * Set Vpp and Vcc (in tenths of a Volt).  Does not
- * support the hi-Z state.
- *
- * Note, this assumes the board uses a TPS2206 chip to control
- * the Vcc and Vpp voltages to the hs_sockets.  If your board
- * uses the MIC2563 (also supported by the HD64465) then you
- * will have to modify this function.
- */
-                                        /* 0V   3.3V  5.5V */
-static const u_char hs_tps2206_avcc[3] = { 0x00, 0x04, 0x08 };
-static const u_char hs_tps2206_bvcc[3] = { 0x00, 0x80, 0x40 };
-
-static int hs_set_voltages(hs_socket_t *sp, int Vcc, int Vpp)
-{
-       u_int psr;
-       u_int vcci = 0;
-       u_int sock = sp->number;
-       
-       DPRINTK("hs_set_voltage(%d, %d, %d)\n", sock, Vcc, Vpp);
-
-       switch (Vcc)
-       {
-       case 0:  vcci = 0; break;
-       case 33: vcci = 1; break;
-       case 50: vcci = 2; break;
-       default: return 0;
-       }
-
-       /* Note: Vpp = 120 not supported -- Greg Banks */
-       if (Vpp != 0 && Vpp != Vcc)
-           return 0;
-       
-       /* The PSR register holds 8 of the 9 bits which control
-        * the TPS2206 via its serial interface.
-        */
-       psr = inw(HD64465_REG_PCCPSR);
-       switch (sock)
-       {
-       case 0:
-           psr &= 0x0f;
-           psr |= hs_tps2206_avcc[vcci];
-           psr |= (Vpp == 0 ? 0x00 : 0x02);
-           break;
-       case 1:
-           psr &= 0xf0;
-           psr |= hs_tps2206_bvcc[vcci];
-           psr |= (Vpp == 0 ? 0x00 : 0x20);
-           break;
-       };
-       outw(psr, HD64465_REG_PCCPSR);
-       
-       return 1;
-}
-
-
-/*============================================================*/
-
-/*
- * Drive the RESET line to the card.
- */
-static void hs_reset_socket(hs_socket_t *sp, int on)
-{
-       unsigned short v;
-       
-       v = hs_in(sp, GCR);
-       if (on)
-           v |= HD64465_PCCGCR_PCCR;
-       else
-           v &= ~HD64465_PCCGCR_PCCR;
-       hs_out(sp, v, GCR);
-}
-
-/*============================================================*/
-
-static int hs_init(struct pcmcia_socket *s)
-{
-       hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-       
-       DPRINTK("hs_init(%d)\n", sp->number);
-
-       return 0;
-}
-
-/*============================================================*/
-
-
-static int hs_get_status(struct pcmcia_socket *s, u_int *value)
-{
-       hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-       unsigned int isr;
-       u_int status = 0;
-       
-       
-       isr = hs_in(sp, ISR);
-
-       /* Card is seated and powered when *both* CD pins are low */
-       if ((isr & HD64465_PCCISR_PCD_MASK) == 0)
-       {
-           status |= SS_DETECT;    /* card present */
-
-           switch (isr & HD64465_PCCISR_PBVD_MASK)
-           {
-           case HD64465_PCCISR_PBVD_BATGOOD:   
-               break;
-           case HD64465_PCCISR_PBVD_BATWARN:
-               status |= SS_BATWARN;
-               break;
-           default:
-               status |= SS_BATDEAD;
-               break;
-           }
-
-           if (isr & HD64465_PCCISR_PREADY)
-               status |= SS_READY;
-
-           if (isr & HD64465_PCCISR_PMWP)
-               status |= SS_WRPROT;
-               
-           /* Voltage Select pins interpreted as per Table 4-5 of the std.
-            * Assuming we have the TPS2206, the socket is a "Low Voltage
-            * key, 3.3V and 5V available, no X.XV available".
-            */
-           switch (isr & (HD64465_PCCISR_PVS2|HD64465_PCCISR_PVS1))
-           {
-           case HD64465_PCCISR_PVS1:
-               printk(KERN_NOTICE MODNAME ": cannot handle X.XV card, ignored\n");
-               status = 0;
-               break;
-           case 0:
-           case HD64465_PCCISR_PVS2:
-               /* 3.3V */
-               status |= SS_3VCARD;
-               break;
-           case HD64465_PCCISR_PVS2|HD64465_PCCISR_PVS1:
-               /* 5V */
-               break;
-           }
-               
-           /* TODO: SS_POWERON */
-           /* TODO: SS_STSCHG */
-       }       
-       
-       DPRINTK("hs_get_status(%d) = %x\n", sock, status);
-       
-       *value = status;
-       return 0;
-}
-
-/*============================================================*/
-
-static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-       hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-       u_long flags;
-       u_int changed;
-       unsigned short cscier;
-
-       DPRINTK("hs_set_socket(sock=%d, flags=%x, csc_mask=%x, Vcc=%d, Vpp=%d, io_irq=%d)\n",
-           sock, state->flags, state->csc_mask, state->Vcc, state->Vpp, state->io_irq);
-       
-       local_irq_save(flags);  /* Don't want interrupts happening here */
-
-       if (state->Vpp != sp->state.Vpp ||
-           state->Vcc != sp->state.Vcc) {
-           if (!hs_set_voltages(sp, state->Vcc, state->Vpp)) {
-               local_irq_restore(flags);
-               return -EINVAL;
-           }
-       }
-
-/*     hd64465_io_debug = 1; */
-       /*
-        * Handle changes in the Card Status Change mask,
-        * by propagating to the CSCR register
-        */     
-       changed = sp->state.csc_mask ^ state->csc_mask;
-       cscier = hs_in(sp, CSCIER);
-           
-       if (changed & SS_DETECT) {
-           if (state->csc_mask & SS_DETECT)
-               cscier |= HD64465_PCCCSCIER_PCDE;
-           else
-               cscier &= ~HD64465_PCCCSCIER_PCDE;
-       }
-
-       if (changed & SS_READY) {
-           if (state->csc_mask & SS_READY)
-               cscier |= HD64465_PCCCSCIER_PRE;
-           else
-               cscier &= ~HD64465_PCCCSCIER_PRE;
-       }
-
-       if (changed & SS_BATDEAD) {
-           if (state->csc_mask & SS_BATDEAD)
-               cscier |= HD64465_PCCCSCIER_PBDE;
-           else
-               cscier &= ~HD64465_PCCCSCIER_PBDE;
-       }
-
-       if (changed & SS_BATWARN) {
-           if (state->csc_mask & SS_BATWARN)
-               cscier |= HD64465_PCCCSCIER_PBWE;
-           else
-               cscier &= ~HD64465_PCCCSCIER_PBWE;
-       }
-
-       if (changed & SS_STSCHG) {
-           if (state->csc_mask & SS_STSCHG)
-               cscier |= HD64465_PCCCSCIER_PSCE;
-           else
-               cscier &= ~HD64465_PCCCSCIER_PSCE;
-       }
-
-       hs_out(sp, cscier, CSCIER);
-
-       if (sp->state.io_irq && !state->io_irq)
-           hs_unmap_irq(sp, sp->state.io_irq);
-       else if (!sp->state.io_irq && state->io_irq)
-           hs_map_irq(sp, state->io_irq);
-
-
-       /*
-        * Handle changes in the flags field,
-        * by propagating to config registers.
-        */     
-       changed = sp->state.flags ^ state->flags;
-
-       if (changed & SS_IOCARD) {
-           DPRINTK("card type: %s\n",
-                   (state->flags & SS_IOCARD ? "i/o" : "memory" ));
-           bool_to_regbit(sp, GCR, HD64465_PCCGCR_PCCT,
-               state->flags & SS_IOCARD);
-       }
-
-       if (changed & SS_RESET) {
-           DPRINTK("%s reset card\n",
-               (state->flags & SS_RESET ? "start" : "stop"));
-           bool_to_regbit(sp, GCR, HD64465_PCCGCR_PCCR,
-               state->flags & SS_RESET);
-       }
-
-       if (changed & SS_OUTPUT_ENA) {
-           DPRINTK("%sabling card output\n",
-               (state->flags & SS_OUTPUT_ENA ? "en" : "dis"));
-           bool_to_regbit(sp, GCR, HD64465_PCCGCR_PDRV,
-               state->flags & SS_OUTPUT_ENA);
-       }
-
-       /* TODO: SS_SPKR_ENA */
-           
-/*     hd64465_io_debug = 0; */
-       sp->state = *state;
-           
-       local_irq_restore(flags);
-
-#if HD64465_DEBUG > 10
-       if (state->flags & SS_OUTPUT_ENA)   
-           cis_hex_dump((const unsigned char*)sp->mem_base, 0x100);
-#endif
-       return 0;
-}
-
-/*============================================================*/
-
-static int hs_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
-{
-       hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-       int map = io->map;
-       int sock = sp->number;
-       struct pccard_io_map *sio;
-       pgprot_t prot;
-
-       DPRINTK("hs_set_io_map(sock=%d, map=%d, flags=0x%x, speed=%dns, start=%#lx, stop=%#lx)\n",
-           sock, map, io->flags, io->speed, io->start, io->stop);
-       if (map >= MAX_IO_WIN)
-           return -EINVAL;
-       sio = &sp->io_maps[map];
-
-       /* check for null changes */    
-       if (io->flags == sio->flags &&
-           io->start == sio->start &&
-           io->stop == sio->stop)
-           return 0;
-       
-       if (io->flags & MAP_AUTOSZ)
-           prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IODYN);
-       else if (io->flags & MAP_16BIT)
-           prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IO16);
-       else
-           prot = PAGE_KERNEL_PCC(sock, _PAGE_PCC_IO8);
-
-       /* TODO: handle MAP_USE_WAIT */
-       if (io->flags & MAP_USE_WAIT)
-           printk(KERN_INFO MODNAME ": MAP_USE_WAIT unimplemented\n");
-       /* TODO: handle MAP_PREFETCH */
-       if (io->flags & MAP_PREFETCH)
-           printk(KERN_INFO MODNAME ": MAP_PREFETCH unimplemented\n");
-       /* TODO: handle MAP_WRPROT */
-       if (io->flags & MAP_WRPROT)
-           printk(KERN_INFO MODNAME ": MAP_WRPROT unimplemented\n");
-       /* TODO: handle MAP_0WS */
-       if (io->flags & MAP_0WS)
-           printk(KERN_INFO MODNAME ": MAP_0WS unimplemented\n");
-
-       if (io->flags & MAP_ACTIVE) {
-           unsigned long pstart, psize, paddrbase;
-           
-           paddrbase = virt_to_phys((void*)(sp->mem_base + 2 * HD64465_PCC_WINDOW));
-           pstart = io->start & PAGE_MASK;
-           psize = ((io->stop + PAGE_SIZE) & PAGE_MASK) - pstart;
-
-           /*
-            * Change PTEs in only that portion of the mapping requested
-            * by the caller.  This means that most of the time, most of
-            * the PTEs in the io_vma will be unmapped and only the bottom
-            * page will be mapped.  But the code allows for weird cards
-            * that might want IO ports > 4K.
-            */
-           sp->io_base = p3_ioremap(paddrbase + pstart, psize, pgprot_val(prot));
-           
-           /*
-            * Change the mapping used by inb() outb() etc
-            */
-           hd64465_port_map(io->start,
-               io->stop - io->start + 1,
-               (unsigned long)sp->io_base + io->start, 0);
-       } else {
-           hd64465_port_unmap(sio->start, sio->stop - sio->start + 1);
-           p3_iounmap(sp->io_base);
-       }
-       
-       *sio = *io;
-       return 0;
-}
-
-/*============================================================*/
-
-static int hs_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
-{
-       hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-       struct pccard_mem_map *smem;
-       int map = mem->map;
-       unsigned long paddr;
-
-#if 0
-       DPRINTK("hs_set_mem_map(sock=%d, map=%d, flags=0x%x, card_start=0x%08x)\n",
-           sock, map, mem->flags, mem->card_start);
-#endif
-
-       if (map >= MAX_WIN)
-           return -EINVAL;
-       smem = &sp->mem_maps[map];
-       
-       paddr = sp->mem_base;               /* base of Attribute mapping */
-       if (!(mem->flags & MAP_ATTRIB))
-           paddr += HD64465_PCC_WINDOW;    /* base of Common mapping */
-       paddr += mem->card_start;
-
-       /* Because we specified SS_CAP_STATIC_MAP, we are obliged
-        * at this time to report the system address corresponding
-        * to the card address requested.  This is how Socket Services
-        * queries our fixed mapping.  I wish this fact had been
-        * documented - Greg Banks.
-        */
-       mem->static_start = paddr;
-       
-       *smem = *mem;
-       
-       return 0;
-}
-
-/* TODO: do we need to use the MMU to access Common memory ??? */
-
-/*============================================================*/
-
-/*
- * This function is registered with the HD64465 glue code to do a
- * secondary demux step on the PCMCIA interrupts.  It handles 
- * mapping the IREQ request from the card to a standard Linux
- * IRQ, as requested by SocketServices.
- */
-static int hs_irq_demux(int irq, void *dev)
-{
-       hs_socket_t *sp = dev;
-       u_int cscr;
-       
-       DPRINTK("hs_irq_demux(irq=%d)\n", irq);
-
-       if (sp->state.io_irq &&
-           (cscr = hs_in(sp, CSCR)) & HD64465_PCCCSCR_PIREQ) {
-           cscr &= ~HD64465_PCCCSCR_PIREQ;
-           hs_out(sp, cscr, CSCR);
-           return sp->state.io_irq;
-       }
-           
-       return irq;
-}
-
-/*============================================================*/
-
-/*
- * Interrupt handling routine.
- */
- 
-static irqreturn_t hs_interrupt(int irq, void *dev)
-{
-       hs_socket_t *sp = dev;
-       u_int events = 0;
-       u_int cscr;
-
-       cscr = hs_in(sp, CSCR);
-       
-       DPRINTK("hs_interrupt, cscr=%04x\n", cscr);
-
-       /* check for bus-related changes to be reported to Socket Services */
-       if (cscr & HD64465_PCCCSCR_PCDC) {
-           /* double-check for a 16-bit card, as we don't support CardBus */
-           if ((hs_in(sp, ISR) & HD64465_PCCISR_PCD_MASK) != 0) {
-               printk(KERN_NOTICE MODNAME
-                   ": socket %d, card not a supported card type or not inserted correctly\n",
-                   sp->number);
-               /* Don't do the rest unless a card is present */
-               cscr &= ~(HD64465_PCCCSCR_PCDC|
-                         HD64465_PCCCSCR_PRC|
-                         HD64465_PCCCSCR_PBW|
-                         HD64465_PCCCSCR_PBD|
-                         HD64465_PCCCSCR_PSC);
-           } else {
-               cscr &= ~HD64465_PCCCSCR_PCDC;
-               events |= SS_DETECT;            /* card insertion or removal */
-           }
-       }
-       if (cscr & HD64465_PCCCSCR_PRC) {
-           cscr &= ~HD64465_PCCCSCR_PRC;
-           events |= SS_READY;         /* ready signal changed */
-       }
-       if (cscr & HD64465_PCCCSCR_PBW) {
-           cscr &= ~HD64465_PCCCSCR_PSC;
-           events |= SS_BATWARN;       /* battery warning */
-       }
-       if (cscr & HD64465_PCCCSCR_PBD) {
-           cscr &= ~HD64465_PCCCSCR_PSC;
-           events |= SS_BATDEAD;       /* battery dead */
-       }
-       if (cscr & HD64465_PCCCSCR_PSC) {
-           cscr &= ~HD64465_PCCCSCR_PSC;
-           events |= SS_STSCHG;        /* STSCHG (status changed) signal */
-       }
-       
-       if (cscr & HD64465_PCCCSCR_PIREQ) {
-           cscr &= ~HD64465_PCCCSCR_PIREQ;
-
-           /* This should have been dealt with during irq demux */         
-           printk(KERN_NOTICE MODNAME ": unexpected IREQ from card\n");
-       }
-
-       hs_out(sp, cscr, CSCR);
-
-       if (events)
-               pcmcia_parse_events(&sp->socket, events);
-
-       return IRQ_HANDLED;
-}
-
-/*============================================================*/
-
-static struct pccard_operations hs_operations = {
-       .init                   = hs_init,
-       .get_status             = hs_get_status,
-       .set_socket             = hs_set_socket,
-       .set_io_map             = hs_set_io_map,
-       .set_mem_map            = hs_set_mem_map,
-};
-
-static int hs_init_socket(hs_socket_t *sp, int irq, unsigned long mem_base,
-           unsigned int ctrl_base)
-{
-       unsigned short v;
-       int i, err;
-
-       memset(sp, 0, sizeof(*sp));
-       sp->irq = irq;
-       sp->mem_base = mem_base;
-       sp->mem_length = 4*HD64465_PCC_WINDOW;  /* 16MB */
-       sp->ctrl_base = ctrl_base;
-       
-       for (i=0 ; i<MAX_IO_WIN ; i++)
-           sp->io_maps[i].map = i;
-       for (i=0 ; i<MAX_WIN ; i++)
-           sp->mem_maps[i].map = i;
-       
-       hd64465_register_irq_demux(sp->irq, hs_irq_demux, sp);
-       
-       if ((err = request_irq(sp->irq, hs_interrupt, IRQF_DISABLED, MODNAME, sp)) < 0)
-           return err;
-       if (request_mem_region(sp->mem_base, sp->mem_length, MODNAME) == 0) {
-           sp->mem_base = 0;
-           return -ENOMEM;
-       }
-
-
-       /* According to section 3.2 of the PCMCIA standard, low-voltage
-        * capable cards must implement cold insertion, i.e. Vpp and
-        * Vcc set to 0 before card is inserted.
-        */
-       /*hs_set_voltages(sp, 0, 0);*/
-       
-       /* hi-Z the outputs to the card and set 16MB map mode */
-       v = hs_in(sp, GCR);
-       v &= ~HD64465_PCCGCR_PCCT;      /* memory-only card */
-       hs_out(sp, v, GCR);
-
-       v = hs_in(sp, GCR);
-       v |= HD64465_PCCGCR_PDRV;       /* enable outputs to card */
-       hs_out(sp, v, GCR);
-
-       v = hs_in(sp, GCR);
-       v |= HD64465_PCCGCR_PMMOD;      /* 16MB mapping mode */
-       hs_out(sp, v, GCR);
-
-       v = hs_in(sp, GCR);
-       /* lowest 16MB of Common */
-       v &= ~(HD64465_PCCGCR_PPA25|HD64465_PCCGCR_PPA24); 
-       hs_out(sp, v, GCR);
-       
-       hs_reset_socket(sp, 1);
-
-       printk(KERN_INFO "HD64465 PCMCIA bridge socket %d at 0x%08lx irq %d\n",
-               i, sp->mem_base, sp->irq);
-
-       return 0;
-}
-
-static void hs_exit_socket(hs_socket_t *sp)
-{
-       unsigned short cscier, gcr;
-       unsigned long flags;
-       
-       local_irq_save(flags);
-
-       /* turn off interrupts in hardware */
-       cscier = hs_in(sp, CSCIER);
-       cscier = (cscier & IER_MASK) | IER_OFF;
-       hs_out(sp, cscier, CSCIER);
-       
-       /* hi-Z the outputs to the card */
-       gcr = hs_in(sp, GCR);
-       gcr &= HD64465_PCCGCR_PDRV;
-       hs_out(sp, gcr, GCR);
-
-       /* power the card down */
-       hs_set_voltages(sp, 0, 0);
-
-       if (sp->mem_base != 0)
-           release_mem_region(sp->mem_base, sp->mem_length);
-       if (sp->irq != 0) {
-           free_irq(sp->irq, hs_interrupt);
-           hd64465_unregister_irq_demux(sp->irq);
-       }
-
-       local_irq_restore(flags);
-}
-
-static struct device_driver hd64465_driver = {
-       .name = "hd64465-pcmcia",
-       .bus = &platform_bus_type,
-       .suspend = pcmcia_socket_dev_suspend,
-       .resume = pcmcia_socket_dev_resume,
-};
-
-static struct platform_device hd64465_device = {
-       .name = "hd64465-pcmcia",
-       .id = 0,
-};
-
-static int __init init_hs(void)
-{
-       int i;
-       unsigned short v;
-
-/*     hd64465_io_debug = 1; */
-       if (driver_register(&hd64465_driver))
-               return -EINVAL;
-       
-       /* Wake both sockets out of STANDBY mode */
-       /* TODO: wait 15ms */
-       v = inw(HD64465_REG_SMSCR);
-       v &= ~(HD64465_SMSCR_PC0ST|HD64465_SMSCR_PC1ST);
-       outw(v, HD64465_REG_SMSCR);
-
-       /* keep power controller out of shutdown mode */
-       v = inb(HD64465_REG_PCC0SCR);
-       v |= HD64465_PCCSCR_SHDN;
-       outb(v, HD64465_REG_PCC0SCR);
-
-       /* use serial (TPS2206) power controller */
-       v = inb(HD64465_REG_PCC0CSCR);
-       v |= HD64465_PCCCSCR_PSWSEL;
-       outb(v, HD64465_REG_PCC0CSCR);
-
-       /*
-        * Setup hs_sockets[] structures and request system resources.
-        * TODO: on memory allocation failure, power down the socket
-        *       before quitting.
-        */
-       for (i=0; i<HS_MAX_SOCKETS; i++) {
-               hs_set_voltages(&hs_sockets[i], 0, 0);
-
-               hs_sockets[i].socket.features |=  SS_CAP_PCCARD | SS_CAP_STATIC_MAP;      /* mappings are fixed in host memory */
-               hs_sockets[i].socket.resource_ops = &pccard_static_ops;
-               hs_sockets[i].socket.irq_mask =  0xffde;/*0xffff*/          /* IRQs mapped in s/w so can do any, really */
-               hs_sockets[i].socket.map_size = HD64465_PCC_WINDOW;     /* 16MB fixed window size */
-
-               hs_sockets[i].socket.owner = THIS_MODULE;
-               hs_sockets[i].socket.ss_entry = &hs_operations;
-       }
-
-       i = hs_init_socket(&hs_sockets[0],
-           HD64465_IRQ_PCMCIA0,
-           HD64465_PCC0_BASE,
-           HD64465_REG_PCC0ISR);
-       if (i < 0) {
-               unregister_driver(&hd64465_driver);
-               return i;
-       }
-       i = hs_init_socket(&hs_sockets[1],
-           HD64465_IRQ_PCMCIA1,
-           HD64465_PCC1_BASE,
-           HD64465_REG_PCC1ISR);
-       if (i < 0) {
-               unregister_driver(&hd64465_driver);
-               return i;
-       }
-
-/*     hd64465_io_debug = 0; */
-
-       platform_device_register(&hd64465_device);
-
-       for (i=0; i<HS_MAX_SOCKETS; i++) {
-               unsigned int ret;
-               hs_sockets[i].socket.dev.parent = &hd64465_device.dev;
-               hs_sockets[i].number = i;
-               ret = pcmcia_register_socket(&hs_sockets[i].socket);
-               if (ret && i)
-                       pcmcia_unregister_socket(&hs_sockets[0].socket);
-       }
-
-       return 0;
-}
-
-static void __exit exit_hs(void)
-{
-       int i;
-
-       for (i=0 ; i<HS_MAX_SOCKETS ; i++) {
-               pcmcia_unregister_socket(&hs_sockets[i].socket);
-               hs_exit_socket(&hs_sockets[i]);
-       }
-
-       platform_device_unregister(&hd64465_device);
-       unregister_driver(&hd64465_driver);
-}
-
-module_init(init_hs);
-module_exit(exit_hs);
-
-/*============================================================*/
-/*END*/