Skip to content

Commit 26c8404

Browse files
Radhey Shyam Pandeyfloatious
authored andcommitted
ata: ahci_ceva: fix error handling for Xilinx GT PHY support
Platform clock and phy error resources are not cleaned up in Xilinx GT PHY error path. To fix introduce the function ceva_ahci_platform_enable_resources() which is a customized version of ahci_platform_enable_resources() and inline with SATA IP programming sequence it does: - Assert SATA reset - Program PS GTR phy - Bring SATA by de-asserting the reset - Wait for GT lane PLL to be locked ceva_ahci_platform_enable_resources() is also used in the resume path as the same SATA programming sequence (as in probe) should be followed. Also cleanup the mixed usage of ahci_platform_enable_resources() and custom implementation in the probe function as both are not required. Fixes: 9a9d3ab ("ata: ahci: ceva: Update the driver to support xilinx GT phy") Signed-off-by: Radhey Shyam Pandey <[email protected]> Reviewed-by: Damien Le Moal <[email protected]> Signed-off-by: Niklas Cassel <[email protected]>
1 parent 9815e39 commit 26c8404

File tree

1 file changed

+79
-46
lines changed

1 file changed

+79
-46
lines changed

drivers/ata/ahci_ceva.c

Lines changed: 79 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ struct ceva_ahci_priv {
8888
u32 axicc;
8989
bool is_cci_enabled;
9090
int flags;
91-
struct reset_control *rst;
9291
};
9392

9493
static unsigned int ceva_ahci_read_id(struct ata_device *dev,
@@ -189,6 +188,60 @@ static const struct scsi_host_template ahci_platform_sht = {
189188
AHCI_SHT(DRV_NAME),
190189
};
191190

191+
static int ceva_ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
192+
{
193+
int rc, i;
194+
195+
rc = ahci_platform_enable_regulators(hpriv);
196+
if (rc)
197+
return rc;
198+
199+
rc = ahci_platform_enable_clks(hpriv);
200+
if (rc)
201+
goto disable_regulator;
202+
203+
/* Assert the controller reset */
204+
rc = ahci_platform_assert_rsts(hpriv);
205+
if (rc)
206+
goto disable_clks;
207+
208+
for (i = 0; i < hpriv->nports; i++) {
209+
rc = phy_init(hpriv->phys[i]);
210+
if (rc)
211+
goto disable_rsts;
212+
}
213+
214+
/* De-assert the controller reset */
215+
ahci_platform_deassert_rsts(hpriv);
216+
217+
for (i = 0; i < hpriv->nports; i++) {
218+
rc = phy_power_on(hpriv->phys[i]);
219+
if (rc) {
220+
phy_exit(hpriv->phys[i]);
221+
goto disable_phys;
222+
}
223+
}
224+
225+
return 0;
226+
227+
disable_rsts:
228+
ahci_platform_deassert_rsts(hpriv);
229+
230+
disable_phys:
231+
while (--i >= 0) {
232+
phy_power_off(hpriv->phys[i]);
233+
phy_exit(hpriv->phys[i]);
234+
}
235+
236+
disable_clks:
237+
ahci_platform_disable_clks(hpriv);
238+
239+
disable_regulator:
240+
ahci_platform_disable_regulators(hpriv);
241+
242+
return rc;
243+
}
244+
192245
static int ceva_ahci_probe(struct platform_device *pdev)
193246
{
194247
struct device_node *np = pdev->dev.of_node;
@@ -203,47 +256,19 @@ static int ceva_ahci_probe(struct platform_device *pdev)
203256
return -ENOMEM;
204257

205258
cevapriv->ahci_pdev = pdev;
206-
207-
cevapriv->rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
208-
NULL);
209-
if (IS_ERR(cevapriv->rst))
210-
dev_err_probe(&pdev->dev, PTR_ERR(cevapriv->rst),
211-
"failed to get reset\n");
212-
213259
hpriv = ahci_platform_get_resources(pdev, 0);
214260
if (IS_ERR(hpriv))
215261
return PTR_ERR(hpriv);
216262

217-
if (!cevapriv->rst) {
218-
rc = ahci_platform_enable_resources(hpriv);
219-
if (rc)
220-
return rc;
221-
} else {
222-
int i;
263+
hpriv->rsts = devm_reset_control_get_optional_exclusive(&pdev->dev,
264+
NULL);
265+
if (IS_ERR(hpriv->rsts))
266+
return dev_err_probe(&pdev->dev, PTR_ERR(hpriv->rsts),
267+
"failed to get reset\n");
223268

224-
rc = ahci_platform_enable_clks(hpriv);
225-
if (rc)
226-
return rc;
227-
/* Assert the controller reset */
228-
reset_control_assert(cevapriv->rst);
229-
230-
for (i = 0; i < hpriv->nports; i++) {
231-
rc = phy_init(hpriv->phys[i]);
232-
if (rc)
233-
return rc;
234-
}
235-
236-
/* De-assert the controller reset */
237-
reset_control_deassert(cevapriv->rst);
238-
239-
for (i = 0; i < hpriv->nports; i++) {
240-
rc = phy_power_on(hpriv->phys[i]);
241-
if (rc) {
242-
phy_exit(hpriv->phys[i]);
243-
return rc;
244-
}
245-
}
246-
}
269+
rc = ceva_ahci_platform_enable_resources(hpriv);
270+
if (rc)
271+
return rc;
247272

248273
if (of_property_read_bool(np, "ceva,broken-gen2"))
249274
cevapriv->flags = CEVA_FLAG_BROKEN_GEN2;
@@ -252,52 +277,60 @@ static int ceva_ahci_probe(struct platform_device *pdev)
252277
if (of_property_read_u8_array(np, "ceva,p0-cominit-params",
253278
(u8 *)&cevapriv->pp2c[0], 4) < 0) {
254279
dev_warn(dev, "ceva,p0-cominit-params property not defined\n");
255-
return -EINVAL;
280+
rc = -EINVAL;
281+
goto disable_resources;
256282
}
257283

258284
if (of_property_read_u8_array(np, "ceva,p1-cominit-params",
259285
(u8 *)&cevapriv->pp2c[1], 4) < 0) {
260286
dev_warn(dev, "ceva,p1-cominit-params property not defined\n");
261-
return -EINVAL;
287+
rc = -EINVAL;
288+
goto disable_resources;
262289
}
263290

264291
/* Read OOB timing value for COMWAKE from device-tree*/
265292
if (of_property_read_u8_array(np, "ceva,p0-comwake-params",
266293
(u8 *)&cevapriv->pp3c[0], 4) < 0) {
267294
dev_warn(dev, "ceva,p0-comwake-params property not defined\n");
268-
return -EINVAL;
295+
rc = -EINVAL;
296+
goto disable_resources;
269297
}
270298

271299
if (of_property_read_u8_array(np, "ceva,p1-comwake-params",
272300
(u8 *)&cevapriv->pp3c[1], 4) < 0) {
273301
dev_warn(dev, "ceva,p1-comwake-params property not defined\n");
274-
return -EINVAL;
302+
rc = -EINVAL;
303+
goto disable_resources;
275304
}
276305

277306
/* Read phy BURST timing value from device-tree */
278307
if (of_property_read_u8_array(np, "ceva,p0-burst-params",
279308
(u8 *)&cevapriv->pp4c[0], 4) < 0) {
280309
dev_warn(dev, "ceva,p0-burst-params property not defined\n");
281-
return -EINVAL;
310+
rc = -EINVAL;
311+
goto disable_resources;
282312
}
283313

284314
if (of_property_read_u8_array(np, "ceva,p1-burst-params",
285315
(u8 *)&cevapriv->pp4c[1], 4) < 0) {
286316
dev_warn(dev, "ceva,p1-burst-params property not defined\n");
287-
return -EINVAL;
317+
rc = -EINVAL;
318+
goto disable_resources;
288319
}
289320

290321
/* Read phy RETRY interval timing value from device-tree */
291322
if (of_property_read_u16_array(np, "ceva,p0-retry-params",
292323
(u16 *)&cevapriv->pp5c[0], 2) < 0) {
293324
dev_warn(dev, "ceva,p0-retry-params property not defined\n");
294-
return -EINVAL;
325+
rc = -EINVAL;
326+
goto disable_resources;
295327
}
296328

297329
if (of_property_read_u16_array(np, "ceva,p1-retry-params",
298330
(u16 *)&cevapriv->pp5c[1], 2) < 0) {
299331
dev_warn(dev, "ceva,p1-retry-params property not defined\n");
300-
return -EINVAL;
332+
rc = -EINVAL;
333+
goto disable_resources;
301334
}
302335

303336
/*
@@ -335,7 +368,7 @@ static int __maybe_unused ceva_ahci_resume(struct device *dev)
335368
struct ahci_host_priv *hpriv = host->private_data;
336369
int rc;
337370

338-
rc = ahci_platform_enable_resources(hpriv);
371+
rc = ceva_ahci_platform_enable_resources(hpriv);
339372
if (rc)
340373
return rc;
341374

0 commit comments

Comments
 (0)