sunxi: driver refresh for 3.13
[openwrt.git] / target / linux / sunxi / patches-3.13 / 160-7-ahci-platform-add-resource-helpers.patch
1 From 05d5a60ae336c122e478cc002afccc880d462b3b Mon Sep 17 00:00:00 2001
2 From: Hans de Goede <hdegoede@redhat.com>
3 Date: Mon, 20 Jan 2014 14:54:40 +0100
4 Subject: [PATCH] ahci-platform: Add enable_ / disable_resources helper
5  functions
6
7 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
8 ---
9  drivers/ata/ahci_platform.c   | 112 ++++++++++++++++++++++++++++--------------
10  include/linux/ahci_platform.h |   2 +
11  2 files changed, 77 insertions(+), 37 deletions(-)
12
13 diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
14 index 907c076..6ebbc17 100644
15 --- a/drivers/ata/ahci_platform.c
16 +++ b/drivers/ata/ahci_platform.c
17 @@ -139,6 +139,68 @@ void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
18  }
19  EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
20  
21 +/**
22 + *     ahci_platform_enable_resources - Enable platform resources
23 + *     @hpriv: host private area to store config values
24 + *
25 + *     This function enables all ahci_platform managed resources in
26 + *     the following order:
27 + *     1) Regulator
28 + *     2) Clocks (through ahci_platform_enable_clks)
29 + *
30 + *     If resource enabling fails at any point the previous enabled
31 + *     resources are disabled in reverse order.
32 + *
33 + *     LOCKING:
34 + *     None.
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
67 + *     the following order:
68 + *     1) Clocks (through ahci_platform_disable_clks)
69 + *     2) Regulator
70 + *
71 + *     LOCKING:
72 + *     None.
73 + */
74 +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
75 +{
76 +       ahci_platform_disable_clks(hpriv);
77 +
78 +       if (hpriv->target_pwr)
79 +               regulator_disable(hpriv->target_pwr);
80 +}
81 +EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
82 +
83  static void ahci_put_clks(struct ahci_host_priv *hpriv)
84  {
85         int c;
86 @@ -221,15 +283,9 @@ static int ahci_probe(struct platform_device *pdev)
87                 hpriv->clks[i] = clk;
88         }
89  
90 -       if (hpriv->target_pwr) {
91 -               rc = regulator_enable(hpriv->target_pwr);
92 -               if (rc)
93 -                       goto free_clk;
94 -       }
95 -
96 -       rc = ahci_enable_clks(dev, hpriv);
97 +       rc = ahci_platform_enable_resources(hpriv);
98         if (rc)
99 -               goto disable_regulator;
100 +               goto free_clk;
101  
102         /*
103          * Some platforms might need to prepare for mmio region access,
104 @@ -240,7 +296,7 @@ static int ahci_probe(struct platform_device *pdev)
105         if (pdata && pdata->init) {
106                 rc = pdata->init(dev, hpriv->mmio);
107                 if (rc)
108 -                       goto disable_unprepare_clk;
109 +                       goto disable_resources;
110         }
111  
112         ahci_save_initial_config(dev, hpriv,
113 @@ -310,11 +366,8 @@ static int ahci_probe(struct platform_device *pdev)
114  pdata_exit:
115         if (pdata && pdata->exit)
116                 pdata->exit(dev);
117 -disable_unprepare_clk:
118 -       ahci_disable_clks(hpriv);
119 -disable_regulator:
120 -       if (hpriv->target_pwr)
121 -               regulator_disable(hpriv->target_pwr);
122 +disable_resources:
123 +       ahci_platform_disable_resources(hpriv);
124  free_clk:
125         ahci_put_clks(hpriv);
126         return rc;
127 @@ -329,11 +382,8 @@ static void ahci_host_stop(struct ata_host *host)
128         if (pdata && pdata->exit)
129                 pdata->exit(dev);
130  
131 -       ahci_disable_clks(hpriv);
132 +       ahci_platform_disable_resources(hpriv);
133         ahci_put_clks(hpriv);
134 -
135 -       if (hpriv->target_pwr)
136 -               regulator_disable(hpriv->target_pwr);
137  }
138  
139  #ifdef CONFIG_PM_SLEEP
140 @@ -368,10 +418,7 @@ static int ahci_suspend(struct device *dev)
141         if (pdata && pdata->suspend)
142                 return pdata->suspend(dev);
143  
144 -       ahci_disable_clks(hpriv);
145 -
146 -       if (hpriv->target_pwr)
147 -               regulator_disable(hpriv->target_pwr);
148 +       ahci_platform_disable_resources(hpriv);
149  
150         return 0;
151  }
152 @@ -383,26 +430,20 @@ static int ahci_resume(struct device *dev)
153         struct ahci_host_priv *hpriv = host->private_data;
154         int rc;
155  
156 -       if (hpriv->target_pwr) {
157 -               rc = regulator_enable(hpriv->target_pwr);
158 -               if (rc)
159 -                       return rc;
160 -       }
161 -
162 -       rc = ahci_enable_clks(dev, hpriv);
163 +       rc = ahci_platform_enable_resources(hpriv);
164         if (rc)
165 -               goto disable_regulator;
166 +               return rc;
167  
168         if (pdata && pdata->resume) {
169                 rc = pdata->resume(dev);
170                 if (rc)
171 -                       goto disable_unprepare_clk;
172 +                       goto disable_resources;
173         }
174  
175         if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
176                 rc = ahci_reset_controller(host);
177                 if (rc)
178 -                       goto disable_unprepare_clk;
179 +                       goto disable_resources;
180  
181                 ahci_init_controller(host);
182         }
183 @@ -411,11 +452,8 @@ static int ahci_resume(struct device *dev)
184  
185         return 0;
186  
187 -disable_unprepare_clk:
188 -       ahci_disable_clks(hpriv);
189 -disable_regulator:
190 -       if (hpriv->target_pwr)
191 -               regulator_disable(hpriv->target_pwr);
192 +disable_resources:
193 +       ahci_platform_disable_resources(hpriv);
194  
195         return rc;
196  }
197 diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
198 index 769d065..b674b01 100644
199 --- a/include/linux/ahci_platform.h
200 +++ b/include/linux/ahci_platform.h
201 @@ -33,5 +33,7 @@ struct ahci_platform_data {
202  
203  int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
204  void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
205 +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
206 +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
207  
208  #endif /* _AHCI_PLATFORM_H */
209 -- 
210 1.8.5.5
211