ARM64: sched: fix bug: remove printk while schedule is in progress
[firefly-linux-kernel-4.4.55.git] / drivers / ata / sata_mv.c
index b256ff5b65794dab8decc4ab85ee64e9d0ccbf1e..bd74ee555278513118d057e832b3ec599923bb69 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
 #include <linux/clk.h>
+#include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
@@ -305,6 +306,11 @@ enum {
        MV5_PHY_CTL             = 0x0C,
        SATA_IFCFG              = 0x050,
        LP_PHY_CTL              = 0x058,
+       LP_PHY_CTL_PIN_PU_PLL   = (1 << 0),
+       LP_PHY_CTL_PIN_PU_RX    = (1 << 1),
+       LP_PHY_CTL_PIN_PU_TX    = (1 << 2),
+       LP_PHY_CTL_GEN_TX_3G    = (1 << 5),
+       LP_PHY_CTL_GEN_RX_3G    = (1 << 9),
 
        MV_M2_PREAMP_MASK       = 0x7e0,
 
@@ -555,10 +561,21 @@ struct mv_host_priv {
        u32                     irq_mask_offset;
        u32                     unmask_all_irqs;
 
-#if defined(CONFIG_HAVE_CLK)
+       /*
+        * Needed on some devices that require their clocks to be enabled.
+        * These are optional: if the platform device does not have any
+        * clocks, they won't be used.  Also, if the underlying hardware
+        * does not support the common clock framework (CONFIG_HAVE_CLK=n),
+        * all the clock operations become no-ops (see clk.h).
+        */
        struct clk              *clk;
        struct clk              **port_clks;
-#endif
+       /*
+        * Some devices have a SATA PHY which can be enabled/disabled
+        * in order to save power. These are optional: if the platform
+        * devices does not have any phy, they won't be used.
+        */
+       struct phy              **port_phys;
        /*
         * These consistent DMA memory pools give us guaranteed
         * alignment for hardware-accessed data structures,
@@ -1379,10 +1396,17 @@ static int mv_scr_write(struct ata_link *link, unsigned int sc_reg_in, u32 val)
                                /*
                                 * Set PHY speed according to SControl speed.
                                 */
-                               if ((val & 0xf0) == 0x10)
-                                       writelfl(0x7, lp_phy_addr);
-                               else
-                                       writelfl(0x227, lp_phy_addr);
+                               u32 lp_phy_val =
+                                       LP_PHY_CTL_PIN_PU_PLL |
+                                       LP_PHY_CTL_PIN_PU_RX  |
+                                       LP_PHY_CTL_PIN_PU_TX;
+
+                               if ((val & 0xf0) != 0x10)
+                                       lp_phy_val |=
+                                               LP_PHY_CTL_GEN_TX_3G |
+                                               LP_PHY_CTL_GEN_RX_3G;
+
+                               writelfl(lp_phy_val, lp_phy_addr);
                        }
                }
                writelfl(val, addr);
@@ -4047,9 +4071,7 @@ static int mv_platform_probe(struct platform_device *pdev)
        struct resource *res;
        int n_ports = 0, irq = 0;
        int rc;
-#if defined(CONFIG_HAVE_CLK)
        int port;
-#endif
 
        ata_print_version_once(&pdev->dev, DRV_VERSION);
 
@@ -4073,7 +4095,7 @@ static int mv_platform_probe(struct platform_device *pdev)
                of_property_read_u32(pdev->dev.of_node, "nr-ports", &n_ports);
                irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
        } else {
-               mv_platform_data = pdev->dev.platform_data;
+               mv_platform_data = dev_get_platdata(&pdev->dev);
                n_ports = mv_platform_data->n_ports;
                irq = platform_get_irq(pdev, 0);
        }
@@ -4083,15 +4105,17 @@ static int mv_platform_probe(struct platform_device *pdev)
 
        if (!host || !hpriv)
                return -ENOMEM;
-#if defined(CONFIG_HAVE_CLK)
        hpriv->port_clks = devm_kzalloc(&pdev->dev,
                                        sizeof(struct clk *) * n_ports,
                                        GFP_KERNEL);
        if (!hpriv->port_clks)
                return -ENOMEM;
-#endif
+       hpriv->port_phys = devm_kzalloc(&pdev->dev,
+                                       sizeof(struct phy *) * n_ports,
+                                       GFP_KERNEL);
+       if (!hpriv->port_phys)
+               return -ENOMEM;
        host->private_data = hpriv;
-       hpriv->n_ports = n_ports;
        hpriv->board_idx = chip_soc;
 
        host->iomap = NULL;
@@ -4099,7 +4123,6 @@ static int mv_platform_probe(struct platform_device *pdev)
                                   resource_size(res));
        hpriv->base -= SATAHC0_REG_BASE;
 
-#if defined(CONFIG_HAVE_CLK)
        hpriv->clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(hpriv->clk))
                dev_notice(&pdev->dev, "cannot get optional clkdev\n");
@@ -4112,8 +4135,25 @@ static int mv_platform_probe(struct platform_device *pdev)
                hpriv->port_clks[port] = clk_get(&pdev->dev, port_number);
                if (!IS_ERR(hpriv->port_clks[port]))
                        clk_prepare_enable(hpriv->port_clks[port]);
+
+               sprintf(port_number, "port%d", port);
+               hpriv->port_phys[port] = devm_phy_optional_get(&pdev->dev,
+                                                              port_number);
+               if (IS_ERR(hpriv->port_phys[port])) {
+                       rc = PTR_ERR(hpriv->port_phys[port]);
+                       hpriv->port_phys[port] = NULL;
+                       if (rc != -EPROBE_DEFER)
+                               dev_warn(&pdev->dev, "error getting phy %d", rc);
+
+                       /* Cleanup only the initialized ports */
+                       hpriv->n_ports = port;
+                       goto err;
+               } else
+                       phy_power_on(hpriv->port_phys[port]);
        }
-#endif
+
+       /* All the ports have been initialized */
+       hpriv->n_ports = n_ports;
 
        /*
         * (Re-)program MBUS remapping windows if we are asked to.
@@ -4148,18 +4188,17 @@ static int mv_platform_probe(struct platform_device *pdev)
                return 0;
 
 err:
-#if defined(CONFIG_HAVE_CLK)
        if (!IS_ERR(hpriv->clk)) {
                clk_disable_unprepare(hpriv->clk);
                clk_put(hpriv->clk);
        }
-       for (port = 0; port < n_ports; port++) {
+       for (port = 0; port < hpriv->n_ports; port++) {
                if (!IS_ERR(hpriv->port_clks[port])) {
                        clk_disable_unprepare(hpriv->port_clks[port]);
                        clk_put(hpriv->port_clks[port]);
                }
+               phy_power_off(hpriv->port_phys[port]);
        }
-#endif
 
        return rc;
 }
@@ -4175,13 +4214,10 @@ err:
 static int mv_platform_remove(struct platform_device *pdev)
 {
        struct ata_host *host = platform_get_drvdata(pdev);
-#if defined(CONFIG_HAVE_CLK)
        struct mv_host_priv *hpriv = host->private_data;
        int port;
-#endif
        ata_host_detach(host);
 
-#if defined(CONFIG_HAVE_CLK)
        if (!IS_ERR(hpriv->clk)) {
                clk_disable_unprepare(hpriv->clk);
                clk_put(hpriv->clk);
@@ -4191,12 +4227,12 @@ static int mv_platform_remove(struct platform_device *pdev)
                        clk_disable_unprepare(hpriv->port_clks[port]);
                        clk_put(hpriv->port_clks[port]);
                }
+               phy_power_off(hpriv->port_phys[port]);
        }
-#endif
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct ata_host *host = platform_get_drvdata(pdev);
@@ -4254,7 +4290,6 @@ static struct platform_driver mv_platform_driver = {
        .resume         = mv_platform_resume,
        .driver         = {
                .name = DRV_NAME,
-               .owner = THIS_MODULE,
                .of_match_table = of_match_ptr(mv_sata_dt_ids),
        },
 };
@@ -4263,7 +4298,7 @@ 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
+#ifdef CONFIG_PM_SLEEP
 static int mv_pci_device_resume(struct pci_dev *pdev);
 #endif
 
@@ -4273,7 +4308,7 @@ 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
+#ifdef CONFIG_PM_SLEEP
        .suspend                = ata_pci_device_suspend,
        .resume                 = mv_pci_device_resume,
 #endif
@@ -4285,10 +4320,10 @@ static int pci_go_64(struct pci_dev *pdev)
 {
        int rc;
 
-       if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-               rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+       if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
+               rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
                if (rc) {
-                       rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+                       rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
                        if (rc) {
                                dev_err(&pdev->dev,
                                        "64-bit DMA enable failed\n");
@@ -4296,12 +4331,12 @@ static int pci_go_64(struct pci_dev *pdev)
                        }
                }
        } else {
-               rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+               rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
                if (rc) {
                        dev_err(&pdev->dev, "32-bit DMA enable failed\n");
                        return rc;
                }
-               rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+               rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
                if (rc) {
                        dev_err(&pdev->dev,
                                "32-bit consistent DMA enable failed\n");
@@ -4431,7 +4466,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
                                 IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int mv_pci_device_resume(struct pci_dev *pdev)
 {
        struct ata_host *host = pci_get_drvdata(pdev);
@@ -4453,9 +4488,6 @@ static int mv_pci_device_resume(struct pci_dev *pdev)
 #endif
 #endif
 
-static int mv_platform_probe(struct platform_device *pdev);
-static int mv_platform_remove(struct platform_device *pdev);
-
 static int __init mv_init(void)
 {
        int rc = -ENODEV;