V4L/DVB: s2255drv: return if vdev not found
[safe/jmp/linux-2.6] / drivers / ata / sata_mv.c
index b625b36..71cc0d4 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
 #include <linux/bitops.h>
+#include <linux/gfp.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -539,6 +540,7 @@ struct mv_port_signal {
 
 struct mv_host_priv {
        u32                     hp_flags;
+       unsigned int            board_idx;
        u32                     main_irq_mask;
        struct mv_port_signal   signal[8];
        const struct mv_hw_ops  *ops;
@@ -2780,7 +2782,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause)
        struct mv_port_priv *pp;
        int edma_was_enabled;
 
-       if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
+       if (ap->flags & ATA_FLAG_DISABLED) {
                mv_unexpected_intr(ap, 0);
                return;
        }
@@ -3859,7 +3861,6 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 /**
  *      mv_init_host - Perform some early initialization of the host.
  *     @host: ATA host to initialize
- *      @board_idx: controller index
  *
  *      If possible, do an early global reset of the host.  Then do
  *      our port init and clear/unmask all/relevant host interrupts.
@@ -3867,13 +3868,13 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_init_host(struct ata_host *host, unsigned int board_idx)
+static int mv_init_host(struct ata_host *host)
 {
        int rc = 0, n_hc, port, hc;
        struct mv_host_priv *hpriv = host->private_data;
        void __iomem *mmio = hpriv->base;
 
-       rc = mv_chip_id(host, board_idx);
+       rc = mv_chip_id(host, hpriv->board_idx);
        if (rc)
                goto done;
 
@@ -3910,14 +3911,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
                void __iomem *port_mmio = mv_port_base(mmio, port);
 
                mv_port_init(&ap->ioaddr, port_mmio);
-
-#ifdef CONFIG_PCI
-               if (!IS_SOC(hpriv)) {
-                       unsigned int offset = port_mmio - mmio;
-                       ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
-                       ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
-               }
-#endif
        }
 
        for (hc = 0; hc < n_hc; hc++) {
@@ -4040,6 +4033,7 @@ static int mv_platform_probe(struct platform_device *pdev)
                return -ENOMEM;
        host->private_data = hpriv;
        hpriv->n_ports = n_ports;
+       hpriv->board_idx = chip_soc;
 
        host->iomap = NULL;
        hpriv->base = devm_ioremap(&pdev->dev, res->start,
@@ -4065,7 +4059,7 @@ static int mv_platform_probe(struct platform_device *pdev)
                goto err;
 
        /* initialize adapter */
-       rc = mv_init_host(host, chip_soc);
+       rc = mv_init_host(host);
        if (rc)
                goto err;
 
@@ -4112,9 +4106,52 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       if (host)
+               return ata_host_suspend(host, state);
+       else
+               return 0;
+}
+
+static int mv_platform_resume(struct platform_device *pdev)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       int ret;
+
+       if (host) {
+               struct mv_host_priv *hpriv = host->private_data;
+               const struct mv_sata_platform_data *mv_platform_data = \
+                       pdev->dev.platform_data;
+               /*
+                * (Re-)program MBUS remapping windows if we are asked to.
+                */
+               if (mv_platform_data->dram != NULL)
+                       mv_conf_mbus_windows(hpriv, mv_platform_data->dram);
+
+               /* initialize adapter */
+               ret = mv_init_host(host);
+               if (ret) {
+                       printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+                       return ret;
+               }
+               ata_host_resume(host);
+       }
+
+       return 0;
+}
+#else
+#define mv_platform_suspend NULL
+#define mv_platform_resume NULL
+#endif
+
 static struct platform_driver mv_platform_driver = {
        .probe                  = mv_platform_probe,
        .remove                 = __devexit_p(mv_platform_remove),
+       .suspend                = mv_platform_suspend,
+       .resume                 = mv_platform_resume,
        .driver                 = {
                                   .name = DRV_NAME,
                                   .owner = THIS_MODULE,
@@ -4125,6 +4162,9 @@ static struct platform_driver mv_platform_driver = {
 #ifdef CONFIG_PCI
 static int mv_pci_init_one(struct pci_dev *pdev,
                           const struct pci_device_id *ent);
+#ifdef CONFIG_PM
+static int mv_pci_device_resume(struct pci_dev *pdev);
+#endif
 
 
 static struct pci_driver mv_pci_driver = {
@@ -4132,6 +4172,11 @@ static struct pci_driver mv_pci_driver = {
        .id_table               = mv_pci_tbl,
        .probe                  = mv_pci_init_one,
        .remove                 = ata_pci_remove_one,
+#ifdef CONFIG_PM
+       .suspend                = ata_pci_device_suspend,
+       .resume                 = mv_pci_device_resume,
+#endif
+
 };
 
 /* move to PCI layer or libata core? */
@@ -4225,7 +4270,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
        struct ata_host *host;
        struct mv_host_priv *hpriv;
-       int n_ports, rc;
+       int n_ports, port, rc;
 
        if (!printed_version++)
                dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@@ -4239,6 +4284,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
                return -ENOMEM;
        host->private_data = hpriv;
        hpriv->n_ports = n_ports;
+       hpriv->board_idx = board_idx;
 
        /* acquire resources */
        rc = pcim_enable_device(pdev);
@@ -4261,8 +4307,17 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        if (rc)
                return rc;
 
+       for (port = 0; port < host->n_ports; port++) {
+               struct ata_port *ap = host->ports[port];
+               void __iomem *port_mmio = mv_port_base(hpriv->base, port);
+               unsigned int offset = port_mmio - hpriv->base;
+
+               ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
+               ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
+       }
+
        /* initialize adapter */
-       rc = mv_init_host(host, board_idx);
+       rc = mv_init_host(host);
        if (rc)
                return rc;
 
@@ -4278,6 +4333,27 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
                                 IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }
+
+#ifdef CONFIG_PM
+static int mv_pci_device_resume(struct pci_dev *pdev)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       int rc;
+
+       rc = ata_pci_device_do_resume(pdev);
+       if (rc)
+               return rc;
+
+       /* initialize adapter */
+       rc = mv_init_host(host);
+       if (rc)
+               return rc;
+
+       ata_host_resume(host);
+
+       return 0;
+}
+#endif
 #endif
 
 static int mv_platform_probe(struct platform_device *pdev);