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
7 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
9 drivers/ata/ahci_platform.c | 112 ++++++++++++++++++++++++++++--------------
10 include/linux/ahci_platform.h | 2 +
11 2 files changed, 77 insertions(+), 37 deletions(-)
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)
19 EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
22 + * ahci_platform_enable_resources - Enable platform resources
23 + * @hpriv: host private area to store config values
25 + * This function enables all ahci_platform managed resources in
26 + * the following order:
28 + * 2) Clocks (through ahci_platform_enable_clks)
30 + * If resource enabling fails at any point the previous enabled
31 + * resources are disabled in reverse order.
37 + * 0 on success otherwise a negative error code
39 +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
43 + if (hpriv->target_pwr) {
44 + rc = regulator_enable(hpriv->target_pwr);
49 + rc = ahci_platform_enable_clks(hpriv);
51 + goto disable_regulator;
56 + if (hpriv->target_pwr)
57 + regulator_disable(hpriv->target_pwr);
60 +EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
63 + * ahci_platform_disable_resources - Disable platform resources
64 + * @hpriv: host private area to store config values
66 + * This function disables all ahci_platform managed resources in
67 + * the following order:
68 + * 1) Clocks (through ahci_platform_disable_clks)
74 +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
76 + ahci_platform_disable_clks(hpriv);
78 + if (hpriv->target_pwr)
79 + regulator_disable(hpriv->target_pwr);
81 +EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
83 static void ahci_put_clks(struct ahci_host_priv *hpriv)
86 @@ -221,15 +283,9 @@ static int ahci_probe(struct platform_device *pdev)
90 - if (hpriv->target_pwr) {
91 - rc = regulator_enable(hpriv->target_pwr);
96 - rc = ahci_enable_clks(dev, hpriv);
97 + rc = ahci_platform_enable_resources(hpriv);
99 - goto disable_regulator;
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);
108 - goto disable_unprepare_clk;
109 + goto disable_resources;
112 ahci_save_initial_config(dev, hpriv,
113 @@ -310,11 +366,8 @@ static int ahci_probe(struct platform_device *pdev)
115 if (pdata && pdata->exit)
117 -disable_unprepare_clk:
118 - ahci_disable_clks(hpriv);
120 - if (hpriv->target_pwr)
121 - regulator_disable(hpriv->target_pwr);
123 + ahci_platform_disable_resources(hpriv);
125 ahci_put_clks(hpriv);
127 @@ -329,11 +382,8 @@ static void ahci_host_stop(struct ata_host *host)
128 if (pdata && pdata->exit)
131 - ahci_disable_clks(hpriv);
132 + ahci_platform_disable_resources(hpriv);
133 ahci_put_clks(hpriv);
135 - if (hpriv->target_pwr)
136 - regulator_disable(hpriv->target_pwr);
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);
144 - ahci_disable_clks(hpriv);
146 - if (hpriv->target_pwr)
147 - regulator_disable(hpriv->target_pwr);
148 + ahci_platform_disable_resources(hpriv);
152 @@ -383,26 +430,20 @@ static int ahci_resume(struct device *dev)
153 struct ahci_host_priv *hpriv = host->private_data;
156 - if (hpriv->target_pwr) {
157 - rc = regulator_enable(hpriv->target_pwr);
162 - rc = ahci_enable_clks(dev, hpriv);
163 + rc = ahci_platform_enable_resources(hpriv);
165 - goto disable_regulator;
168 if (pdata && pdata->resume) {
169 rc = pdata->resume(dev);
171 - goto disable_unprepare_clk;
172 + goto disable_resources;
175 if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
176 rc = ahci_reset_controller(host);
178 - goto disable_unprepare_clk;
179 + goto disable_resources;
181 ahci_init_controller(host);
183 @@ -411,11 +452,8 @@ static int ahci_resume(struct device *dev)
187 -disable_unprepare_clk:
188 - ahci_disable_clks(hpriv);
190 - if (hpriv->target_pwr)
191 - regulator_disable(hpriv->target_pwr);
193 + ahci_platform_disable_resources(hpriv);
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 {
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);
208 #endif /* _AHCI_PLATFORM_H */