kernel: update 3.14 to 3.14.18
[openwrt.git] / target / linux / ipq806x / patches / 0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch
1 From 3b2df84624b38362cb84c2d4c6d1d3540c5069d3 Mon Sep 17 00:00:00 2001
2 From: Hans de Goede <hdegoede@redhat.com>
3 Date: Sat, 22 Feb 2014 16:53:33 +0100
4 Subject: [PATCH 112/182] ahci-platform: Add enable_ / disable_resources
5  helper functions
6
7 tj: Minor comment formatting updates.
8
9 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
10 Signed-off-by: Tejun Heo <tj@kernel.org>
11 ---
12  drivers/ata/ahci_platform.c   |  106 +++++++++++++++++++++++++++--------------
13  include/linux/ahci_platform.h |    2 +
14  2 files changed, 71 insertions(+), 37 deletions(-)
15
16 --- a/drivers/ata/ahci_platform.c
17 +++ b/drivers/ata/ahci_platform.c
18 @@ -133,6 +133,62 @@ void ahci_platform_disable_clks(struct a
19  }
20  EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
21  
22 +/**
23 + * ahci_platform_enable_resources - Enable platform resources
24 + * @hpriv: host private area to store config values
25 + *
26 + * This function enables all ahci_platform managed resources in the
27 + * following order:
28 + * 1) Regulator
29 + * 2) Clocks (through ahci_platform_enable_clks)
30 + *
31 + * If resource enabling fails at any point the previous enabled resources
32 + * are disabled in reverse order.
33 + *
34 + * RETURNS:
35 + * 0 on success otherwise a negative error code
36 + */
37 +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
38 +{
39 +       int rc;
40 +
41 +       if (hpriv->target_pwr) {
42 +               rc = regulator_enable(hpriv->target_pwr);
43 +               if (rc)
44 +                       return rc;
45 +       }
46 +
47 +       rc = ahci_platform_enable_clks(hpriv);
48 +       if (rc)
49 +               goto disable_regulator;
50 +
51 +       return 0;
52 +
53 +disable_regulator:
54 +       if (hpriv->target_pwr)
55 +               regulator_disable(hpriv->target_pwr);
56 +       return rc;
57 +}
58 +EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
59 +
60 +/**
61 + * ahci_platform_disable_resources - Disable platform resources
62 + * @hpriv: host private area to store config values
63 + *
64 + * This function disables all ahci_platform managed resources in the
65 + * following order:
66 + * 1) Clocks (through ahci_platform_disable_clks)
67 + * 2) Regulator
68 + */
69 +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
70 +{
71 +       ahci_platform_disable_clks(hpriv);
72 +
73 +       if (hpriv->target_pwr)
74 +               regulator_disable(hpriv->target_pwr);
75 +}
76 +EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
77 +
78  static void ahci_put_clks(struct ahci_host_priv *hpriv)
79  {
80         int c;
81 @@ -215,15 +271,9 @@ static int ahci_probe(struct platform_de
82                 hpriv->clks[i] = clk;
83         }
84  
85 -       if (hpriv->target_pwr) {
86 -               rc = regulator_enable(hpriv->target_pwr);
87 -               if (rc)
88 -                       goto free_clk;
89 -       }
90 -
91 -       rc = ahci_enable_clks(dev, hpriv);
92 +       rc = ahci_platform_enable_resources(hpriv);
93         if (rc)
94 -               goto disable_regulator;
95 +               goto free_clk;
96  
97         /*
98          * Some platforms might need to prepare for mmio region access,
99 @@ -234,7 +284,7 @@ static int ahci_probe(struct platform_de
100         if (pdata && pdata->init) {
101                 rc = pdata->init(dev, hpriv->mmio);
102                 if (rc)
103 -                       goto disable_unprepare_clk;
104 +                       goto disable_resources;
105         }
106  
107         ahci_save_initial_config(dev, hpriv,
108 @@ -304,11 +354,8 @@ static int ahci_probe(struct platform_de
109  pdata_exit:
110         if (pdata && pdata->exit)
111                 pdata->exit(dev);
112 -disable_unprepare_clk:
113 -       ahci_disable_clks(hpriv);
114 -disable_regulator:
115 -       if (hpriv->target_pwr)
116 -               regulator_disable(hpriv->target_pwr);
117 +disable_resources:
118 +       ahci_platform_disable_resources(hpriv);
119  free_clk:
120         ahci_put_clks(hpriv);
121         return rc;
122 @@ -323,11 +370,8 @@ static void ahci_host_stop(struct ata_ho
123         if (pdata && pdata->exit)
124                 pdata->exit(dev);
125  
126 -       ahci_disable_clks(hpriv);
127 +       ahci_platform_disable_resources(hpriv);
128         ahci_put_clks(hpriv);
129 -
130 -       if (hpriv->target_pwr)
131 -               regulator_disable(hpriv->target_pwr);
132  }
133  
134  #ifdef CONFIG_PM_SLEEP
135 @@ -362,10 +406,7 @@ static int ahci_suspend(struct device *d
136         if (pdata && pdata->suspend)
137                 return pdata->suspend(dev);
138  
139 -       ahci_disable_clks(hpriv);
140 -
141 -       if (hpriv->target_pwr)
142 -               regulator_disable(hpriv->target_pwr);
143 +       ahci_platform_disable_resources(hpriv);
144  
145         return 0;
146  }
147 @@ -377,26 +418,20 @@ static int ahci_resume(struct device *de
148         struct ahci_host_priv *hpriv = host->private_data;
149         int rc;
150  
151 -       if (hpriv->target_pwr) {
152 -               rc = regulator_enable(hpriv->target_pwr);
153 -               if (rc)
154 -                       return rc;
155 -       }
156 -
157 -       rc = ahci_enable_clks(dev, hpriv);
158 +       rc = ahci_platform_enable_resources(hpriv);
159         if (rc)
160 -               goto disable_regulator;
161 +               return rc;
162  
163         if (pdata && pdata->resume) {
164                 rc = pdata->resume(dev);
165                 if (rc)
166 -                       goto disable_unprepare_clk;
167 +                       goto disable_resources;
168         }
169  
170         if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
171                 rc = ahci_reset_controller(host);
172                 if (rc)
173 -                       goto disable_unprepare_clk;
174 +                       goto disable_resources;
175  
176                 ahci_init_controller(host);
177         }
178 @@ -405,11 +440,8 @@ static int ahci_resume(struct device *de
179  
180         return 0;
181  
182 -disable_unprepare_clk:
183 -       ahci_disable_clks(hpriv);
184 -disable_regulator:
185 -       if (hpriv->target_pwr)
186 -               regulator_disable(hpriv->target_pwr);
187 +disable_resources:
188 +       ahci_platform_disable_resources(hpriv);
189  
190         return rc;
191  }
192 --- a/include/linux/ahci_platform.h
193 +++ b/include/linux/ahci_platform.h
194 @@ -33,5 +33,7 @@ struct ahci_platform_data {
195  
196  int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
197  void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
198 +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
199 +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
200  
201  #endif /* _AHCI_PLATFORM_H */