1 From a52ae09871d171d6771b4bef2d4c56dd435e740f Mon Sep 17 00:00:00 2001
2 From: Roger Quadros <rogerq@ti.com>
3 Date: Mon, 20 Jan 2014 16:32:33 +0200
4 Subject: [PATCH] ata: ahci_platform: Add DT compatible for Synopsis DWC AHCI
7 Add compatible string "snps,dwc-ahci", which should be used
8 for Synopsis Designware SATA cores. e.g. on TI OMAP5 and DRA7 platforms.
10 Signed-off-by: Roger Quadros <rogerq@ti.com>
11 Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
12 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
14 drivers/ata/ahci_platform.c | 1 +
15 1 file changed, 1 insertion(+)
17 --- a/drivers/ata/ahci_platform.c
18 +++ b/drivers/ata/ahci_platform.c
20 #include <linux/platform_device.h>
21 #include <linux/libata.h>
22 #include <linux/ahci_platform.h>
23 +#include <linux/phy/phy.h>
24 +#include <linux/pm_runtime.h>
27 static void ahci_host_stop(struct ata_host *host);
28 @@ -147,6 +149,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_
29 * the following order:
31 * 2) Clocks (through ahci_platform_enable_clks)
34 * If resource enabling fails at any point the previous enabled
35 * resources are disabled in reverse order.
36 @@ -171,8 +174,23 @@ int ahci_platform_enable_resources(struc
38 goto disable_regulator;
41 + rc = phy_init(hpriv->phy);
45 + rc = phy_power_on(hpriv->phy);
47 + phy_exit(hpriv->phy);
55 + ahci_platform_disable_clks(hpriv);
58 if (hpriv->target_pwr)
59 regulator_disable(hpriv->target_pwr);
60 @@ -186,14 +204,20 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_r
62 * This function disables all ahci_platform managed resources in
63 * the following order:
64 - * 1) Clocks (through ahci_platform_disable_clks)
67 + * 2) Clocks (through ahci_platform_disable_clks)
73 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
76 + phy_power_off(hpriv->phy);
77 + phy_exit(hpriv->phy);
80 ahci_platform_disable_clks(hpriv);
82 if (hpriv->target_pwr)
83 @@ -206,6 +230,11 @@ static void ahci_platform_put_resources(
84 struct ahci_host_priv *hpriv = res;
87 + if (hpriv->got_runtime_pm) {
88 + pm_runtime_put_sync(dev);
89 + pm_runtime_disable(dev);
92 for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
93 clk_put(hpriv->clks[c]);
95 @@ -222,6 +251,7 @@ static void ahci_platform_put_resources(
96 * 2) regulator for controlling the targets power (optional)
97 * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
98 * or for non devicetree enabled platforms a single clock
103 @@ -283,6 +313,29 @@ struct ahci_host_priv *ahci_platform_get
104 hpriv->clks[i] = clk;
107 + hpriv->phy = devm_phy_get(dev, "sata-phy");
108 + if (IS_ERR(hpriv->phy)) {
109 + rc = PTR_ERR(hpriv->phy);
113 + /* continue normally */
117 + case -EPROBE_DEFER:
121 + dev_err(dev, "couldn't get sata-phy\n");
126 + pm_runtime_enable(dev);
127 + pm_runtime_get_sync(dev);
128 + hpriv->got_runtime_pm = true;
130 devres_remove_group(dev, NULL);
133 @@ -592,6 +645,11 @@ int ahci_platform_resume(struct device *
135 goto disable_resources;
137 + /* We resumed so update PM runtime state */
138 + pm_runtime_disable(dev);
139 + pm_runtime_set_active(dev);
140 + pm_runtime_enable(dev);
145 @@ -609,6 +667,7 @@ static const struct of_device_id ahci_of
146 { .compatible = "snps,spear-ahci", },
147 { .compatible = "snps,exynos5440-ahci", },
148 { .compatible = "ibm,476gtr-ahci", },
149 + { .compatible = "snps,dwc-ahci", },
152 MODULE_DEVICE_TABLE(of, ahci_of_match);
153 --- a/drivers/ata/ahci.h
154 +++ b/drivers/ata/ahci.h
157 #include <linux/clk.h>
158 #include <linux/libata.h>
159 +#include <linux/phy/phy.h>
160 #include <linux/regulator/consumer.h>
162 /* Enclosure Management Control */
163 @@ -324,8 +325,10 @@ struct ahci_host_priv {
164 u32 em_loc; /* enclosure management location */
165 u32 em_buf_sz; /* EM buffer size in byte */
166 u32 em_msg_type; /* EM message type */
167 + bool got_runtime_pm; /* Did we do pm_runtime_get? */
168 struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
169 struct regulator *target_pwr; /* Optional */
170 + struct phy *phy; /* If platform uses phy */
171 void *plat_data; /* Other platform data */
173 * Optional ahci_start_engine override, if not set this gets set to the
174 --- a/drivers/ata/ahci_sunxi.c
175 +++ b/drivers/ata/ahci_sunxi.c
176 @@ -90,7 +90,7 @@ static int ahci_sunxi_phy_init(struct de
178 /* This magic is from the original code */
179 writel(0, reg_base + AHCI_RWCR);
183 sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(19));
184 sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
185 @@ -105,7 +105,7 @@ static int ahci_sunxi_phy_init(struct de
186 (0x7 << 20), (0x3 << 20));
187 sunxi_clrsetbits(reg_base + AHCI_PHYCS2R,
188 (0x1f << 5), (0x19 << 5));
192 sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19));
194 @@ -137,7 +137,7 @@ static int ahci_sunxi_phy_init(struct de
201 writel(0x7, reg_base + AHCI_RWCR);