]> err.no Git - linux-2.6/blobdiff - drivers/ide/ppc/mpc8xx.c
Merge branches 'at91', 'dyntick', 'ep93xx', 'iop', 'ixp', 'misc', 'orion', 'omap...
[linux-2.6] / drivers / ide / ppc / mpc8xx.c
index ebaba01c7551287a44b140e8cb8cd10d3decfb9e..236f9c38e5198d33614beeb61d22311ae70c733e 100644 (file)
@@ -36,6 +36,8 @@
 #include <asm/machdep.h>
 #include <asm/irq.h>
 
+#define DRV_NAME "ide-mpc8xx"
+
 static int identify  (volatile u8 *p);
 static void print_fixed (volatile u8 *p);
 static void print_funcid (int func);
@@ -99,32 +101,6 @@ static int _slot_ = -1;                     /* will be read from PCMCIA registers   */
 /* Make clock cycles and always round up */
 #define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U )
 
-
-
-/*
- * IDE stuff.
- */
-static int
-m8xx_ide_default_irq(unsigned long base)
-{
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
-       if (base >= MAX_HWIFS)
-               return 0;
-
-       printk("[%d] m8xx_ide_default_irq %d\n",__LINE__,ioport_dsc[base].irq);
-       
-       return (ioport_dsc[base].irq);
-#else
-        return 9;
-#endif
-}
-
-static unsigned long
-m8xx_ide_default_io_base(int index)
-{
-        return index;
-}
-
 #define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
 #define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
 
@@ -149,14 +125,13 @@ static int pcmcia_schlvl = PCMCIA_SCHLVL;
  */
 
 /*
- * m8xx_ide_init_hwif_ports for a direct IDE interface _using_
+ * m8xx_ide_init_ports() for a direct IDE interface _using_
+ * MPC8xx's internal PCMCIA interface
  */
 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
-static void
-m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, 
-               unsigned long ctrl_port, int *irq)
+static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 {
-       unsigned long *p = hw->io_ports;
+       unsigned long *p = hw->io_ports_array;
        int i;
 
        typedef struct {
@@ -173,8 +148,6 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
        unsigned long base;
 
        *p = 0;
-       if (irq)
-               *irq = 0;
 
        pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
 
@@ -211,6 +184,13 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
                        pcmcia_phy_base, pcmcia_phy_end,
                        pcmcia_phy_end - pcmcia_phy_base);
 
+               if (!request_mem_region(pcmcia_phy_base,
+                                       pcmcia_phy_end - pcmcia_phy_base,
+                                       DRV_NAME)) {
+                       printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+                       return -EBUSY;
+               }
+
                pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base,
                                                   pcmcia_phy_end-pcmcia_phy_base);
 
@@ -248,9 +228,6 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
                }
        }
 
-       if (data_port >= MAX_HWIFS)
-               return;
-
        if (_slot_ == -1) {
                printk ("PCMCIA slot has not been defined! Using A as default\n");
                _slot_ = 0;
@@ -268,7 +245,7 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
        if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) {
                printk ("No card in slot %c: PIPR=%08x\n",
                        'A' + _slot_, (u32) pcmp->pcmc_pipr);
-               return;         /* No card in slot */
+               return -ENODEV;         /* No card in slot */
        }
 
        check_ide_device (pcmcia_base);
@@ -292,11 +269,13 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
                *p++ = base + ioport_dsc[data_port].reg_off[i];
        }
 
-       if (irq) {
+       hw->irq = ioport_dsc[data_port].irq;
+       hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
+
 #ifdef CONFIG_IDE_8xx_PCCARD
+       {
                unsigned int reg;
 
-               *irq = ioport_dsc[data_port].irq;
                if (_slot_)
                        pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcrb;
                else
@@ -306,14 +285,8 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
                reg |= mk_int_int_mask (pcmcia_schlvl) << 24;
                reg |= mk_int_int_mask (pcmcia_schlvl) << 16;
                *pgcrx = reg;
-#else  /* direct connected IDE drive, i.e. external IRQ, not the PCMCIA irq */
-               *irq = ioport_dsc[data_port].irq;
-#endif /* CONFIG_IDE_8xx_PCCARD */
        }
-
-       ide_hwifs[data_port].pio_mask = ATA_PIO4;
-       ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
-       ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
+#endif /* CONFIG_IDE_8xx_PCCARD */
 
        /* Enable Harddisk Interrupt,
         * and make it edge sensitive
@@ -329,18 +302,21 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
        /* Enable falling edge irq */
        pcmp->pcmc_per = 0x100000 >> (16 * _slot_);
 #endif /* CONFIG_IDE_8xx_PCCARD */
-}      /* m8xx_ide_init_hwif_ports() using 8xx internal PCMCIA interface */
+
+       hw->chipset = ide_generic;
+
+       return 0;
+}
 #endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */
 
 /*
- * m8xx_ide_init_hwif_ports for a direct IDE interface _not_ using
+ * m8xx_ide_init_ports() for a direct IDE interface _not_ using
  * MPC8xx's internal PCMCIA interface
  */
 #if defined(CONFIG_IDE_EXT_DIRECT)
-void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
-       unsigned long data_port, unsigned long ctrl_port, int *irq)
+static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 {
-       unsigned long *p = hw->io_ports;
+       unsigned long *p = hw->io_ports_array;
        int i;
 
        u32 ide_phy_base;
@@ -349,8 +325,6 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
        unsigned long base;
 
        *p = 0;
-       if (irq)
-               *irq = 0;
 
        if (!ide_base) {
 
@@ -363,7 +337,12 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
                printk ("IDE phys mem : %08x...%08x (size %08x)\n",
                        ide_phy_base, ide_phy_end,
                        ide_phy_end - ide_phy_base);
-               
+
+               if (!request_mem_region(ide_phy_base, 0x200, DRV_NAME)) {
+                       printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+                       return -EBUSY;
+               }
+
                ide_base=(unsigned long)ioremap(ide_phy_base,
                                                ide_phy_end-ide_phy_base);
 
@@ -372,9 +351,6 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
 #endif
        }
 
-       if (data_port >= MAX_HWIFS)
-               return;
-
        base = ide_base + ioport_dsc[data_port].base_off;
 #ifdef DEBUG
        printk ("base: %08x + %08x = %08x\n",
@@ -392,14 +368,9 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
                *p++ = base + ioport_dsc[data_port].reg_off[i];
        }
 
-       if (irq) {
-               /* direct connected IDE drive, i.e. external IRQ */
-               *irq = ioport_dsc[data_port].irq;
-       }
-
-       ide_hwifs[data_port].pio_mask = ATA_PIO4;
-       ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
-       ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
+       /* direct connected IDE drive, i.e. external IRQ */
+       hw->irq = ioport_dsc[data_port].irq;
+       hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
 
        /* Enable Harddisk Interrupt,
         * and make it edge sensitive
@@ -407,8 +378,11 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
        /* (11-18) Set edge detect for irq, no wakeup from low power mode */
        ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |=
                        (0x80000000 >> ioport_dsc[data_port].irq);
-}      /* m8xx_ide_init_hwif_ports() for CONFIG_IDE_8xx_DIRECT */ 
 
+       hw->chipset = ide_generic;
+
+       return 0;
+}
 #endif /* CONFIG_IDE_8xx_DIRECT */
 
 
@@ -468,10 +442,14 @@ static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 #elif defined(CONFIG_IDE_EXT_DIRECT)
 
        printk("%s[%d] %s: not implemented yet!\n",
-               __FILE__,__LINE__,__FUNCTION__);
+               __FILE__, __LINE__, __func__);
 #endif /* defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_PCMCIA */
 }
 
+static const struct ide_port_ops m8xx_port_ops = {
+       .set_pio_mode           = m8xx_ide_set_pio_mode,
+};
+
 static void
 ide_interrupt_ack (void *dev)
 {
@@ -829,21 +807,37 @@ static int identify  (volatile u8 *p)
        return (0);     /* don't know */
 }
 
-void m8xx_ide_init(void)
-{
-       ppc_ide_md.default_irq          = m8xx_ide_default_irq;
-       ppc_ide_md.default_io_base      = m8xx_ide_default_io_base;
-       ppc_ide_md.ide_init_hwif        = m8xx_ide_init_hwif_ports;
-}
-
 static int __init mpc8xx_ide_probe(void)
 {
+       hw_regs_t hw;
        u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 #ifdef IDE0_BASE_OFFSET
-       idx[0] = 0;
+       memset(&hw, 0, sizeof(hw));
+       if (!m8xx_ide_init_ports(&hw, 0)) {
+               ide_hwif_t *hwif = ide_find_port();
+
+               if (hwif) {
+                       ide_init_port_hw(hwif, &hw);
+                       hwif->pio_mask = ATA_PIO4;
+                       hwif->port_ops = &m8xx_port_ops;
+
+                       idx[0] = hwif->index;
+               }
+       }
 #ifdef IDE1_BASE_OFFSET
-       idx[1] = 1;
+       memset(&hw, 0, sizeof(hw));
+       if (!m8xx_ide_init_ports(&hw, 1)) {
+               ide_hwif_t *mate = ide_find_port();
+
+               if (mate) {
+                       ide_init_port_hw(mate, &hw);
+                       mate->pio_mask = ATA_PIO4;
+                       mate->port_ops = &m8xx_port_ops;
+
+                       idx[1] = mate->index;
+               }
+       }
 #endif
 #endif