kernel: update 3.14 to 3.14.18
[openwrt/staging/luka.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 */