summaryrefslogtreecommitdiffstats
path: root/drivers/ide/legacy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/legacy')
-rw-r--r--drivers/ide/legacy/Makefile2
-rw-r--r--drivers/ide/legacy/ali14xx.c10
-rw-r--r--drivers/ide/legacy/dtc2278.c6
-rw-r--r--drivers/ide/legacy/ht6560b.c11
-rw-r--r--drivers/ide/legacy/ide_platform.c182
-rw-r--r--drivers/ide/legacy/qd65xx.c60
-rw-r--r--drivers/ide/legacy/umc8672.c7
7 files changed, 231 insertions, 47 deletions
diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile
index c7971061767e..409822349f10 100644
--- a/drivers/ide/legacy/Makefile
+++ b/drivers/ide/legacy/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o
+obj-$(CONFIG_BLK_DEV_PLATFORM) += ide_platform.o
+
# Last of all
obj-$(CONFIG_BLK_DEV_HD) += hd.o
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index 9b9c4761cb7d..2f0ef9b44033 100644
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -68,8 +68,6 @@ static RegInitializer initData[] __initdata = {
{0x35, 0x03}, {0x00, 0x00}
};
-#define ALI_MAX_PIO 4
-
/* timing parameter registers for each drive */
static struct { u8 reg1, reg2, reg3, reg4; } regTab[4] = {
{0x03, 0x26, 0x04, 0x27}, /* drive 0 */
@@ -109,7 +107,7 @@ static void outReg (u8 data, u8 reg)
* This function computes timing parameters
* and sets controller registers accordingly.
*/
-static void ali14xx_tune_drive (ide_drive_t *drive, u8 pio)
+static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
int driveNum;
int time1, time2;
@@ -117,8 +115,6 @@ static void ali14xx_tune_drive (ide_drive_t *drive, u8 pio)
unsigned long flags;
int bus_speed = system_bus_clock();
- pio = ide_get_best_pio_mode(drive, pio, ALI_MAX_PIO);
-
/* calculate timing, according to PIO mode */
time1 = ide_pio_cycle_time(drive, pio);
time2 = ide_pio_timings[pio].active_time;
@@ -212,12 +208,12 @@ static int __init ali14xx_probe(void)
hwif->chipset = ide_ali14xx;
hwif->pio_mask = ATA_PIO4;
- hwif->tuneproc = &ali14xx_tune_drive;
+ hwif->set_pio_mode = &ali14xx_set_pio_mode;
hwif->mate = mate;
mate->chipset = ide_ali14xx;
mate->pio_mask = ATA_PIO4;
- mate->tuneproc = &ali14xx_tune_drive;
+ mate->set_pio_mode = &ali14xx_set_pio_mode;
mate->mate = hwif;
mate->channel = 1;
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
index 6c01d951d074..f16521254867 100644
--- a/drivers/ide/legacy/dtc2278.c
+++ b/drivers/ide/legacy/dtc2278.c
@@ -67,12 +67,10 @@ static void sub22 (char b, char c)
}
}
-static void tune_dtc2278 (ide_drive_t *drive, u8 pio)
+static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
unsigned long flags;
- pio = ide_get_best_pio_mode(drive, pio, 4);
-
if (pio >= 3) {
spin_lock_irqsave(&ide_lock, flags);
/*
@@ -124,7 +122,7 @@ static int __init dtc2278_probe(void)
hwif->serialized = 1;
hwif->chipset = ide_dtc2278;
hwif->pio_mask = ATA_PIO4;
- hwif->tuneproc = &tune_dtc2278;
+ hwif->set_pio_mode = &dtc2278_set_pio_mode;
hwif->drives[0].no_unmask = 1;
hwif->drives[1].no_unmask = 1;
hwif->mate = mate;
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index bfaa2025173b..2e5a9cc5c0f7 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -199,7 +199,7 @@ static int __init try_to_init_ht6560b(void)
return 1;
}
-static u8 ht_pio2timings(ide_drive_t *drive, u8 pio)
+static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
{
int active_time, recovery_time;
int active_cycles, recovery_cycles;
@@ -208,7 +208,6 @@ static u8 ht_pio2timings(ide_drive_t *drive, u8 pio)
if (pio) {
unsigned int cycle_time;
- pio = ide_get_best_pio_mode(drive, pio, 5);
cycle_time = ide_pio_cycle_time(drive, pio);
/*
@@ -277,7 +276,7 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
#endif
}
-static void tune_ht6560b (ide_drive_t *drive, u8 pio)
+static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
unsigned long flags;
u8 timing;
@@ -333,15 +332,17 @@ int __init ht6560b_init(void)
hwif->chipset = ide_ht6560b;
hwif->selectproc = &ht6560b_selectproc;
+ hwif->host_flags = IDE_HFLAG_ABUSE_PREFETCH;
hwif->pio_mask = ATA_PIO5;
- hwif->tuneproc = &tune_ht6560b;
+ hwif->set_pio_mode = &ht6560b_set_pio_mode;
hwif->serialized = 1; /* is this needed? */
hwif->mate = mate;
mate->chipset = ide_ht6560b;
mate->selectproc = &ht6560b_selectproc;
+ mate->host_flags = IDE_HFLAG_ABUSE_PREFETCH;
mate->pio_mask = ATA_PIO5;
- mate->tuneproc = &tune_ht6560b;
+ mate->set_pio_mode = &ht6560b_set_pio_mode;
mate->serialized = 1; /* is this needed? */
mate->mate = hwif;
mate->channel = 1;
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
new file mode 100644
index 000000000000..ccfb9893a467
--- /dev/null
+++ b/drivers/ide/legacy/ide_platform.c
@@ -0,0 +1,182 @@
+/*
+ * Platform IDE driver
+ *
+ * Copyright (C) 2007 MontaVista Software
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/pata_platform.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+static struct {
+ void __iomem *plat_ide_mapbase;
+ void __iomem *plat_ide_alt_mapbase;
+ ide_hwif_t *hwif;
+ int index;
+} hwif_prop;
+
+static ide_hwif_t *__devinit plat_ide_locate_hwif(void __iomem *base,
+ void __iomem *ctrl, struct pata_platform_info *pdata, int irq,
+ int mmio)
+{
+ unsigned long port = (unsigned long)base;
+ ide_hwif_t *hwif;
+ int index, i;
+
+ for (index = 0; index < MAX_HWIFS; ++index) {
+ hwif = ide_hwifs + index;
+ if (hwif->io_ports[IDE_DATA_OFFSET] == port)
+ goto found;
+ }
+
+ for (index = 0; index < MAX_HWIFS; ++index) {
+ hwif = ide_hwifs + index;
+ if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
+ goto found;
+ }
+
+ return NULL;
+
+found:
+
+ hwif->hw.io_ports[IDE_DATA_OFFSET] = port;
+
+ port += (1 << pdata->ioport_shift);
+ for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
+ i++, port += (1 << pdata->ioport_shift))
+ hwif->hw.io_ports[i] = port;
+
+ hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+
+ memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
+ hwif->hw.irq = hwif->irq = irq;
+
+ hwif->hw.dma = NO_DMA;
+ hwif->hw.chipset = ide_generic;
+
+ if (mmio) {
+ hwif->mmio = 1;
+ default_hwif_mmiops(hwif);
+ }
+
+ hwif_prop.hwif = hwif;
+ hwif_prop.index = index;
+
+ return hwif;
+}
+
+static int __devinit plat_ide_probe(struct platform_device *pdev)
+{
+ struct resource *res_base, *res_alt, *res_irq;
+ ide_hwif_t *hwif;
+ struct pata_platform_info *pdata;
+ int ret = 0;
+ int mmio = 0;
+
+ pdata = pdev->dev.platform_data;
+
+ /* get a pointer to the register memory */
+ res_base = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ res_alt = platform_get_resource(pdev, IORESOURCE_IO, 1);
+
+ if (!res_base || !res_alt) {
+ res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res_alt = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res_base || !res_alt) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ mmio = 1;
+ }
+
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res_irq) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (mmio) {
+ hwif_prop.plat_ide_mapbase = devm_ioremap(&pdev->dev,
+ res_base->start, res_base->end - res_base->start + 1);
+ hwif_prop.plat_ide_alt_mapbase = devm_ioremap(&pdev->dev,
+ res_alt->start, res_alt->end - res_alt->start + 1);
+ } else {
+ hwif_prop.plat_ide_mapbase = devm_ioport_map(&pdev->dev,
+ res_base->start, res_base->end - res_base->start + 1);
+ hwif_prop.plat_ide_alt_mapbase = devm_ioport_map(&pdev->dev,
+ res_alt->start, res_alt->end - res_alt->start + 1);
+ }
+
+ hwif = plat_ide_locate_hwif(hwif_prop.plat_ide_mapbase,
+ hwif_prop.plat_ide_alt_mapbase, pdata, res_irq->start, mmio);
+
+ if (!hwif) {
+ ret = -ENODEV;
+ goto out;
+ }
+ hwif->gendev.parent = &pdev->dev;
+ hwif->noprobe = 0;
+
+ probe_hwif_init(hwif);
+
+ platform_set_drvdata(pdev, hwif);
+ ide_proc_register_port(hwif);
+
+ return 0;
+
+out:
+ return ret;
+}
+
+static int __devexit plat_ide_remove(struct platform_device *pdev)
+{
+ ide_hwif_t *hwif = pdev->dev.driver_data;
+
+ if (hwif != hwif_prop.hwif) {
+ dev_printk(KERN_DEBUG, &pdev->dev, "%s: hwif value error",
+ pdev->name);
+ } else {
+ ide_unregister(hwif_prop.index);
+ hwif_prop.index = 0;
+ hwif_prop.hwif = NULL;
+ }
+
+ return 0;
+}
+
+static struct platform_driver platform_ide_driver = {
+ .driver = {
+ .name = "pata_platform",
+ },
+ .probe = plat_ide_probe,
+ .remove = __devexit_p(plat_ide_remove),
+};
+
+static int __init platform_ide_init(void)
+{
+ return platform_driver_register(&platform_ide_driver);
+}
+
+static void __exit platform_ide_exit(void)
+{
+ platform_driver_unregister(&platform_ide_driver);
+}
+
+MODULE_DESCRIPTION("Platform IDE driver");
+MODULE_LICENSE("GPL");
+
+module_init(platform_ide_init);
+module_exit(platform_ide_exit);
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index 8b87a424094a..0c81d2d0b941 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -224,15 +224,14 @@ static void qd_set_timing (ide_drive_t *drive, u8 timing)
printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
}
-/*
- * qd6500_tune_drive
- */
-
-static void qd6500_tune_drive (ide_drive_t *drive, u8 pio)
+static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
int active_time = 175;
int recovery_time = 415; /* worst case values from the dos driver */
+ /*
+ * FIXME: use "pio" value
+ */
if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)
&& drive->id->tPIO && (drive->id->field_valid & 0x02)
&& drive->id->eide_pio >= 240) {
@@ -246,11 +245,7 @@ static void qd6500_tune_drive (ide_drive_t *drive, u8 pio)
qd_set_timing(drive, qd6500_compute_timing(HWIF(drive), active_time, recovery_time));
}
-/*
- * qd6580_tune_drive
- */
-
-static void qd6580_tune_drive (ide_drive_t *drive, u8 pio)
+static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
int base = HWIF(drive)->select_data;
unsigned int cycle_time;
@@ -258,7 +253,6 @@ static void qd6580_tune_drive (ide_drive_t *drive, u8 pio)
int recovery_time = 415; /* worst case values from the dos driver */
if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) {
- pio = ide_get_best_pio_mode(drive, pio, 4);
cycle_time = ide_pio_cycle_time(drive, pio);
switch (pio) {
@@ -335,8 +329,7 @@ static int __init qd_testreg(int port)
*/
static void __init qd_setup(ide_hwif_t *hwif, int base, int config,
- unsigned int data0, unsigned int data1,
- void (*tuneproc) (ide_drive_t *, u8 pio))
+ unsigned int data0, unsigned int data1)
{
hwif->chipset = ide_qd65xx;
hwif->channel = hwif->index;
@@ -347,8 +340,6 @@ static void __init qd_setup(ide_hwif_t *hwif, int base, int config,
hwif->drives[0].io_32bit =
hwif->drives[1].io_32bit = 1;
hwif->pio_mask = ATA_PIO4;
- hwif->tuneproc = tuneproc;
- probe_hwif_init(hwif);
}
/*
@@ -361,7 +352,7 @@ static void __exit qd_unsetup(ide_hwif_t *hwif)
{
u8 config = hwif->config_data;
int base = hwif->select_data;
- void *tuneproc = (void *) hwif->tuneproc;
+ void *set_pio_mode = (void *)hwif->set_pio_mode;
if (hwif->chipset != ide_qd65xx)
return;
@@ -369,12 +360,12 @@ static void __exit qd_unsetup(ide_hwif_t *hwif)
printk(KERN_NOTICE "%s: back to defaults\n", hwif->name);
hwif->selectproc = NULL;
- hwif->tuneproc = NULL;
+ hwif->set_pio_mode = NULL;
- if (tuneproc == (void *) qd6500_tune_drive) {
+ if (set_pio_mode == (void *)qd6500_set_pio_mode) {
// will do it for both
qd_write_reg(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
- } else if (tuneproc == (void *) qd6580_tune_drive) {
+ } else if (set_pio_mode == (void *)qd6580_set_pio_mode) {
if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
qd_write_reg(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
qd_write_reg(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
@@ -424,8 +415,11 @@ static int __init qd_probe(int base)
return 1;
}
- qd_setup(hwif, base, config, QD6500_DEF_DATA, QD6500_DEF_DATA,
- &qd6500_tune_drive);
+ qd_setup(hwif, base, config, QD6500_DEF_DATA, QD6500_DEF_DATA);
+
+ hwif->set_pio_mode = &qd6500_set_pio_mode;
+
+ probe_hwif_init(hwif);
ide_proc_register_port(hwif);
@@ -455,8 +449,12 @@ static int __init qd_probe(int base)
printk(KERN_INFO "%s: qd6580: single IDE board\n",
hwif->name);
qd_setup(hwif, base, config | (control << 8),
- QD6580_DEF_DATA, QD6580_DEF_DATA2,
- &qd6580_tune_drive);
+ QD6580_DEF_DATA, QD6580_DEF_DATA2);
+
+ hwif->set_pio_mode = &qd6580_set_pio_mode;
+
+ probe_hwif_init(hwif);
+
qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
ide_proc_register_port(hwif);
@@ -472,11 +470,19 @@ static int __init qd_probe(int base)
hwif->name, mate->name);
qd_setup(hwif, base, config | (control << 8),
- QD6580_DEF_DATA, QD6580_DEF_DATA,
- &qd6580_tune_drive);
+ QD6580_DEF_DATA, QD6580_DEF_DATA);
+
+ hwif->set_pio_mode = &qd6580_set_pio_mode;
+
+ probe_hwif_init(hwif);
+
qd_setup(mate, base, config | (control << 8),
- QD6580_DEF_DATA2, QD6580_DEF_DATA2,
- &qd6580_tune_drive);
+ QD6580_DEF_DATA2, QD6580_DEF_DATA2);
+
+ mate->set_pio_mode = &qd6580_set_pio_mode;
+
+ probe_hwif_init(mate);
+
qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
ide_proc_register_port(hwif);
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
index d2862e638bc5..1151c92dd531 100644
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -105,12 +105,11 @@ static void umc_set_speeds (u8 speeds[])
speeds[0], speeds[1], speeds[2], speeds[3]);
}
-static void tune_umc (ide_drive_t *drive, u8 pio)
+static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
unsigned long flags;
ide_hwgroup_t *hwgroup = ide_hwifs[HWIF(drive)->index^1].hwgroup;
- pio = ide_get_best_pio_mode(drive, pio, 4);
printk("%s: setting umc8672 to PIO mode%d (speed %d)\n",
drive->name, pio, pio_to_umc[pio]);
spin_lock_irqsave(&ide_lock, flags);
@@ -150,12 +149,12 @@ static int __init umc8672_probe(void)
hwif->chipset = ide_umc8672;
hwif->pio_mask = ATA_PIO4;
- hwif->tuneproc = &tune_umc;
+ hwif->set_pio_mode = &umc_set_pio_mode;
hwif->mate = mate;
mate->chipset = ide_umc8672;
mate->pio_mask = ATA_PIO4;
- mate->tuneproc = &tune_umc;
+ mate->set_pio_mode = &umc_set_pio_mode;
mate->mate = hwif;
mate->channel = 1;