Skip to content

Commit b6d6928

Browse files
committed
Merge tag 'ata-6.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux
Pull ata fixes from Niklas Cassel: - Do not try to set a sleeping device to standby. Sleep is a deeper sleep state than standby, and needs a reset to wake up the drive. A system resume will reset the port. Sending a command other than reset to a sleeping device is not wise, as the command will timeout (Damien Le Moal) - Do not try to put a device to standby twice during system shutdown. ata_dev_power_set_standby() is currently called twice during shutdown, once after the scsi device is removed, and another when ata_pci_shutdown_one() executes. Modify ata_dev_power_set_standby() to do nothing if the device is already in standby (Damien Le Moal) - Add a quirk for ASM1064 to fixup the number of implemented ports. We probe all ports that the hardware reports to be implemented. Probing ports that are not implemented causes significantly increased boot time (Andrey Jr. Melnikov) - Fix error handling for the ahci_ceva driver. Ensure that the ahci_ceva driver does a proper cleanup of its resources in the error path (Radhey Shyam Pandey) * tag 'ata-6.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux: ata: libata-core: Do not call ata_dev_power_set_standby() twice ata: ahci_ceva: fix error handling for Xilinx GT PHY support ahci: asm1064: correct count of reported ports ata: libata-core: Do not try to set sleeping devices to standby
2 parents 9cd42be + 9cec467 commit b6d6928

File tree

3 files changed

+122
-76
lines changed

3 files changed

+122
-76
lines changed

drivers/ata/ahci.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -671,9 +671,17 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
671671
static void ahci_pci_save_initial_config(struct pci_dev *pdev,
672672
struct ahci_host_priv *hpriv)
673673
{
674-
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1166) {
675-
dev_info(&pdev->dev, "ASM1166 has only six ports\n");
676-
hpriv->saved_port_map = 0x3f;
674+
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA) {
675+
switch (pdev->device) {
676+
case 0x1166:
677+
dev_info(&pdev->dev, "ASM1166 has only six ports\n");
678+
hpriv->saved_port_map = 0x3f;
679+
break;
680+
case 0x1064:
681+
dev_info(&pdev->dev, "ASM1064 has only four ports\n");
682+
hpriv->saved_port_map = 0xf;
683+
break;
684+
}
677685
}
678686

679687
if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {

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

drivers/ata/libata-core.c

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,33 @@ bool ata_dev_power_init_tf(struct ata_device *dev, struct ata_taskfile *tf,
20012001
return true;
20022002
}
20032003

2004+
static bool ata_dev_power_is_active(struct ata_device *dev)
2005+
{
2006+
struct ata_taskfile tf;
2007+
unsigned int err_mask;
2008+
2009+
ata_tf_init(dev, &tf);
2010+
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
2011+
tf.protocol = ATA_PROT_NODATA;
2012+
tf.command = ATA_CMD_CHK_POWER;
2013+
2014+
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
2015+
if (err_mask) {
2016+
ata_dev_err(dev, "Check power mode failed (err_mask=0x%x)\n",
2017+
err_mask);
2018+
/*
2019+
* Assume we are in standby mode so that we always force a
2020+
* spinup in ata_dev_power_set_active().
2021+
*/
2022+
return false;
2023+
}
2024+
2025+
ata_dev_dbg(dev, "Power mode: 0x%02x\n", tf.nsect);
2026+
2027+
/* Active or idle */
2028+
return tf.nsect == 0xff;
2029+
}
2030+
20042031
/**
20052032
* ata_dev_power_set_standby - Set a device power mode to standby
20062033
* @dev: target device
@@ -2017,6 +2044,11 @@ void ata_dev_power_set_standby(struct ata_device *dev)
20172044
struct ata_taskfile tf;
20182045
unsigned int err_mask;
20192046

2047+
/* If the device is already sleeping or in standby, do nothing. */
2048+
if ((dev->flags & ATA_DFLAG_SLEEPING) ||
2049+
!ata_dev_power_is_active(dev))
2050+
return;
2051+
20202052
/*
20212053
* Some odd clown BIOSes issue spindown on power off (ACPI S4 or S5)
20222054
* causing some drives to spin up and down again. For these, do nothing
@@ -2042,33 +2074,6 @@ void ata_dev_power_set_standby(struct ata_device *dev)
20422074
err_mask);
20432075
}
20442076

2045-
static bool ata_dev_power_is_active(struct ata_device *dev)
2046-
{
2047-
struct ata_taskfile tf;
2048-
unsigned int err_mask;
2049-
2050-
ata_tf_init(dev, &tf);
2051-
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
2052-
tf.protocol = ATA_PROT_NODATA;
2053-
tf.command = ATA_CMD_CHK_POWER;
2054-
2055-
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
2056-
if (err_mask) {
2057-
ata_dev_err(dev, "Check power mode failed (err_mask=0x%x)\n",
2058-
err_mask);
2059-
/*
2060-
* Assume we are in standby mode so that we always force a
2061-
* spinup in ata_dev_power_set_active().
2062-
*/
2063-
return false;
2064-
}
2065-
2066-
ata_dev_dbg(dev, "Power mode: 0x%02x\n", tf.nsect);
2067-
2068-
/* Active or idle */
2069-
return tf.nsect == 0xff;
2070-
}
2071-
20722077
/**
20732078
* ata_dev_power_set_active - Set a device power mode to active
20742079
* @dev: target device

0 commit comments

Comments
 (0)