Merge branches 'release', 'asus', 'sony-laptop' and 'thinkpad' into release
[pandora-kernel.git] / drivers / ide / pci / pdc202xx_new.c
index d1087cc..1c8cb77 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
 #include <linux/hdreg.h>
-#include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ide.h>
 
 #include <asm/io.h>
-#include <asm/irq.h>
 
 #ifdef CONFIG_PPC_PMAC
 #include <asm/prom.h>
@@ -146,9 +140,10 @@ static struct udma_timing {
        { 0x1a, 0x01, 0xcb },   /* UDMA mode 6 */
 };
 
-static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
+static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = HWIF(drive);
+       struct pci_dev *dev     = to_pci_dev(hwif->dev);
        u8 adj                  = (drive->dn & 1) ? 0x08 : 0x00;
 
        /*
@@ -159,48 +154,21 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
         * As we set up the PLL to output 133 MHz for UltraDMA/133 capable
         * chips, we must override the default register settings...
         */
-       if (max_dma_rate(hwif->pci_dev) == 4) {
+       if (max_dma_rate(dev) == 4) {
                u8 mode = speed & 0x07;
 
-               switch (speed) {
-                       case XFER_UDMA_6:
-                       case XFER_UDMA_5:
-                       case XFER_UDMA_4:
-                       case XFER_UDMA_3:
-                       case XFER_UDMA_2:
-                       case XFER_UDMA_1:
-                       case XFER_UDMA_0:
-                               set_indexed_reg(hwif, 0x10 + adj,
-                                               udma_timings[mode].reg10);
-                               set_indexed_reg(hwif, 0x11 + adj,
-                                               udma_timings[mode].reg11);
-                               set_indexed_reg(hwif, 0x12 + adj,
-                                               udma_timings[mode].reg12);
-                               break;
-
-                       case XFER_MW_DMA_2:
-                       case XFER_MW_DMA_1:
-                       case XFER_MW_DMA_0:
-                               set_indexed_reg(hwif, 0x0e + adj,
-                                               mwdma_timings[mode].reg0e);
-                               set_indexed_reg(hwif, 0x0f + adj,
-                                               mwdma_timings[mode].reg0f);
-                               break;
-                       case XFER_PIO_4:
-                       case XFER_PIO_3:
-                       case XFER_PIO_2:
-                       case XFER_PIO_1:
-                       case XFER_PIO_0:
-                               set_indexed_reg(hwif, 0x0c + adj,
-                                               pio_timings[mode].reg0c);
-                               set_indexed_reg(hwif, 0x0d + adj,
-                                               pio_timings[mode].reg0d);
-                               set_indexed_reg(hwif, 0x13 + adj,
-                                               pio_timings[mode].reg13);
-                               break;
-                       default:
-                               printk(KERN_ERR "pdc202xx_new: "
-                                      "Unknown speed %d ignored\n", speed);
+               if (speed >= XFER_UDMA_0) {
+                       set_indexed_reg(hwif, 0x10 + adj,
+                                       udma_timings[mode].reg10);
+                       set_indexed_reg(hwif, 0x11 + adj,
+                                       udma_timings[mode].reg11);
+                       set_indexed_reg(hwif, 0x12 + adj,
+                                       udma_timings[mode].reg12);
+               } else {
+                       set_indexed_reg(hwif, 0x0e + adj,
+                                       mwdma_timings[mode].reg0e);
+                       set_indexed_reg(hwif, 0x0f + adj,
+                                       mwdma_timings[mode].reg0f);
                }
        } else if (speed == XFER_UDMA_2) {
                /* Set tHOLD bit to 0 if using UDMA mode 2 */
@@ -212,10 +180,18 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
 
 static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       pdcnew_set_mode(drive, XFER_PIO_0 + pio);
+       ide_hwif_t *hwif = drive->hwif;
+       struct pci_dev *dev = to_pci_dev(hwif->dev);
+       u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
+
+       if (max_dma_rate(dev) == 4) {
+               set_indexed_reg(hwif, 0x0c + adj, pio_timings[pio].reg0c);
+               set_indexed_reg(hwif, 0x0d + adj, pio_timings[pio].reg0d);
+               set_indexed_reg(hwif, 0x13 + adj, pio_timings[pio].reg13);
+       }
 }
 
-static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
+static u8 __devinit pdcnew_cable_detect(ide_hwif_t *hwif)
 {
        if (get_indexed_reg(hwif, 0x0b) & 0x04)
                return ATA_CBL_PATA40;
@@ -223,14 +199,17 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
                return ATA_CBL_PATA80;
 }
 
-static int pdcnew_quirkproc(ide_drive_t *drive)
+static void pdcnew_quirkproc(ide_drive_t *drive)
 {
        const char **list, *model = drive->id->model;
 
        for (list = pdc_quirk_drives; *list != NULL; list++)
-               if (strstr(model, *list) != NULL)
-                       return 2;
-       return 0;
+               if (strstr(model, *list) != NULL) {
+                       drive->quirk_list = 2;
+                       return;
+               }
+
+       drive->quirk_list = 0;
 }
 
 static void pdcnew_reset(ide_drive_t *drive)
@@ -332,16 +311,12 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base)
 static void __devinit apple_kiwi_init(struct pci_dev *pdev)
 {
        struct device_node *np = pci_device_to_OF_node(pdev);
-       unsigned int class_rev = 0;
        u8 conf;
 
        if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
                return;
 
-       pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
-       class_rev &= 0xff;
-
-       if (class_rev >= 0x03) {
+       if (pdev->revision >= 0x03) {
                /* Setup chip magic config stuff (from darwin) */
                pci_read_config_byte (pdev, 0x40, &conf);
                pci_write_config_byte(pdev, 0x40, (conf | 0x01));
@@ -469,44 +444,79 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha
 
 static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
 {
-       hwif->autodma = 0;
-
        hwif->set_pio_mode = &pdcnew_set_pio_mode;
-       hwif->set_dma_mode = &pdcnew_set_mode;
+       hwif->set_dma_mode = &pdcnew_set_dma_mode;
 
        hwif->quirkproc = &pdcnew_quirkproc;
        hwif->resetproc = &pdcnew_reset;
 
-       hwif->err_stops_fifo = 1;
+       hwif->cable_detect = pdcnew_cable_detect;
+}
 
-       hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
+{
+       struct pci_dev *dev2;
 
-       if (hwif->dma_base == 0)
-               return;
+       dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 1,
+                                               PCI_FUNC(dev->devfn)));
 
-       hwif->atapi_dma  = 1;
+       if (dev2 &&
+           dev2->vendor == dev->vendor &&
+           dev2->device == dev->device) {
 
-       hwif->ultra_mask = hwif->cds->udma_mask;
-       hwif->mwdma_mask = 0x07;
+               if (dev2->irq != dev->irq) {
+                       dev2->irq = dev->irq;
+                       printk(KERN_INFO "PDC20270: PCI config space "
+                                        "interrupt fixed\n");
+               }
 
-       if (hwif->cbl != ATA_CBL_PATA40_SHORT)
-               hwif->cbl = pdcnew_cable_detect(hwif);
+               return dev2;
+       }
 
-       if (!noautodma)
-               hwif->autodma = 1;
-       hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
+       return NULL;
 }
 
-static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       return ide_setup_pci_device(dev, d);
-}
+#define DECLARE_PDCNEW_DEV(name_str, udma) \
+       { \
+               .name           = name_str, \
+               .init_chipset   = init_chipset_pdcnew, \
+               .init_hwif      = init_hwif_pdc202new, \
+               .host_flags     = IDE_HFLAG_POST_SET_MODE | \
+                                 IDE_HFLAG_ERROR_STOPS_FIFO | \
+                                 IDE_HFLAG_OFF_BOARD, \
+               .pio_mask       = ATA_PIO4, \
+               .mwdma_mask     = ATA_MWDMA2, \
+               .udma_mask      = udma, \
+       }
 
-static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
+static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {
+       /* 0 */ DECLARE_PDCNEW_DEV("PDC20268", ATA_UDMA5),
+       /* 1 */ DECLARE_PDCNEW_DEV("PDC20269", ATA_UDMA6),
+       /* 2 */ DECLARE_PDCNEW_DEV("PDC20270", ATA_UDMA5),
+       /* 3 */ DECLARE_PDCNEW_DEV("PDC20271", ATA_UDMA6),
+       /* 4 */ DECLARE_PDCNEW_DEV("PDC20275", ATA_UDMA6),
+       /* 5 */ DECLARE_PDCNEW_DEV("PDC20276", ATA_UDMA6),
+       /* 6 */ DECLARE_PDCNEW_DEV("PDC20277", ATA_UDMA6),
+};
+
+/**
+ *     pdc202new_init_one      -       called when a pdc202xx is found
+ *     @dev: the pdc202new device
+ *     @id: the matching pci id
+ *
+ *     Called when the PCI registration layer (or the IDE initialization)
+ *     finds a device matching our IDE device tables.
+ */
+static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
+       const struct ide_port_info *d;
        struct pci_dev *bridge = dev->bus->self;
+       u8 idx = id->driver_data;
+
+       d = &pdcnew_chipsets[idx];
 
-       if (bridge != NULL &&
+       if (idx == 2 && bridge &&
            bridge->vendor == PCI_VENDOR_ID_DEC &&
            bridge->device == PCI_DEVICE_ID_DEC_21150) {
                struct pci_dev *dev2;
@@ -514,133 +524,26 @@ static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *
                if (PCI_SLOT(dev->devfn) & 2)
                        return -ENODEV;
 
-               dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2,
-                                                       PCI_FUNC(dev->devfn)));
-               if (dev2 != NULL &&
-                   dev2->vendor == dev->vendor &&
-                   dev2->device == dev->device) {
-                       int ret;
+               dev2 = pdc20270_get_dev2(dev);
 
-                       if (dev2->irq != dev->irq) {
-                               dev2->irq = dev->irq;
-
-                               printk(KERN_WARNING "%s: PCI config space "
-                                      "interrupt fixed.\n", d->name);
-                       }
-
-                       ret = ide_setup_pci_devices(dev, dev2, d);
+               if (dev2) {
+                       int ret = ide_setup_pci_devices(dev, dev2, d);
                        if (ret < 0)
                                pci_dev_put(dev2);
                        return ret;
                }
        }
-       return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
-{
-       struct pci_dev *bridge = dev->bus->self;
 
-       if (bridge != NULL &&
+       if (idx == 5 && bridge &&
            bridge->vendor == PCI_VENDOR_ID_INTEL &&
-          (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
-           bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
-
-               printk(KERN_INFO "%s: attached to I2O RAID controller, "
-                                "skipping.\n", d->name);
+           (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
+            bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
+               printk(KERN_INFO "PDC20276: attached to I2O RAID controller, "
+                                "skipping\n");
                return -ENODEV;
        }
-       return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
-       {       /* 0 */
-               .name           = "PDC20268",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x3f, /* udma0-5 */
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 1 */
-               .name           = "PDC20269",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 2 */
-               .name           = "PDC20270",
-               .init_setup     = init_setup_pdc20270,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x3f, /* udma0-5 */
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 3 */
-               .name           = "PDC20271",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 4 */
-               .name           = "PDC20275",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 5 */
-               .name           = "PDC20276",
-               .init_setup     = init_setup_pdc20276,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       },{     /* 6 */
-               .name           = "PDC20277",
-               .init_setup     = init_setup_pdcnew,
-               .init_chipset   = init_chipset_pdcnew,
-               .init_hwif      = init_hwif_pdc202new,
-               .autodma        = AUTODMA,
-               .bootable       = OFF_BOARD,
-               .pio_mask       = ATA_PIO4,
-               .udma_mask      = 0x7f, /* udma0-6*/
-               .host_flags     = IDE_HFLAG_POST_SET_MODE,
-       }
-};
 
-/**
- *     pdc202new_init_one      -       called when a pdc202xx is found
- *     @dev: the pdc202new device
- *     @id: the matching pci id
- *
- *     Called when the PCI registration layer (or the IDE initialization)
- *     finds a device matching our IDE device tables.
- */
-static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data];
-
-       return d->init_setup(dev, d);
+       return ide_setup_pci_device(dev, d);
 }
 
 static const struct pci_device_id pdc202new_pci_tbl[] = {