pata_ali: Add Mitac 8317 and derivatives
[safe/jmp/linux-2.6] / drivers / ata / pata_platform.c
index cbb7866..ac03a90 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Generic platform device PATA driver
  *
- * Copyright (C) 2006  Paul Mundt
+ * Copyright (C) 2006 - 2007  Paul Mundt
  *
  * Based on pata_pcmcia:
  *
@@ -22,7 +22,7 @@
 #include <linux/pata_platform.h>
 
 #define DRV_NAME "pata_platform"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "1.2"
 
 static int pio_mask = 1;
 
@@ -30,13 +30,11 @@ static int pio_mask = 1;
  * Provide our own set_mode() as we don't want to change anything that has
  * already been configured..
  */
-static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unused)
+static int pata_platform_set_mode(struct ata_link *link, struct ata_device **unused)
 {
-       int i;
-
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
+       struct ata_device *dev;
 
+       ata_link_for_each_dev(dev, link) {
                if (ata_dev_enabled(dev)) {
                        /* We don't really care */
                        dev->pio_mode = dev->xfer_mode = XFER_PIO_0;
@@ -71,7 +69,6 @@ static struct scsi_host_template pata_platform_sht = {
 static struct ata_port_operations pata_platform_port_ops = {
        .set_mode               = pata_platform_set_mode,
 
-       .port_disable           = ata_port_disable,
        .tf_load                = ata_tf_load,
        .tf_read                = ata_tf_read,
        .check_status           = ata_check_status,
@@ -91,7 +88,6 @@ static struct ata_port_operations pata_platform_port_ops = {
 
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
-       .irq_ack                = ata_irq_ack,
 
        .port_start             = ata_dummy_ret0,
 };
@@ -124,27 +120,34 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
  *     Register a platform bus IDE interface. Such interfaces are PIO and we
  *     assume do not support IRQ sharing.
  *
- *     Platform devices are expected to contain 3 resources per port:
+ *     Platform devices are expected to contain at least 2 resources per port:
  *
  *             - I/O Base (IORESOURCE_IO or IORESOURCE_MEM)
  *             - CTL Base (IORESOURCE_IO or IORESOURCE_MEM)
+ *
+ *     and optionally:
+ *
  *             - IRQ      (IORESOURCE_IRQ)
  *
  *     If the base resources are both mem types, the ioremap() is handled
  *     here. For IORESOURCE_IO, it's assumed that there's no remapping
  *     necessary.
+ *
+ *     If no IRQ resource is present, PIO polling mode is used instead.
  */
 static int __devinit pata_platform_probe(struct platform_device *pdev)
 {
        struct resource *io_res, *ctl_res;
        struct ata_host *host;
        struct ata_port *ap;
+       struct pata_platform_info *pp_info;
        unsigned int mmio;
+       int irq;
 
        /*
         * Simple resource validation ..
         */
-       if (unlikely(pdev->num_resources != 3)) {
+       if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) {
                dev_err(&pdev->dev, "invalid number of resources\n");
                return -EINVAL;
        }
@@ -176,6 +179,13 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
                (ctl_res->flags == IORESOURCE_MEM));
 
        /*
+        * And the IRQ
+        */
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               irq = 0;        /* no irq */
+
+       /*
         * Now that that's out of the way, wire up the port..
         */
        host = ata_host_alloc(&pdev->dev, 1);
@@ -188,6 +198,14 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
        ap->flags |= ATA_FLAG_SLAVE_POSS;
 
        /*
+        * Use polling mode if there's no IRQ
+        */
+       if (!irq) {
+               ap->flags |= ATA_FLAG_PIO_POLLING;
+               ata_port_desc(ap, "no IRQ, using PIO polling");
+       }
+
+       /*
         * Handle the MMIO case
         */
        if (mmio) {
@@ -208,11 +226,17 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
 
        ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
 
-       pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data);
+       pp_info = pdev->dev.platform_data;
+       pata_platform_setup_port(&ap->ioaddr, pp_info);
+
+       ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport",
+                     (unsigned long long)io_res->start,
+                     (unsigned long long)ctl_res->start);
 
        /* activate */
-       return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt,
-                                0, &pata_platform_sht);
+       return ata_host_activate(host, irq, irq ? ata_interrupt : NULL,
+                                pp_info ? pp_info->irq_flags : 0,
+                                &pata_platform_sht);
 }
 
 /**