aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorPeter Griffin <peter.griffin@linaro.org>2015-04-20 09:41:05 -0400
committerTejun Heo <tj@kernel.org>2015-04-20 13:36:38 -0400
commite0e2674b92056c24c69940d5f405ea4aef5e4010 (patch)
treeab0213bd4d1259819f640373d15ea430f11b5e31 /drivers/ata
parent5df07b74f671d1dfc1d81c3e791c335183cfc515 (diff)
ata: ahci_st: fixup layering violations / drvdata errors
Brian noticed while working on another SATA driver that uses libahci_platform, an error in this driver; it tries to the the driver data for its device, while libata also thinks it can set the driver data. See: ahci_platform_init_host() -> ata_host_alloc_pinfo() -> ata_host_alloc() -> dev_set_drvdata() So instead of sticking the IP-specific platform data into drvdata, let's use the plat_data variable that is reserved for this use. Addtionally plat_data isn't set until ahci_platform_init_host() has been called further down in probe(). So re-work the st_ahci_probe_resets and st_ahci_deassert_resets functions to take ahci_host_priv *hpriv as a parameter. Signed-off-by: Peter Griffin <peter.griffin@linaro.org> Suggested-by: Brian Norris <computersforpeace@gmail.com> Cc: Srinivas Kandagatla <srinivas.kandagatla@gmail.com> Cc: Maxime Coquelin <maxime.coquelin@st.com> Cc: Patrice Chotard <patrice.chotard@st.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci_st.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c
index ea0ff005b86c..8ff428fe8e0f 100644
--- a/drivers/ata/ahci_st.c
+++ b/drivers/ata/ahci_st.c
@@ -37,7 +37,6 @@ struct st_ahci_drv_data {
37 struct reset_control *pwr; 37 struct reset_control *pwr;
38 struct reset_control *sw_rst; 38 struct reset_control *sw_rst;
39 struct reset_control *pwr_rst; 39 struct reset_control *pwr_rst;
40 struct ahci_host_priv *hpriv;
41}; 40};
42 41
43static void st_ahci_configure_oob(void __iomem *mmio) 42static void st_ahci_configure_oob(void __iomem *mmio)
@@ -55,9 +54,10 @@ static void st_ahci_configure_oob(void __iomem *mmio)
55 writel(new_val, mmio + ST_AHCI_OOBR); 54 writel(new_val, mmio + ST_AHCI_OOBR);
56} 55}
57 56
58static int st_ahci_deassert_resets(struct device *dev) 57static int st_ahci_deassert_resets(struct ahci_host_priv *hpriv,
58 struct device *dev)
59{ 59{
60 struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); 60 struct st_ahci_drv_data *drv_data = hpriv->plat_data;
61 int err; 61 int err;
62 62
63 if (drv_data->pwr) { 63 if (drv_data->pwr) {
@@ -90,8 +90,8 @@ static int st_ahci_deassert_resets(struct device *dev)
90static void st_ahci_host_stop(struct ata_host *host) 90static void st_ahci_host_stop(struct ata_host *host)
91{ 91{
92 struct ahci_host_priv *hpriv = host->private_data; 92 struct ahci_host_priv *hpriv = host->private_data;
93 struct st_ahci_drv_data *drv_data = hpriv->plat_data;
93 struct device *dev = host->dev; 94 struct device *dev = host->dev;
94 struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
95 int err; 95 int err;
96 96
97 if (drv_data->pwr) { 97 if (drv_data->pwr) {
@@ -103,29 +103,30 @@ static void st_ahci_host_stop(struct ata_host *host)
103 ahci_platform_disable_resources(hpriv); 103 ahci_platform_disable_resources(hpriv);
104} 104}
105 105
106static int st_ahci_probe_resets(struct platform_device *pdev) 106static int st_ahci_probe_resets(struct ahci_host_priv *hpriv,
107 struct device *dev)
107{ 108{
108 struct st_ahci_drv_data *drv_data = platform_get_drvdata(pdev); 109 struct st_ahci_drv_data *drv_data = hpriv->plat_data;
109 110
110 drv_data->pwr = devm_reset_control_get(&pdev->dev, "pwr-dwn"); 111 drv_data->pwr = devm_reset_control_get(dev, "pwr-dwn");
111 if (IS_ERR(drv_data->pwr)) { 112 if (IS_ERR(drv_data->pwr)) {
112 dev_info(&pdev->dev, "power reset control not defined\n"); 113 dev_info(dev, "power reset control not defined\n");
113 drv_data->pwr = NULL; 114 drv_data->pwr = NULL;
114 } 115 }
115 116
116 drv_data->sw_rst = devm_reset_control_get(&pdev->dev, "sw-rst"); 117 drv_data->sw_rst = devm_reset_control_get(dev, "sw-rst");
117 if (IS_ERR(drv_data->sw_rst)) { 118 if (IS_ERR(drv_data->sw_rst)) {
118 dev_info(&pdev->dev, "soft reset control not defined\n"); 119 dev_info(dev, "soft reset control not defined\n");
119 drv_data->sw_rst = NULL; 120 drv_data->sw_rst = NULL;
120 } 121 }
121 122
122 drv_data->pwr_rst = devm_reset_control_get(&pdev->dev, "pwr-rst"); 123 drv_data->pwr_rst = devm_reset_control_get(dev, "pwr-rst");
123 if (IS_ERR(drv_data->pwr_rst)) { 124 if (IS_ERR(drv_data->pwr_rst)) {
124 dev_dbg(&pdev->dev, "power soft reset control not defined\n"); 125 dev_dbg(dev, "power soft reset control not defined\n");
125 drv_data->pwr_rst = NULL; 126 drv_data->pwr_rst = NULL;
126 } 127 }
127 128
128 return st_ahci_deassert_resets(&pdev->dev); 129 return st_ahci_deassert_resets(hpriv, dev);
129} 130}
130 131
131static struct ata_port_operations st_ahci_port_ops = { 132static struct ata_port_operations st_ahci_port_ops = {
@@ -154,15 +155,12 @@ static int st_ahci_probe(struct platform_device *pdev)
154 if (!drv_data) 155 if (!drv_data)
155 return -ENOMEM; 156 return -ENOMEM;
156 157
157 platform_set_drvdata(pdev, drv_data);
158
159 hpriv = ahci_platform_get_resources(pdev); 158 hpriv = ahci_platform_get_resources(pdev);
160 if (IS_ERR(hpriv)) 159 if (IS_ERR(hpriv))
161 return PTR_ERR(hpriv); 160 return PTR_ERR(hpriv);
161 hpriv->plat_data = drv_data;
162 162
163 drv_data->hpriv = hpriv; 163 err = st_ahci_probe_resets(hpriv, &pdev->dev);
164
165 err = st_ahci_probe_resets(pdev);
166 if (err) 164 if (err)
167 return err; 165 return err;
168 166
@@ -170,7 +168,7 @@ static int st_ahci_probe(struct platform_device *pdev)
170 if (err) 168 if (err)
171 return err; 169 return err;
172 170
173 st_ahci_configure_oob(drv_data->hpriv->mmio); 171 st_ahci_configure_oob(hpriv->mmio);
174 172
175 err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, 173 err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
176 &ahci_platform_sht); 174 &ahci_platform_sht);
@@ -185,8 +183,9 @@ static int st_ahci_probe(struct platform_device *pdev)
185#ifdef CONFIG_PM_SLEEP 183#ifdef CONFIG_PM_SLEEP
186static int st_ahci_suspend(struct device *dev) 184static int st_ahci_suspend(struct device *dev)
187{ 185{
188 struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); 186 struct ata_host *host = dev_get_drvdata(dev);
189 struct ahci_host_priv *hpriv = drv_data->hpriv; 187 struct ahci_host_priv *hpriv = host->private_data;
188 struct st_ahci_drv_data *drv_data = hpriv->plat_data;
190 int err; 189 int err;
191 190
192 err = ahci_platform_suspend_host(dev); 191 err = ahci_platform_suspend_host(dev);
@@ -208,21 +207,21 @@ static int st_ahci_suspend(struct device *dev)
208 207
209static int st_ahci_resume(struct device *dev) 208static int st_ahci_resume(struct device *dev)
210{ 209{
211 struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev); 210 struct ata_host *host = dev_get_drvdata(dev);
212 struct ahci_host_priv *hpriv = drv_data->hpriv; 211 struct ahci_host_priv *hpriv = host->private_data;
213 int err; 212 int err;
214 213
215 err = ahci_platform_enable_resources(hpriv); 214 err = ahci_platform_enable_resources(hpriv);
216 if (err) 215 if (err)
217 return err; 216 return err;
218 217
219 err = st_ahci_deassert_resets(dev); 218 err = st_ahci_deassert_resets(hpriv, dev);
220 if (err) { 219 if (err) {
221 ahci_platform_disable_resources(hpriv); 220 ahci_platform_disable_resources(hpriv);
222 return err; 221 return err;
223 } 222 }
224 223
225 st_ahci_configure_oob(drv_data->hpriv->mmio); 224 st_ahci_configure_oob(hpriv->mmio);
226 225
227 return ahci_platform_resume_host(dev); 226 return ahci_platform_resume_host(dev);
228} 227}