X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fide%2Fppc%2Fpmac.c;h=ba2d58727964f2bfa6a527b683535035da2da3b1;hb=c907310fb0a5dd69a7fe11c08368abb0d34a35cb;hp=88619b50d9ef9ada1a475b74cfe2de355130a239;hpb=eddeb0e2d863e3941d8768e70cb50c6120e61fa0;p=linux-2.6-omap-h63xx.git diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 88619b50d9e..ba2d5872796 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -59,7 +59,6 @@ typedef struct pmac_ide_hwif { int irq; int kind; int aapl_bus_id; - unsigned cable_80 : 1; unsigned mediabay : 1; unsigned broken_dma : 1; unsigned broken_dma_warn : 1; @@ -79,8 +78,6 @@ typedef struct pmac_ide_hwif { } pmac_ide_hwif_t; -static pmac_ide_hwif_t pmac_ide[MAX_HWIFS]; - enum { controller_ohare, /* OHare based */ controller_heathrow, /* Heathrow/Paddington */ @@ -411,7 +408,7 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time) */ #define IDE_WAKEUP_DELAY (1*HZ) -static int pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif); +static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *); static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq); static void pmac_ide_selectproc(ide_drive_t *drive); static void pmac_ide_kauai_selectproc(ide_drive_t *drive); @@ -419,7 +416,7 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive); #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ #define PMAC_IDE_REG(x) \ - ((void __iomem *)((drive)->hwif->io_ports[IDE_DATA_OFFSET] + (x))) + ((void __iomem *)((drive)->hwif->io_ports.data_addr + (x))) /* * Apply the timings of the proper unit (master/slave) to the shared @@ -920,12 +917,60 @@ pmac_ide_do_resume(ide_hwif_t *hwif) return 0; } +static u8 pmac_ide_cable_detect(ide_hwif_t *hwif) +{ + pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)ide_get_hwifdata(hwif); + struct device_node *np = pmif->node; + const char *cable = of_get_property(np, "cable-type", NULL); + + /* Get cable type from device-tree. */ + if (cable && !strncmp(cable, "80-", 3)) + return ATA_CBL_PATA80; + + /* + * G5's seem to have incorrect cable type in device-tree. + * Let's assume they have a 80 conductor cable, this seem + * to be always the case unless the user mucked around. + */ + if (of_device_is_compatible(np, "K2-UATA") || + of_device_is_compatible(np, "shasta-ata")) + return ATA_CBL_PATA80; + + return ATA_CBL_PATA40; +} + +static const struct ide_port_ops pmac_ide_ata6_port_ops = { + .set_pio_mode = pmac_ide_set_pio_mode, + .set_dma_mode = pmac_ide_set_dma_mode, + .selectproc = pmac_ide_kauai_selectproc, + .cable_detect = pmac_ide_cable_detect, +}; + +static const struct ide_port_ops pmac_ide_ata4_port_ops = { + .set_pio_mode = pmac_ide_set_pio_mode, + .set_dma_mode = pmac_ide_set_dma_mode, + .selectproc = pmac_ide_selectproc, + .cable_detect = pmac_ide_cable_detect, +}; + +static const struct ide_port_ops pmac_ide_port_ops = { + .set_pio_mode = pmac_ide_set_pio_mode, + .set_dma_mode = pmac_ide_set_dma_mode, + .selectproc = pmac_ide_selectproc, +}; + +static const struct ide_dma_ops pmac_dma_ops; + static const struct ide_port_info pmac_port_info = { + .init_dma = pmac_ide_init_dma, .chipset = ide_pmac, +#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC + .dma_ops = &pmac_dma_ops, +#endif + .port_ops = &pmac_ide_port_ops, .host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA | - IDE_HFLAG_PIO_NO_DOWNGRADE | IDE_HFLAG_POST_SET_MODE | - IDE_HFLAG_NO_DMA | /* no SFF-style DMA */ + IDE_HFLAG_MMIO | IDE_HFLAG_UNMASK_IRQS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, @@ -933,10 +978,7 @@ static const struct ide_port_info pmac_port_info = { /* * Setup, register & probe an IDE channel driven by this driver, this is - * called by one of the 2 probe functions (macio or PCI). Note that a channel - * that ends up beeing free of any device is not kept around by this driver - * (it is kept in 2.4). This introduce an interface numbering change on some - * rare machines unfortunately, but it's better this way. + * called by one of the 2 probe functions (macio or PCI). */ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) @@ -946,20 +988,23 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; struct ide_port_info d = pmac_port_info; - pmif->cable_80 = 0; pmif->broken_dma = pmif->broken_dma_warn = 0; if (of_device_is_compatible(np, "shasta-ata")) { pmif->kind = controller_sh_ata6; + d.port_ops = &pmac_ide_ata6_port_ops; d.udma_mask = ATA_UDMA6; } else if (of_device_is_compatible(np, "kauai-ata")) { pmif->kind = controller_un_ata6; + d.port_ops = &pmac_ide_ata6_port_ops; d.udma_mask = ATA_UDMA5; } else if (of_device_is_compatible(np, "K2-UATA")) { pmif->kind = controller_k2_ata6; + d.port_ops = &pmac_ide_ata6_port_ops; d.udma_mask = ATA_UDMA5; } else if (of_device_is_compatible(np, "keylargo-ata")) { if (strcmp(np->name, "ata-4") == 0) { pmif->kind = controller_kl_ata4; + d.port_ops = &pmac_ide_ata4_port_ops; d.udma_mask = ATA_UDMA4; } else pmif->kind = controller_kl_ata3; @@ -973,22 +1018,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) bidp = of_get_property(np, "AAPL,bus-id", NULL); pmif->aapl_bus_id = bidp ? *bidp : 0; - /* Get cable type from device-tree */ - if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6 - || pmif->kind == controller_k2_ata6 - || pmif->kind == controller_sh_ata6) { - const char* cable = of_get_property(np, "cable-type", NULL); - if (cable && !strncmp(cable, "80-", 3)) - pmif->cable_80 = 1; - } - /* G5's seem to have incorrect cable type in device-tree. Let's assume - * they have a 80 conductor cable, this seem to be always the case unless - * the user mucked around - */ - if (of_device_is_compatible(np, "K2-UATA") || - of_device_is_compatible(np, "shasta-ata")) - pmif->cable_80 = 1; - /* On Kauai-type controllers, we make sure the FCR is correct */ if (pmif->kauai_fcr) writel(KAUAI_FCR_UATA_MAGIC | @@ -1032,37 +1061,23 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw) default_hwif_mmiops(hwif); hwif->OUTBSYNC = pmac_outbsync; - /* Tell common code _not_ to mess with resources */ - hwif->mmio = 1; hwif->hwif_data = pmif; ide_init_port_hw(hwif, hw); - hwif->noprobe = pmif->mediabay; - hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; - hwif->set_pio_mode = pmac_ide_set_pio_mode; - if (pmif->kind == controller_un_ata6 - || pmif->kind == controller_k2_ata6 - || pmif->kind == controller_sh_ata6) - hwif->selectproc = pmac_ide_kauai_selectproc; - else - hwif->selectproc = pmac_ide_selectproc; - hwif->set_dma_mode = pmac_ide_set_dma_mode; printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, pmif->mediabay ? " (mediabay)" : "", hwif->irq); - -#ifdef CONFIG_PMAC_MEDIABAY - if (pmif->mediabay && check_media_bay_by_base(pmif->regbase, MB_CD) == 0) - hwif->noprobe = 0; -#endif /* CONFIG_PMAC_MEDIABAY */ -#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC - if (pmif->cable_80 == 0) - d.udma_mask &= ATA_UDMA2; - /* has a DBDMA controller channel */ - if (pmif->dma_regs == 0 || pmac_ide_setup_dma(pmif, hwif) < 0) + if (pmif->mediabay) { +#ifdef CONFIG_PMAC_MEDIABAY + if (check_media_bay_by_base(pmif->regbase, MB_CD)) { +#else + if (1) { #endif - d.udma_mask = d.mwdma_mask = 0; + hwif->drives[0].noprobe = 1; + hwif->drives[1].noprobe = 1; + } + } idx[0] = hwif->index; @@ -1076,8 +1091,9 @@ static void __devinit pmac_ide_init_ports(hw_regs_t *hw, unsigned long base) int i; for (i = 0; i < 8; ++i) - hw->io_ports[i] = base + i * 0x10; - hw->io_ports[8] = base + 0x160; + hw->io_ports_array[i] = base + i * 0x10; + + hw->io_ports.ctl_addr = base + 0x160; } /* @@ -1088,35 +1104,36 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) { void __iomem *base; unsigned long regbase; - int irq; ide_hwif_t *hwif; pmac_ide_hwif_t *pmif; - int i, rc; + int irq, rc; hw_regs_t hw; - i = 0; - while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 - || pmac_ide[i].node != NULL)) - ++i; - if (i >= MAX_HWIFS) { + pmif = kzalloc(sizeof(*pmif), GFP_KERNEL); + if (pmif == NULL) + return -ENOMEM; + + hwif = ide_find_port(); + if (hwif == NULL) { printk(KERN_ERR "ide-pmac: MacIO interface attach with no slot\n"); printk(KERN_ERR " %s\n", mdev->ofdev.node->full_name); - return -ENODEV; + rc = -ENODEV; + goto out_free_pmif; } - pmif = &pmac_ide[i]; - hwif = &ide_hwifs[i]; - if (macio_resource_count(mdev) == 0) { - printk(KERN_WARNING "ide%d: no address for %s\n", - i, mdev->ofdev.node->full_name); - return -ENXIO; + printk(KERN_WARNING "ide-pmac: no address for %s\n", + mdev->ofdev.node->full_name); + rc = -ENXIO; + goto out_free_pmif; } /* Request memory resource for IO ports */ if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) { - printk(KERN_ERR "ide%d: can't request mmio resource !\n", i); - return -EBUSY; + printk(KERN_ERR "ide-pmac: can't request MMIO resource for " + "%s!\n", mdev->ofdev.node->full_name); + rc = -EBUSY; + goto out_free_pmif; } /* XXX This is bogus. Should be fixed in the registry by checking @@ -1125,8 +1142,8 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) * where that happens though... */ if (macio_irq_count(mdev) == 0) { - printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n", - i, mdev->ofdev.node->full_name); + printk(KERN_WARNING "ide-pmac: no intrs for device %s, using " + "13\n", mdev->ofdev.node->full_name); irq = irq_create_mapping(NULL, 13); } else irq = macio_irq(mdev, 0); @@ -1144,7 +1161,9 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC if (macio_resource_count(mdev) >= 2) { if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) - printk(KERN_WARNING "ide%d: can't request DMA resource !\n", i); + printk(KERN_WARNING "ide-pmac: can't request DMA " + "resource for %s!\n", + mdev->ofdev.node->full_name); else pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); } else @@ -1166,11 +1185,15 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) iounmap(pmif->dma_regs); macio_release_resource(mdev, 1); } - memset(pmif, 0, sizeof(*pmif)); macio_release_resource(mdev, 0); + kfree(pmif); } return rc; + +out_free_pmif: + kfree(pmif); + return rc; } static int @@ -1215,7 +1238,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) pmac_ide_hwif_t *pmif; void __iomem *base; unsigned long rbase, rlen; - int i, rc; + int rc; hw_regs_t hw; np = pci_device_to_OF_node(pdev); @@ -1223,30 +1246,32 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) printk(KERN_ERR "ide-pmac: cannot find MacIO node for Kauai ATA interface\n"); return -ENODEV; } - i = 0; - while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0 - || pmac_ide[i].node != NULL)) - ++i; - if (i >= MAX_HWIFS) { + + pmif = kzalloc(sizeof(*pmif), GFP_KERNEL); + if (pmif == NULL) + return -ENOMEM; + + hwif = ide_find_port(); + if (hwif == NULL) { printk(KERN_ERR "ide-pmac: PCI interface attach with no slot\n"); printk(KERN_ERR " %s\n", np->full_name); - return -ENODEV; + rc = -ENODEV; + goto out_free_pmif; } - pmif = &pmac_ide[i]; - hwif = &ide_hwifs[i]; - if (pci_enable_device(pdev)) { - printk(KERN_WARNING "ide%i: Can't enable PCI device for %s\n", - i, np->full_name); - return -ENXIO; + printk(KERN_WARNING "ide-pmac: Can't enable PCI device for " + "%s\n", np->full_name); + rc = -ENXIO; + goto out_free_pmif; } pci_set_master(pdev); if (pci_request_regions(pdev, "Kauai ATA")) { - printk(KERN_ERR "ide%d: Cannot obtain PCI resources for %s\n", - i, np->full_name); - return -ENXIO; + printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources for " + "%s\n", np->full_name); + rc = -ENXIO; + goto out_free_pmif; } hwif->dev = &pdev->dev; @@ -1276,11 +1301,15 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) /* The inteface is released to the common IDE layer */ pci_set_drvdata(pdev, NULL); iounmap(base); - memset(pmif, 0, sizeof(*pmif)); pci_release_regions(pdev); + kfree(pmif); } return rc; + +out_free_pmif: + kfree(pmif); + return rc; } static int @@ -1652,18 +1681,31 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive) printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status); } +static const struct ide_dma_ops pmac_dma_ops = { + .dma_host_set = pmac_ide_dma_host_set, + .dma_setup = pmac_ide_dma_setup, + .dma_exec_cmd = pmac_ide_dma_exec_cmd, + .dma_start = pmac_ide_dma_start, + .dma_end = pmac_ide_dma_end, + .dma_test_irq = pmac_ide_dma_test_irq, + .dma_timeout = ide_dma_timeout, + .dma_lost_irq = pmac_ide_dma_lost_irq, +}; + /* * Allocate the data structures needed for using DMA with an interface * and fill the proper list of functions pointers */ -static int __devinit pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) +static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif, + const struct ide_port_info *d) { + pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data; struct pci_dev *dev = to_pci_dev(hwif->dev); /* We won't need pci_dev if we switch to generic consistent * DMA routines ... */ - if (dev == NULL) + if (dev == NULL || pmif->dma_regs == 0) return -ENODEV; /* * Allocate space for the DBDMA commands. @@ -1682,18 +1724,14 @@ static int __devinit pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->sg_max_nents = MAX_DCMDS; - hwif->dma_host_set = &pmac_ide_dma_host_set; - hwif->dma_setup = &pmac_ide_dma_setup; - hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd; - hwif->dma_start = &pmac_ide_dma_start; - hwif->ide_dma_end = &pmac_ide_dma_end; - hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; - hwif->dma_timeout = &ide_dma_timeout; - hwif->dma_lost_irq = &pmac_ide_dma_lost_irq; - return 0; } - +#else +static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif, + const struct ide_port_info *d) +{ + return -EOPNOTSUPP; +} #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ module_init(pmac_ide_probe);