kernel: update 3.14 to 3.14.18
[openwrt.git] / target / linux / sunxi / patches-3.14 / 192-ahci-platform-changes.patch
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
5  controller
6
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.
9
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>
13 ---
14  drivers/ata/ahci_platform.c | 1 +
15  1 file changed, 1 insertion(+)
16
17 --- a/drivers/ata/ahci_platform.c
18 +++ b/drivers/ata/ahci_platform.c
19 @@ -23,6 +23,8 @@
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>
25  #include "ahci.h"
26  
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:
30   *     1) Regulator
31   *     2) Clocks (through ahci_platform_enable_clks)
32 + *     3) Phy
33   *
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
37         if (rc)
38                 goto disable_regulator;
39  
40 +       if (hpriv->phy) {
41 +               rc = phy_init(hpriv->phy);
42 +               if (rc)
43 +                       goto disable_clks;
44 +
45 +               rc = phy_power_on(hpriv->phy);
46 +               if (rc) {
47 +                       phy_exit(hpriv->phy);
48 +                       goto disable_clks;
49 +               }
50 +       }
51 +
52         return 0;
53  
54 +disable_clks:
55 +       ahci_platform_disable_clks(hpriv);
56 +
57  disable_regulator:
58         if (hpriv->target_pwr)
59                 regulator_disable(hpriv->target_pwr);
60 @@ -186,14 +204,20 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_r
61   *
62   *     This function disables all ahci_platform managed resources in
63   *     the following order:
64 - *     1) Clocks (through ahci_platform_disable_clks)
65 - *     2) Regulator
66 + *     1) Phy
67 + *     2) Clocks (through ahci_platform_disable_clks)
68 + *     3) Regulator
69   *
70   *     LOCKING:
71   *     None.
72   */
73  void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
74  {
75 +       if (hpriv->phy) {
76 +               phy_power_off(hpriv->phy);
77 +               phy_exit(hpriv->phy);
78 +       }
79 +
80         ahci_platform_disable_clks(hpriv);
81  
82         if (hpriv->target_pwr)
83 @@ -206,6 +230,11 @@ static void ahci_platform_put_resources(
84         struct ahci_host_priv *hpriv = res;
85         int c;
86  
87 +       if (hpriv->got_runtime_pm) {
88 +               pm_runtime_put_sync(dev);
89 +               pm_runtime_disable(dev);
90 +       }
91 +
92         for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
93                 clk_put(hpriv->clks[c]);
94  }
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
99 + *     4) phy (optional)
100   *
101   *     LOCKING:
102   *     None.
103 @@ -283,6 +313,29 @@ struct ahci_host_priv *ahci_platform_get
104                 hpriv->clks[i] = clk;
105         }
106  
107 +       hpriv->phy = devm_phy_get(dev, "sata-phy");
108 +       if (IS_ERR(hpriv->phy)) {
109 +               rc = PTR_ERR(hpriv->phy);
110 +               switch (rc) {
111 +               case -ENODEV:
112 +               case -ENOSYS:
113 +                       /* continue normally */
114 +                       hpriv->phy = NULL;
115 +                       break;
116 +
117 +               case -EPROBE_DEFER:
118 +                       goto err_out;
119 +
120 +               default:
121 +                       dev_err(dev, "couldn't get sata-phy\n");
122 +                       goto err_out;
123 +               }
124 +       }
125 +
126 +       pm_runtime_enable(dev);
127 +       pm_runtime_get_sync(dev);
128 +       hpriv->got_runtime_pm = true;
129 +
130         devres_remove_group(dev, NULL);
131         return hpriv;
132  
133 @@ -592,6 +645,11 @@ int ahci_platform_resume(struct device *
134         if (rc)
135                 goto disable_resources;
136  
137 +       /* We resumed so update PM runtime state */
138 +       pm_runtime_disable(dev);
139 +       pm_runtime_set_active(dev);
140 +       pm_runtime_enable(dev);
141 +
142         return 0;
143  
144  disable_resources:
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", },
150         {},
151  };
152  MODULE_DEVICE_TABLE(of, ahci_of_match);
153 --- a/drivers/ata/ahci.h
154 +++ b/drivers/ata/ahci.h
155 @@ -37,6 +37,7 @@
156  
157  #include <linux/clk.h>
158  #include <linux/libata.h>
159 +#include <linux/phy/phy.h>
160  #include <linux/regulator/consumer.h>
161  
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 */
172         /*
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
177  
178         /* This magic is from the original code */
179         writel(0, reg_base + AHCI_RWCR);
180 -       mdelay(5);
181 +       msleep(5);
182  
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));
189 -       mdelay(5);
190 +       msleep(5);
191  
192         sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19));
193  
194 @@ -137,7 +137,7 @@ static int ahci_sunxi_phy_init(struct de
195                 udelay(1);
196         } while (1);
197  
198 -       mdelay(15);
199 +       msleep(15);
200  
201         writel(0x7, reg_base + AHCI_RWCR);
202