Merge branch 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Aug 2018 20:20:33 +0000 (13:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Aug 2018 20:20:33 +0000 (13:20 -0700)
Pull libata updates from Tejun Heo:
 "Nothing too interesting. Mostly ahci and ahci_platform changes, many
  around power management"

* 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: (22 commits)
  ata: ahci_platform: enable to get and control reset
  ata: libahci_platform: add reset control support
  ata: add an extra argument to ahci_platform_get_resources()
  ata: sata_rcar: Add r8a77965 support
  ata: sata_rcar: exclude setting of PHY registers in Gen3
  ata: sata_rcar: really mask all interrupts on Gen2 and later
  Revert "ata: ahci_platform: allow disabling of hotplug to save power"
  ata: libahci: Allow reconfigure of DEVSLP register
  ata: libahci: Correct setting of DEVSLP register
  ata: ahci: Enable DEVSLP by default on x86 with SLP_S0
  ata: ahci: Support state with min power but Partial low power state
  Revert "ata: ahci_platform: convert kcalloc to devm_kcalloc"
  ata: sata_rcar: Add rudimentary Runtime PM support
  ata: sata_rcar: Provide a short-hand for &pdev->dev
  ata: Only output sg element mapped number in verbose debug
  ata: Guard ata_scsi_dump_cdb() by ATA_VERBOSE_DEBUG
  ata: ahci_platform: convert kcalloc to devm_kcalloc
  ata: ahci_platform: convert kzallloc to kcalloc
  ata: ahci_platform: correct parameter documentation for ahci_platform_shutdown
  libata: remove ata_sff_data_xfer_noirq()
  ...

35 files changed:
Documentation/devicetree/bindings/ata/ahci-platform.txt
Documentation/devicetree/bindings/ata/sata_rcar.txt
Documentation/driver-api/libata.rst
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ahci_brcm.c
drivers/ata/ahci_ceva.c
drivers/ata/ahci_da850.c
drivers/ata/ahci_dm816.c
drivers/ata/ahci_imx.c
drivers/ata/ahci_mtk.c
drivers/ata/ahci_mvebu.c
drivers/ata/ahci_platform.c
drivers/ata/ahci_qoriq.c
drivers/ata/ahci_seattle.c
drivers/ata/ahci_st.c
drivers/ata/ahci_sunxi.c
drivers/ata/ahci_tegra.c
drivers/ata/ahci_xgene.c
drivers/ata/libahci.c
drivers/ata/libahci_platform.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_cmd640.c
drivers/ata/pata_icside.c
drivers/ata/pata_imx.c
drivers/ata/pata_legacy.c
drivers/ata/pata_palmld.c
drivers/ata/pata_pcmcia.c
drivers/ata/pata_platform.c
drivers/ata/pata_via.c
drivers/ata/sata_rcar.c
include/linux/ahci_platform.h
include/linux/libata.h

index 663766685818f41f12f6813b7140b72ec3f84a24..5d5bd456d9d96303e9cbabf4fed97e8cef6b3277 100644 (file)
@@ -29,6 +29,7 @@ compatible:
 Optional properties:
 - dma-coherent      : Present if dma operations are coherent
 - clocks            : a list of phandle + clock specifier pairs
+- resets            : a list of phandle + reset specifier pairs
 - target-supply     : regulator for SATA target power
 - phys              : reference to the SATA PHY node
 - phy-names         : must be "sata-phy"
index e20eac7a30874f0db82adefa0cdf3a77ac09aec2..4268e17d24116cec8e26806823ebd5ca458cc925 100644 (file)
@@ -8,6 +8,7 @@ Required properties:
                          - "renesas,sata-r8a7791" for R-Car M2-W
                          - "renesas,sata-r8a7793" for R-Car M2-N
                          - "renesas,sata-r8a7795" for R-Car H3
+                         - "renesas,sata-r8a77965" for R-Car M3-N
                          - "renesas,rcar-gen2-sata" for a generic R-Car Gen2 compatible device
                          - "renesas,rcar-gen3-sata" for a generic R-Car Gen3 compatible device
                          - "renesas,rcar-sata" is deprecated
index 4adc056f763565f415f3c5ec82fa5a0b9eec01fc..70e180e6b93dcc74d25fb6133bfaeb018166b870 100644 (file)
@@ -118,8 +118,7 @@ PIO data read/write
 All bmdma-style drivers must implement this hook. This is the low-level
 operation that actually copies the data bytes during a PIO data
 transfer. Typically the driver will choose one of
-:c:func:`ata_sff_data_xfer_noirq`, :c:func:`ata_sff_data_xfer`, or
-:c:func:`ata_sff_data_xfer32`.
+:c:func:`ata_sff_data_xfer`, or :c:func:`ata_sff_data_xfer32`.
 
 ATA command execute
 ~~~~~~~~~~~~~~~~~~~
index b2b9eba1d214765723165f1d3d7c1bda64720207..021ce46e2e57343b181976a980abef2e16e798d5 100644 (file)
@@ -610,7 +610,7 @@ static int marvell_enable = 1;
 module_param(marvell_enable, int, 0644);
 MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
 
-static int mobile_lpm_policy = CONFIG_SATA_MOBILE_LPM_POLICY;
+static int mobile_lpm_policy = -1;
 module_param(mobile_lpm_policy, int, 0644);
 MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
 
@@ -1604,6 +1604,37 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
        return pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
 }
 
+static void ahci_update_initial_lpm_policy(struct ata_port *ap,
+                                          struct ahci_host_priv *hpriv)
+{
+       int policy = CONFIG_SATA_MOBILE_LPM_POLICY;
+
+
+       /* Ignore processing for non mobile platforms */
+       if (!(hpriv->flags & AHCI_HFLAG_IS_MOBILE))
+               return;
+
+       /* user modified policy via module param */
+       if (mobile_lpm_policy != -1) {
+               policy = mobile_lpm_policy;
+               goto update_policy;
+       }
+
+#ifdef CONFIG_ACPI
+       if (policy > ATA_LPM_MED_POWER &&
+           (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
+               if (hpriv->cap & HOST_CAP_PART)
+                       policy = ATA_LPM_MIN_POWER_WITH_PARTIAL;
+               else if (hpriv->cap & HOST_CAP_SSC)
+                       policy = ATA_LPM_MIN_POWER;
+       }
+#endif
+
+update_policy:
+       if (policy >= ATA_LPM_UNKNOWN && policy <= ATA_LPM_MIN_POWER)
+               ap->target_lpm_policy = policy;
+}
+
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        unsigned int board_id = ent->driver_data;
@@ -1807,10 +1838,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                if (ap->flags & ATA_FLAG_EM)
                        ap->em_message_type = hpriv->em_msg_type;
 
-               if ((hpriv->flags & AHCI_HFLAG_IS_MOBILE) &&
-                   mobile_lpm_policy >= ATA_LPM_UNKNOWN &&
-                   mobile_lpm_policy <= ATA_LPM_MIN_POWER)
-                       ap->target_lpm_policy = mobile_lpm_policy;
+               ahci_update_initial_lpm_policy(ap, hpriv);
 
                /* disabled/not-implemented port */
                if (!(hpriv->port_map & (1 << i)))
index 1609ebab4e230e885040a0b4582c4b09c789fa7f..6a1515f0da4021d755d433bf618cc423487fe930 100644 (file)
@@ -350,6 +350,7 @@ struct ahci_host_priv {
        u32                     em_msg_type;    /* EM message type */
        bool                    got_runtime_pm; /* Did we do pm_runtime_get? */
        struct clk              *clks[AHCI_MAX_CLKS]; /* Optional */
+       struct reset_control    *rsts;          /* Optional */
        struct regulator        **target_pwrs;  /* Optional */
        /*
         * If platform uses PHYs. There is a 1:1 relation between the port number and
index ea430819c80b9793657652775edda0b7131c08ae..f3d557777d8292bd7739a477b70cc47f5df802e0 100644 (file)
@@ -425,7 +425,7 @@ static int brcm_ahci_probe(struct platform_device *pdev)
 
        brcm_sata_phys_enable(priv);
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
        hpriv->plat_data = priv;
index 5ecc9d46cb54474f50132dd781e2b5da96fe893a..dc78c98cb9f102caf651ac36bbe794fcdf0ac960 100644 (file)
@@ -213,7 +213,7 @@ static int ceva_ahci_probe(struct platform_device *pdev)
 
        cevapriv->ahci_pdev = pdev;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 9b34dff6453633fcc9cf63393eb6fe553af29dbe..ebaa657f28c40c039ff5f6bbaee6f426fd3571fc 100644 (file)
@@ -171,7 +171,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
        u32 mpy;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index fbd827c3a75c79fac65daae8716d023b7df88520..89509c3efb014f76139c98fb282fdb13156a1a3d 100644 (file)
@@ -148,7 +148,7 @@ static int ahci_dm816_probe(struct platform_device *pdev)
        struct ahci_host_priv *hpriv;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 6822e2f33f7e801a53d3dfe423ceaf756e40a06f..b00799d208f509740cdd84bb1743625c7a9f6b62 100644 (file)
@@ -1127,7 +1127,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
                        return ret;
        }
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 0ae6971c2a4cfcd3bba93856335f4a031137385c..8bc1a26ffc31e67073a7ba8154a071ca23d29305 100644 (file)
@@ -142,7 +142,7 @@ static int mtk_ahci_probe(struct platform_device *pdev)
        if (!plat)
                return -ENOMEM;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 72d90b4c3aaefa4b9051d02383b55c9e3899072b..f9cb51be38ebfd099940c1836d34e6933275ec54 100644 (file)
@@ -158,7 +158,7 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
        const struct mbus_dram_target_info *dram;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 564570ea3e273a74dea7007e64d136bf672d90e9..46f0bd75eff7984f9709d431aaa874fa951c3724 100644 (file)
@@ -43,7 +43,8 @@ static int ahci_probe(struct platform_device *pdev)
        struct ahci_host_priv *hpriv;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev,
+                                           AHCI_PLATFORM_GET_RESETS);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index cfdef4d44ae92cdf5a335c99a7d049df8a8cb5ae..ce59253ec158e1765570892b017e662c98eb0a59 100644 (file)
@@ -250,7 +250,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
        struct resource *res;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 1d31c0c0fc20b48c287d2df293776cf9c1e52329..e57b6f92c288574b557b06614275b05dbdcd1ad9 100644 (file)
@@ -164,7 +164,7 @@ static int ahci_seattle_probe(struct platform_device *pdev)
        int rc;
        struct ahci_host_priv *hpriv;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index bc345f24955531fba69e36e1bc0233da3bb6fc88..21c5c44832ef3b6466ce4e0f81189d490ee7c6cf 100644 (file)
@@ -156,7 +156,7 @@ static int st_ahci_probe(struct platform_device *pdev)
        if (!drv_data)
                return -ENOMEM;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
        hpriv->plat_data = drv_data;
index b26437430163e89f2c9a81e725df51d5c6c777f3..631610b72aa5843431e05b1f709abedcc1df3efb 100644 (file)
@@ -181,7 +181,7 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
        struct ahci_host_priv *hpriv;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 64d848409fe23d4c457f57f8b26d39769199caed..004f2608818ed85da701451a02da23dd02d78259 100644 (file)
@@ -494,7 +494,7 @@ static int tegra_ahci_probe(struct platform_device *pdev)
        int ret;
        unsigned int i;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index ad58da7c9affd8e4ec381d8bb0fd7f23d6fa0310..7e157e1bf65e47f160a10b9e8a6a335bbaaa8d5c 100644 (file)
@@ -759,7 +759,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
                                              &xgene_ahci_v2_port_info };
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 09620c2ffa0f72e1a696d10d3e4480818b101e51..b5f57c69c48786e7b795b399b8a828a111534ec9 100644 (file)
@@ -801,6 +801,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
                        cmd |= PORT_CMD_ALPE;
                        if (policy == ATA_LPM_MIN_POWER)
                                cmd |= PORT_CMD_ASP;
+                       else if (policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
+                               cmd &= ~PORT_CMD_ASP;
 
                        /* write out new cmd value */
                        writel(cmd, port_mmio + PORT_CMD);
@@ -811,7 +813,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
        if ((hpriv->cap2 & HOST_CAP2_SDS) &&
            (hpriv->cap2 & HOST_CAP2_SADM) &&
            (link->device->flags & ATA_DFLAG_DEVSLP)) {
-               if (policy == ATA_LPM_MIN_POWER)
+               if (policy == ATA_LPM_MIN_POWER ||
+                   policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
                        ahci_set_aggressive_devslp(ap, true);
                else
                        ahci_set_aggressive_devslp(ap, false);
@@ -2107,7 +2110,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
        struct ahci_host_priv *hpriv = ap->host->private_data;
        void __iomem *port_mmio = ahci_port_base(ap);
        struct ata_device *dev = ap->link.device;
-       u32 devslp, dm, dito, mdat, deto;
+       u32 devslp, dm, dito, mdat, deto, dito_conf;
        int rc;
        unsigned int err_mask;
 
@@ -2131,8 +2134,15 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
                return;
        }
 
-       /* device sleep was already enabled */
-       if (devslp & PORT_DEVSLP_ADSE)
+       dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
+       dito = devslp_idle_timeout / (dm + 1);
+       if (dito > 0x3ff)
+               dito = 0x3ff;
+
+       dito_conf = (devslp >> PORT_DEVSLP_DITO_OFFSET) & 0x3FF;
+
+       /* device sleep was already enabled and same dito */
+       if ((devslp & PORT_DEVSLP_ADSE) && (dito_conf == dito))
                return;
 
        /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */
@@ -2140,11 +2150,6 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
        if (rc)
                return;
 
-       dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
-       dito = devslp_idle_timeout / (dm + 1);
-       if (dito > 0x3ff)
-               dito = 0x3ff;
-
        /* Use the nominal value 10 ms if the read MDAT is zero,
         * the nominal value of DETO is 20 ms.
         */
@@ -2162,6 +2167,8 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
                deto = 20;
        }
 
+       /* Make dito, mdat, deto bits to 0s */
+       devslp &= ~GENMASK_ULL(24, 2);
        devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) |
                   (mdat << PORT_DEVSLP_MDAT_OFFSET) |
                   (deto << PORT_DEVSLP_DETO_OFFSET) |
@@ -2439,6 +2446,8 @@ static void ahci_port_stop(struct ata_port *ap)
         * re-enabling INTx.
         */
        writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT);
+
+       ahci_rpm_put_port(ap);
 }
 
 void ahci_print_info(struct ata_host *host, const char *scc_s)
index 30cc8f1a31e1299f3cc68659a5be959492249382..c92c10d553746da95702677b9b380a0da099b242 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
 #include <linux/of_platform.h>
+#include <linux/reset.h>
 #include "ahci.h"
 
 static void ahci_host_stop(struct ata_host *host);
@@ -195,7 +196,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
  * following order:
  * 1) Regulator
  * 2) Clocks (through ahci_platform_enable_clks)
- * 3) Phys
+ * 3) Resets
+ * 4) Phys
  *
  * If resource enabling fails at any point the previous enabled resources
  * are disabled in reverse order.
@@ -215,12 +217,19 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
        if (rc)
                goto disable_regulator;
 
-       rc = ahci_platform_enable_phys(hpriv);
+       rc = reset_control_deassert(hpriv->rsts);
        if (rc)
                goto disable_clks;
 
+       rc = ahci_platform_enable_phys(hpriv);
+       if (rc)
+               goto disable_resets;
+
        return 0;
 
+disable_resets:
+       reset_control_assert(hpriv->rsts);
+
 disable_clks:
        ahci_platform_disable_clks(hpriv);
 
@@ -238,13 +247,16 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
  * This function disables all ahci_platform managed resources in the
  * following order:
  * 1) Phys
- * 2) Clocks (through ahci_platform_disable_clks)
- * 3) Regulator
+ * 2) Resets
+ * 3) Clocks (through ahci_platform_disable_clks)
+ * 4) Regulator
  */
 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
 {
        ahci_platform_disable_phys(hpriv);
 
+       reset_control_assert(hpriv->rsts);
+
        ahci_platform_disable_clks(hpriv);
 
        ahci_platform_disable_regulators(hpriv);
@@ -332,6 +344,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
 /**
  * ahci_platform_get_resources - Get platform resources
  * @pdev: platform device to get resources for
+ * @flags: bitmap representing the resource to get
  *
  * This function allocates an ahci_host_priv struct, and gets the following
  * resources, storing a reference to them inside the returned struct:
@@ -340,18 +353,20 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
  * 2) regulator for controlling the targets power (optional)
  * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
  *    or for non devicetree enabled platforms a single clock
- * 4) phys (optional)
+ * 4) resets, if flags has AHCI_PLATFORM_GET_RESETS (optional)
+ * 5) phys (optional)
  *
  * RETURNS:
  * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
  */
-struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
+struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
+                                                  unsigned int flags)
 {
        struct device *dev = &pdev->dev;
        struct ahci_host_priv *hpriv;
        struct clk *clk;
        struct device_node *child;
-       int i, sz, enabled_ports = 0, rc = -ENOMEM, child_nodes;
+       int i, enabled_ports = 0, rc = -ENOMEM, child_nodes;
        u32 mask_port_map = 0;
 
        if (!devres_open_group(dev, NULL, GFP_KERNEL))
@@ -393,6 +408,14 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
                hpriv->clks[i] = clk;
        }
 
+       if (flags & AHCI_PLATFORM_GET_RESETS) {
+               hpriv->rsts = devm_reset_control_array_get_optional_shared(dev);
+               if (IS_ERR(hpriv->rsts)) {
+                       rc = PTR_ERR(hpriv->rsts);
+                       goto err_out;
+               }
+       }
+
        hpriv->nports = child_nodes = of_get_child_count(dev->of_node);
 
        /*
@@ -403,14 +426,16 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
        if (!child_nodes)
                hpriv->nports = 1;
 
-       sz = hpriv->nports * sizeof(*hpriv->phys);
-       hpriv->phys = devm_kzalloc(dev, sz, GFP_KERNEL);
+       hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL);
        if (!hpriv->phys) {
                rc = -ENOMEM;
                goto err_out;
        }
-       sz = hpriv->nports * sizeof(*hpriv->target_pwrs);
-       hpriv->target_pwrs = kzalloc(sz, GFP_KERNEL);
+       /*
+        * We cannot use devm_ here, since ahci_platform_put_resources() uses
+        * target_pwrs after devm_ have freed memory
+        */
+       hpriv->target_pwrs = kcalloc(hpriv->nports, sizeof(*hpriv->target_pwrs), GFP_KERNEL);
        if (!hpriv->target_pwrs) {
                rc = -ENOMEM;
                goto err_out;
@@ -605,7 +630,7 @@ static void ahci_host_stop(struct ata_host *host)
 
 /**
  * ahci_platform_shutdown - Disable interrupts and stop DMA for host ports
- * @dev: platform device pointer for the host
+ * @pdev: platform device pointer for the host
  *
  * This function is called during system shutdown and performs the minimal
  * deconfiguration required to ensure that an ahci_platform host cannot
index 984b37647b2f025c1a43ffda8e6d38f825099c5c..172e32840256bef2365a0841950da638900a098e 100644 (file)
@@ -3970,6 +3970,7 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
                scontrol |= (0x6 << 8);
                break;
        case ATA_LPM_MED_POWER_WITH_DIPM:
+       case ATA_LPM_MIN_POWER_WITH_PARTIAL:
        case ATA_LPM_MIN_POWER:
                if (ata_link_nr_enabled(link) > 0)
                        /* no restrictions on LPM transitions */
@@ -5066,7 +5067,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
        if (n_elem < 1)
                return -1;
 
-       DPRINTK("%d sg elements mapped\n", n_elem);
+       VPRINTK("%d sg elements mapped\n", n_elem);
        qc->orig_n_elem = qc->n_elem;
        qc->n_elem = n_elem;
        qc->flags |= ATA_QCFLAG_DMAMAP;
index 8e270962b2f31431f9185d9da30410897e9fb950..1984fc78c750b42505a5178761366dce33fa4089 100644 (file)
@@ -110,6 +110,7 @@ static const char *ata_lpm_policy_names[] = {
        [ATA_LPM_MAX_POWER]             = "max_performance",
        [ATA_LPM_MED_POWER]             = "medium_power",
        [ATA_LPM_MED_POWER_WITH_DIPM]   = "med_power_with_dipm",
+       [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial",
        [ATA_LPM_MIN_POWER]             = "min_power",
 };
 
@@ -4288,10 +4289,10 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
 static inline void ata_scsi_dump_cdb(struct ata_port *ap,
                                     struct scsi_cmnd *cmd)
 {
-#ifdef ATA_DEBUG
+#ifdef ATA_VERBOSE_DEBUG
        struct scsi_device *scsidev = cmd->device;
 
-       DPRINTK("CDB (%u:%d,%d,%lld) %9ph\n",
+       VPRINTK("CDB (%u:%d,%d,%lld) %9ph\n",
                ap->print_id,
                scsidev->channel, scsidev->id, scsidev->lun,
                cmd->cmnd);
index cc2f2e35f4c2e4ee49a67ef8df5da34cfb182a4e..c5ea0fc635e54eb800cb12d8812ea5e508c388cc 100644 (file)
@@ -657,36 +657,6 @@ unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf,
 }
 EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
 
-/**
- *     ata_sff_data_xfer_noirq - Transfer data by PIO
- *     @qc: queued command
- *     @buf: data buffer
- *     @buflen: buffer length
- *     @rw: read/write
- *
- *     Transfer data from/to the device data register by PIO. Do the
- *     transfer with interrupts disabled.
- *
- *     LOCKING:
- *     Inherited from caller.
- *
- *     RETURNS:
- *     Bytes consumed.
- */
-unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc, unsigned char *buf,
-                                    unsigned int buflen, int rw)
-{
-       unsigned long flags;
-       unsigned int consumed;
-
-       local_irq_save(flags);
-       consumed = ata_sff_data_xfer32(qc, buf, buflen, rw);
-       local_irq_restore(flags);
-
-       return consumed;
-}
-EXPORT_SYMBOL_GPL(ata_sff_data_xfer_noirq);
-
 /**
  *     ata_pio_sector - Transfer a sector of data.
  *     @qc: Command on going
index c47caa807fa933d370e91720ca99df253216c803..e3532eda7b058d41a16500c9b6d6dc7a0d6b1059 100644 (file)
@@ -178,7 +178,7 @@ static struct scsi_host_template cmd640_sht = {
 static struct ata_port_operations cmd640_port_ops = {
        .inherits       = &ata_sff_port_ops,
        /* In theory xfer_noirq is not needed once we kill the prefetcher */
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
        .sff_irq_check  = cmd640_sff_irq_check,
        .qc_issue       = cmd640_qc_issue,
        .cable_detect   = ata_cable_40wire,
index 188f2f2eb21fe54ad5b62675864cb97ea31f9c32..c272f2cbb47c5872fae9d17a29ff7bfe0d79e48f 100644 (file)
@@ -324,7 +324,7 @@ static struct ata_port_operations pata_icside_port_ops = {
        .inherits               = &ata_bmdma_port_ops,
        /* no need to build any PRD tables for DMA */
        .qc_prep                = ata_noop_qc_prep,
-       .sff_data_xfer          = ata_sff_data_xfer_noirq,
+       .sff_data_xfer          = ata_sff_data_xfer32,
        .bmdma_setup            = pata_icside_bmdma_setup,
        .bmdma_start            = pata_icside_bmdma_start,
        .bmdma_stop             = pata_icside_bmdma_stop,
index 6f0534047c6d748fa2879937944556aebbef755b..2e538726802b68674f172a7c76e459f743ed5e91 100644 (file)
@@ -103,7 +103,7 @@ static struct scsi_host_template pata_imx_sht = {
 
 static struct ata_port_operations pata_imx_port_ops = {
        .inherits               = &ata_sff_port_ops,
-       .sff_data_xfer          = ata_sff_data_xfer_noirq,
+       .sff_data_xfer          = ata_sff_data_xfer32,
        .cable_detect           = ata_cable_unknown,
        .set_piomode            = pata_imx_set_piomode,
 };
index 53828b6c30441735b62a36103d42d67df58794b6..8ea4b8431fc822855f79ad2853b1ab4832ec6da4 100644 (file)
@@ -246,12 +246,12 @@ static const struct ata_port_operations legacy_base_port_ops = {
 
 static struct ata_port_operations simple_port_ops = {
        .inherits       = &legacy_base_port_ops,
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
 };
 
 static struct ata_port_operations legacy_port_ops = {
        .inherits       = &legacy_base_port_ops,
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
        .set_mode       = legacy_set_mode,
 };
 
@@ -341,7 +341,7 @@ static unsigned int pdc_data_xfer_vlb(struct ata_queued_cmd *qc,
                }
                local_irq_restore(flags);
        } else
-               buflen = ata_sff_data_xfer_noirq(qc, buf, buflen, rw);
+               buflen = ata_sff_data_xfer32(qc, buf, buflen, rw);
 
        return buflen;
 }
index 8c0d7d736b7afd81b1146536527efc3b46bab42e..d071ab6864a8a82cafd2befcfefbfaba93952dd8 100644 (file)
@@ -44,7 +44,7 @@ static struct scsi_host_template palmld_sht = {
 
 static struct ata_port_operations palmld_port_ops = {
        .inherits               = &ata_sff_port_ops,
-       .sff_data_xfer          = ata_sff_data_xfer_noirq,
+       .sff_data_xfer          = ata_sff_data_xfer32,
        .cable_detect           = ata_cable_40wire,
 };
 
index a541eacc5e95c3278598c4b849146280b1f6cc87..9b0e6c72e3f96c3cf55a7cc438c25f20b2f8ba6d 100644 (file)
@@ -151,7 +151,7 @@ static struct scsi_host_template pcmcia_sht = {
 
 static struct ata_port_operations pcmcia_port_ops = {
        .inherits       = &ata_sff_port_ops,
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
        .cable_detect   = ata_cable_40wire,
        .set_mode       = pcmcia_set_mode,
 };
index c503ded87bb88a341cb0c2d1f9e22e0fb9ddd60f..d6f8f540644243fa8accf10b59e145982295b10b 100644 (file)
@@ -49,7 +49,7 @@ static struct scsi_host_template pata_platform_sht = {
 
 static struct ata_port_operations pata_platform_port_ops = {
        .inherits               = &ata_sff_port_ops,
-       .sff_data_xfer          = ata_sff_data_xfer_noirq,
+       .sff_data_xfer          = ata_sff_data_xfer32,
        .cable_detect           = ata_cable_unknown,
        .set_mode               = pata_platform_set_mode,
 };
index 1ca6bcab369f015dffc43718b985d58717eabce5..fd19f1ce83aa16dffd2e23cb6e8d9ae54c2129b7 100644 (file)
@@ -471,7 +471,7 @@ static struct ata_port_operations via_port_ops = {
 
 static struct ata_port_operations via_port_ops_noirq = {
        .inherits       = &via_port_ops,
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
 };
 
 /**
index 6456e07db72a7ea4e5cf2bcb1110dec9db42e946..10ecb232245db8c617ee808966db432ece834358 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/libata.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/err.h>
 
 #define DRV_NAME "sata_rcar"
 #define SATAINTMASK_ERRMSK             BIT(2)
 #define SATAINTMASK_ERRCRTMSK          BIT(1)
 #define SATAINTMASK_ATAMSK             BIT(0)
+#define SATAINTMASK_ALL_GEN1           0x7ff
+#define SATAINTMASK_ALL_GEN2           0xfff
 
 #define SATA_RCAR_INT_MASK             (SATAINTMASK_SERRMSK | \
                                         SATAINTMASK_ATAMSK)
@@ -152,7 +154,7 @@ enum sata_rcar_type {
 
 struct sata_rcar_priv {
        void __iomem *base;
-       struct clk *clk;
+       u32 sataint_mask;
        enum sata_rcar_type type;
 };
 
@@ -226,7 +228,7 @@ static void sata_rcar_freeze(struct ata_port *ap)
        struct sata_rcar_priv *priv = ap->host->private_data;
 
        /* mask */
-       iowrite32(0x7ff, priv->base + SATAINTMASK_REG);
+       iowrite32(priv->sataint_mask, priv->base + SATAINTMASK_REG);
 
        ata_sff_freeze(ap);
 }
@@ -242,7 +244,7 @@ static void sata_rcar_thaw(struct ata_port *ap)
        ata_sff_thaw(ap);
 
        /* unmask */
-       iowrite32(0x7ff & ~SATA_RCAR_INT_MASK, base + SATAINTMASK_REG);
+       iowrite32(priv->sataint_mask & ~SATA_RCAR_INT_MASK, base + SATAINTMASK_REG);
 }
 
 static void sata_rcar_ioread16_rep(void __iomem *reg, void *buffer, int count)
@@ -736,7 +738,7 @@ static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance)
        if (!sataintstat)
                goto done;
        /* ack */
-       iowrite32(~sataintstat & 0x7ff, base + SATAINTSTAT_REG);
+       iowrite32(~sataintstat & priv->sataint_mask, base + SATAINTSTAT_REG);
 
        ap = host->ports[0];
 
@@ -809,7 +811,7 @@ static void sata_rcar_init_module(struct sata_rcar_priv *priv)
 
        /* ack and mask */
        iowrite32(0, base + SATAINTSTAT_REG);
-       iowrite32(0x7ff, base + SATAINTMASK_REG);
+       iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
 
        /* enable interrupts */
        iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
@@ -819,16 +821,20 @@ static void sata_rcar_init_controller(struct ata_host *host)
 {
        struct sata_rcar_priv *priv = host->private_data;
 
+       priv->sataint_mask = SATAINTMASK_ALL_GEN2;
+
        /* reset and setup phy */
        switch (priv->type) {
        case RCAR_GEN1_SATA:
+               priv->sataint_mask = SATAINTMASK_ALL_GEN1;
                sata_rcar_gen1_phy_init(priv);
                break;
        case RCAR_GEN2_SATA:
-       case RCAR_GEN3_SATA:
        case RCAR_R8A7790_ES1_SATA:
                sata_rcar_gen2_phy_init(priv);
                break;
+       case RCAR_GEN3_SATA:
+               break;
        default:
                dev_warn(host->dev, "SATA phy is not initialized\n");
                break;
@@ -881,6 +887,7 @@ MODULE_DEVICE_TABLE(of, sata_rcar_match);
 
 static int sata_rcar_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        struct ata_host *host;
        struct sata_rcar_priv *priv;
        struct resource *mem;
@@ -891,36 +898,31 @@ static int sata_rcar_probe(struct platform_device *pdev)
        if (irq <= 0)
                return -EINVAL;
 
-       priv = devm_kzalloc(&pdev->dev, sizeof(struct sata_rcar_priv),
-                          GFP_KERNEL);
+       priv = devm_kzalloc(dev, sizeof(struct sata_rcar_priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
-       priv->type = (enum sata_rcar_type)of_device_get_match_data(&pdev->dev);
-       priv->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(priv->clk)) {
-               dev_err(&pdev->dev, "failed to get access to sata clock\n");
-               return PTR_ERR(priv->clk);
-       }
+       priv->type = (enum sata_rcar_type)of_device_get_match_data(dev);
 
-       ret = clk_prepare_enable(priv->clk);
-       if (ret)
-               return ret;
+       pm_runtime_enable(dev);
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
+               goto err_pm_disable;
 
-       host = ata_host_alloc(&pdev->dev, 1);
+       host = ata_host_alloc(dev, 1);
        if (!host) {
-               dev_err(&pdev->dev, "ata_host_alloc failed\n");
+               dev_err(dev, "ata_host_alloc failed\n");
                ret = -ENOMEM;
-               goto cleanup;
+               goto err_pm_put;
        }
 
        host->private_data = priv;
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->base = devm_ioremap_resource(&pdev->dev, mem);
+       priv->base = devm_ioremap_resource(dev, mem);
        if (IS_ERR(priv->base)) {
                ret = PTR_ERR(priv->base);
-               goto cleanup;
+               goto err_pm_put;
        }
 
        /* setup port */
@@ -934,9 +936,10 @@ static int sata_rcar_probe(struct platform_device *pdev)
        if (!ret)
                return 0;
 
-cleanup:
-       clk_disable_unprepare(priv->clk);
-
+err_pm_put:
+       pm_runtime_put(dev);
+err_pm_disable:
+       pm_runtime_disable(dev);
        return ret;
 }
 
@@ -952,9 +955,10 @@ static int sata_rcar_remove(struct platform_device *pdev)
        iowrite32(0, base + ATAPI_INT_ENABLE_REG);
        /* ack and mask */
        iowrite32(0, base + SATAINTSTAT_REG);
-       iowrite32(0x7ff, base + SATAINTMASK_REG);
+       iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
 
-       clk_disable_unprepare(priv->clk);
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
@@ -972,9 +976,9 @@ static int sata_rcar_suspend(struct device *dev)
                /* disable interrupts */
                iowrite32(0, base + ATAPI_INT_ENABLE_REG);
                /* mask */
-               iowrite32(0x7ff, base + SATAINTMASK_REG);
+               iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
 
-               clk_disable_unprepare(priv->clk);
+               pm_runtime_put(dev);
        }
 
        return ret;
@@ -987,17 +991,16 @@ static int sata_rcar_resume(struct device *dev)
        void __iomem *base = priv->base;
        int ret;
 
-       ret = clk_prepare_enable(priv->clk);
-       if (ret)
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
                return ret;
 
        if (priv->type == RCAR_GEN3_SATA) {
-               sata_rcar_gen2_phy_init(priv);
                sata_rcar_init_module(priv);
        } else {
                /* ack and mask */
                iowrite32(0, base + SATAINTSTAT_REG);
-               iowrite32(0x7ff, base + SATAINTMASK_REG);
+               iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
 
                /* enable interrupts */
                iowrite32(ATAPI_INT_ENABLE_SATAINT,
@@ -1012,11 +1015,10 @@ static int sata_rcar_resume(struct device *dev)
 static int sata_rcar_restore(struct device *dev)
 {
        struct ata_host *host = dev_get_drvdata(dev);
-       struct sata_rcar_priv *priv = host->private_data;
        int ret;
 
-       ret = clk_prepare_enable(priv->clk);
-       if (ret)
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
                return ret;
 
        sata_rcar_setup_port(host);
index 1b0a17b22cd3c8e224a7d3dd1fdaa155830ac49a..eaedca5fe6fca8c84f02b90ccecad44ac72c84b9 100644 (file)
@@ -30,7 +30,7 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv);
 int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
 struct ahci_host_priv *ahci_platform_get_resources(
-       struct platform_device *pdev);
+       struct platform_device *pdev, unsigned int flags);
 int ahci_platform_init_host(struct platform_device *pdev,
                            struct ahci_host_priv *hpriv,
                            const struct ata_port_info *pi_template,
@@ -43,4 +43,6 @@ int ahci_platform_resume_host(struct device *dev);
 int ahci_platform_suspend(struct device *dev);
 int ahci_platform_resume(struct device *dev);
 
+#define AHCI_PLATFORM_GET_RESETS       0x01
+
 #endif /* _AHCI_PLATFORM_H */
index bc4f87cbe7f40d70d61a942b819769560816fb73..38c95d66ab12f1465fe02c9b62752a8887976dae 100644 (file)
@@ -523,7 +523,8 @@ enum ata_lpm_policy {
        ATA_LPM_MAX_POWER,
        ATA_LPM_MED_POWER,
        ATA_LPM_MED_POWER_WITH_DIPM, /* Med power + DIPM as win IRST does */
-       ATA_LPM_MIN_POWER,
+       ATA_LPM_MIN_POWER_WITH_PARTIAL, /* Min Power + partial and slumber */
+       ATA_LPM_MIN_POWER, /* Min power + no partial (slumber only) */
 };
 
 enum ata_lpm_hints {
@@ -1858,8 +1859,6 @@ extern unsigned int ata_sff_data_xfer(struct ata_queued_cmd *qc,
                        unsigned char *buf, unsigned int buflen, int rw);
 extern unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc,
                        unsigned char *buf, unsigned int buflen, int rw);
-extern unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc,
-                       unsigned char *buf, unsigned int buflen, int rw);
 extern void ata_sff_irq_on(struct ata_port *ap);
 extern void ata_sff_irq_clear(struct ata_port *ap);
 extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,