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