ad6adbebf5d92b53f42da1c69867202bc4f42424
[15.05/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 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