Skip to content

Commit 036db8b

Browse files
committed
Merge branch 'for-4.17-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata fixes from Tejun Heo: "An earlier commit to add reset control for embedded ahci controllers affected some of the hardware specific drivers and got reverted for now. Other than that, just per-device workarounds and trivial changes" * 'for-4.17-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: driver core: add __printf verification to __ata_ehi_pushv_desc ata: fix spelling mistake: "directon" -> "direction" libata: Apply NOLPM quirk for SanDisk SD7UB3Q*G1001 SSDs libata: Apply NOLPM quirk for SAMSUNG MZMPC128HBFU-000MV SSD ata: ahci: mvebu: override ahci_stop_engine for mvebu AHCI libahci: Allow drivers to override stop_engine Revert "ata: ahci-platform: add reset control support"
2 parents 93a0d34 + 0d74d87 commit 036db8b

File tree

12 files changed

+95
-42
lines changed

12 files changed

+95
-42
lines changed

Documentation/devicetree/bindings/ata/ahci-platform.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ compatible:
3030
Optional properties:
3131
- dma-coherent : Present if dma operations are coherent
3232
- clocks : a list of phandle + clock specifier pairs
33-
- resets : a list of phandle + reset specifier pairs
3433
- target-supply : regulator for SATA target power
3534
- phys : reference to the SATA PHY node
3635
- phy-names : must be "sata-phy"

drivers/ata/ahci.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
698698

699699
DPRINTK("ENTER\n");
700700

701-
ahci_stop_engine(ap);
701+
hpriv->stop_engine(ap);
702702

703703
rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
704704
deadline, &online, NULL);
@@ -724,7 +724,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
724724
bool online;
725725
int rc;
726726

727-
ahci_stop_engine(ap);
727+
hpriv->stop_engine(ap);
728728

729729
/* clear D2H reception area to properly wait for D2H FIS */
730730
ata_tf_init(link->device, &tf);
@@ -788,7 +788,7 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
788788

789789
DPRINTK("ENTER\n");
790790

791-
ahci_stop_engine(ap);
791+
hpriv->stop_engine(ap);
792792

793793
for (i = 0; i < 2; i++) {
794794
u16 val;

drivers/ata/ahci.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,6 @@ struct ahci_host_priv {
350350
u32 em_msg_type; /* EM message type */
351351
bool got_runtime_pm; /* Did we do pm_runtime_get? */
352352
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
353-
struct reset_control *rsts; /* Optional */
354353
struct regulator **target_pwrs; /* Optional */
355354
/*
356355
* If platform uses PHYs. There is a 1:1 relation between the port number and
@@ -366,6 +365,13 @@ struct ahci_host_priv {
366365
* be overridden anytime before the host is activated.
367366
*/
368367
void (*start_engine)(struct ata_port *ap);
368+
/*
369+
* Optional ahci_stop_engine override, if not set this gets set to the
370+
* default ahci_stop_engine during ahci_save_initial_config, this can
371+
* be overridden anytime before the host is activated.
372+
*/
373+
int (*stop_engine)(struct ata_port *ap);
374+
369375
irqreturn_t (*irq_handler)(int irq, void *dev_instance);
370376

371377
/* only required for per-port MSI(-X) support */

drivers/ata/ahci_mvebu.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,60 @@ static void ahci_mvebu_regret_option(struct ahci_host_priv *hpriv)
6262
writel(0x80, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA);
6363
}
6464

65+
/**
66+
* ahci_mvebu_stop_engine
67+
*
68+
* @ap: Target ata port
69+
*
70+
* Errata Ref#226 - SATA Disk HOT swap issue when connected through
71+
* Port Multiplier in FIS-based Switching mode.
72+
*
73+
* To avoid the issue, according to design, the bits[11:8, 0] of
74+
* register PxFBS are cleared when Port Command and Status (0x18) bit[0]
75+
* changes its value from 1 to 0, i.e. falling edge of Port
76+
* Command and Status bit[0] sends PULSE that resets PxFBS
77+
* bits[11:8; 0].
78+
*
79+
* This function is used to override function of "ahci_stop_engine"
80+
* from libahci.c by adding the mvebu work around(WA) to save PxFBS
81+
* value before the PxCMD ST write of 0, then restore PxFBS value.
82+
*
83+
* Return: 0 on success; Error code otherwise.
84+
*/
85+
int ahci_mvebu_stop_engine(struct ata_port *ap)
86+
{
87+
void __iomem *port_mmio = ahci_port_base(ap);
88+
u32 tmp, port_fbs;
89+
90+
tmp = readl(port_mmio + PORT_CMD);
91+
92+
/* check if the HBA is idle */
93+
if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0)
94+
return 0;
95+
96+
/* save the port PxFBS register for later restore */
97+
port_fbs = readl(port_mmio + PORT_FBS);
98+
99+
/* setting HBA to idle */
100+
tmp &= ~PORT_CMD_START;
101+
writel(tmp, port_mmio + PORT_CMD);
102+
103+
/*
104+
* bit #15 PxCMD signal doesn't clear PxFBS,
105+
* restore the PxFBS register right after clearing the PxCMD ST,
106+
* no need to wait for the PxCMD bit #15.
107+
*/
108+
writel(port_fbs, port_mmio + PORT_FBS);
109+
110+
/* wait for engine to stop. This could be as long as 500 msec */
111+
tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
112+
PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
113+
if (tmp & PORT_CMD_LIST_ON)
114+
return -EIO;
115+
116+
return 0;
117+
}
118+
65119
#ifdef CONFIG_PM_SLEEP
66120
static int ahci_mvebu_suspend(struct platform_device *pdev, pm_message_t state)
67121
{
@@ -112,6 +166,8 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
112166
if (rc)
113167
return rc;
114168

169+
hpriv->stop_engine = ahci_mvebu_stop_engine;
170+
115171
if (of_device_is_compatible(pdev->dev.of_node,
116172
"marvell,armada-380-ahci")) {
117173
dram = mv_mbus_dram_info();

drivers/ata/ahci_qoriq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class,
9696

9797
DPRINTK("ENTER\n");
9898

99-
ahci_stop_engine(ap);
99+
hpriv->stop_engine(ap);
100100

101101
/*
102102
* There is a errata on ls1021a Rev1.0 and Rev2.0 which is:

drivers/ata/ahci_xgene.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static int xgene_ahci_restart_engine(struct ata_port *ap)
165165
PORT_CMD_ISSUE, 0x0, 1, 100))
166166
return -EBUSY;
167167

168-
ahci_stop_engine(ap);
168+
hpriv->stop_engine(ap);
169169
ahci_start_fis_rx(ap);
170170

171171
/*
@@ -421,7 +421,7 @@ static int xgene_ahci_hardreset(struct ata_link *link, unsigned int *class,
421421
portrxfis_saved = readl(port_mmio + PORT_FIS_ADDR);
422422
portrxfishi_saved = readl(port_mmio + PORT_FIS_ADDR_HI);
423423

424-
ahci_stop_engine(ap);
424+
hpriv->stop_engine(ap);
425425

426426
rc = xgene_ahci_do_hardreset(link, deadline, &online);
427427

drivers/ata/libahci.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,9 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
560560
if (!hpriv->start_engine)
561561
hpriv->start_engine = ahci_start_engine;
562562

563+
if (!hpriv->stop_engine)
564+
hpriv->stop_engine = ahci_stop_engine;
565+
563566
if (!hpriv->irq_handler)
564567
hpriv->irq_handler = ahci_single_level_irq_intr;
565568
}
@@ -897,9 +900,10 @@ static void ahci_start_port(struct ata_port *ap)
897900
static int ahci_deinit_port(struct ata_port *ap, const char **emsg)
898901
{
899902
int rc;
903+
struct ahci_host_priv *hpriv = ap->host->private_data;
900904

901905
/* disable DMA */
902-
rc = ahci_stop_engine(ap);
906+
rc = hpriv->stop_engine(ap);
903907
if (rc) {
904908
*emsg = "failed to stop engine";
905909
return rc;
@@ -1310,7 +1314,7 @@ int ahci_kick_engine(struct ata_port *ap)
13101314
int busy, rc;
13111315

13121316
/* stop engine */
1313-
rc = ahci_stop_engine(ap);
1317+
rc = hpriv->stop_engine(ap);
13141318
if (rc)
13151319
goto out_restart;
13161320

@@ -1549,7 +1553,7 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
15491553

15501554
DPRINTK("ENTER\n");
15511555

1552-
ahci_stop_engine(ap);
1556+
hpriv->stop_engine(ap);
15531557

15541558
/* clear D2H reception area to properly wait for D2H FIS */
15551559
ata_tf_init(link->device, &tf);
@@ -2075,14 +2079,14 @@ void ahci_error_handler(struct ata_port *ap)
20752079

20762080
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
20772081
/* restart engine */
2078-
ahci_stop_engine(ap);
2082+
hpriv->stop_engine(ap);
20792083
hpriv->start_engine(ap);
20802084
}
20812085

20822086
sata_pmp_error_handler(ap);
20832087

20842088
if (!ata_dev_enabled(ap->link.device))
2085-
ahci_stop_engine(ap);
2089+
hpriv->stop_engine(ap);
20862090
}
20872091
EXPORT_SYMBOL_GPL(ahci_error_handler);
20882092

@@ -2129,7 +2133,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
21292133
return;
21302134

21312135
/* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */
2132-
rc = ahci_stop_engine(ap);
2136+
rc = hpriv->stop_engine(ap);
21332137
if (rc)
21342138
return;
21352139

@@ -2189,7 +2193,7 @@ static void ahci_enable_fbs(struct ata_port *ap)
21892193
return;
21902194
}
21912195

2192-
rc = ahci_stop_engine(ap);
2196+
rc = hpriv->stop_engine(ap);
21932197
if (rc)
21942198
return;
21952199

@@ -2222,7 +2226,7 @@ static void ahci_disable_fbs(struct ata_port *ap)
22222226
return;
22232227
}
22242228

2225-
rc = ahci_stop_engine(ap);
2229+
rc = hpriv->stop_engine(ap);
22262230
if (rc)
22272231
return;
22282232

drivers/ata/libahci_platform.c

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include <linux/phy/phy.h>
2626
#include <linux/pm_runtime.h>
2727
#include <linux/of_platform.h>
28-
#include <linux/reset.h>
2928
#include "ahci.h"
3029

3130
static void ahci_host_stop(struct ata_host *host);
@@ -196,8 +195,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
196195
* following order:
197196
* 1) Regulator
198197
* 2) Clocks (through ahci_platform_enable_clks)
199-
* 3) Resets
200-
* 4) Phys
198+
* 3) Phys
201199
*
202200
* If resource enabling fails at any point the previous enabled resources
203201
* are disabled in reverse order.
@@ -217,19 +215,12 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
217215
if (rc)
218216
goto disable_regulator;
219217

220-
rc = reset_control_deassert(hpriv->rsts);
221-
if (rc)
222-
goto disable_clks;
223-
224218
rc = ahci_platform_enable_phys(hpriv);
225219
if (rc)
226-
goto disable_resets;
220+
goto disable_clks;
227221

228222
return 0;
229223

230-
disable_resets:
231-
reset_control_assert(hpriv->rsts);
232-
233224
disable_clks:
234225
ahci_platform_disable_clks(hpriv);
235226

@@ -248,15 +239,12 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
248239
* following order:
249240
* 1) Phys
250241
* 2) Clocks (through ahci_platform_disable_clks)
251-
* 3) Resets
252-
* 4) Regulator
242+
* 3) Regulator
253243
*/
254244
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
255245
{
256246
ahci_platform_disable_phys(hpriv);
257247

258-
reset_control_assert(hpriv->rsts);
259-
260248
ahci_platform_disable_clks(hpriv);
261249

262250
ahci_platform_disable_regulators(hpriv);
@@ -405,12 +393,6 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
405393
hpriv->clks[i] = clk;
406394
}
407395

408-
hpriv->rsts = devm_reset_control_array_get_optional_shared(dev);
409-
if (IS_ERR(hpriv->rsts)) {
410-
rc = PTR_ERR(hpriv->rsts);
411-
goto err_out;
412-
}
413-
414396
hpriv->nports = child_nodes = of_get_child_count(dev->of_node);
415397

416398
/*

drivers/ata/libata-core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4549,6 +4549,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
45494549
ATA_HORKAGE_ZERO_AFTER_TRIM |
45504550
ATA_HORKAGE_NOLPM, },
45514551

4552+
/* This specific Samsung model/firmware-rev does not handle LPM well */
4553+
{ "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_HORKAGE_NOLPM, },
4554+
4555+
/* Sandisk devices which are known to not handle LPM well */
4556+
{ "SanDisk SD7UB3Q*G1001", NULL, ATA_HORKAGE_NOLPM, },
4557+
45524558
/* devices that don't properly handle queued TRIM commands */
45534559
{ "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
45544560
ATA_HORKAGE_ZERO_AFTER_TRIM, },

drivers/ata/libata-eh.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
175175
{ }
176176
#endif /* CONFIG_PM */
177177

178-
static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt,
179-
va_list args)
178+
static __printf(2, 0) void __ata_ehi_pushv_desc(struct ata_eh_info *ehi,
179+
const char *fmt, va_list args)
180180
{
181181
ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len,
182182
ATA_EH_DESC_LEN - ehi->desc_len,

drivers/ata/sata_highbank.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
410410
int rc;
411411
int retry = 100;
412412

413-
ahci_stop_engine(ap);
413+
hpriv->stop_engine(ap);
414414

415415
/* clear D2H reception area to properly wait for D2H FIS */
416416
ata_tf_init(link->device, &tf);

drivers/ata/sata_sil24.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,13 @@ static const struct sil24_cerr_info {
285285
[PORT_CERR_INCONSISTENT] = { AC_ERR_HSM, ATA_EH_RESET,
286286
"protocol mismatch" },
287287
[PORT_CERR_DIRECTION] = { AC_ERR_HSM, ATA_EH_RESET,
288-
"data directon mismatch" },
288+
"data direction mismatch" },
289289
[PORT_CERR_UNDERRUN] = { AC_ERR_HSM, ATA_EH_RESET,
290290
"ran out of SGEs while writing" },
291291
[PORT_CERR_OVERRUN] = { AC_ERR_HSM, ATA_EH_RESET,
292292
"ran out of SGEs while reading" },
293293
[PORT_CERR_PKT_PROT] = { AC_ERR_HSM, ATA_EH_RESET,
294-
"invalid data directon for ATAPI CDB" },
294+
"invalid data direction for ATAPI CDB" },
295295
[PORT_CERR_SGT_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_RESET,
296296
"SGT not on qword boundary" },
297297
[PORT_CERR_SGT_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET,

0 commit comments

Comments
 (0)