aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartosz Golaszewski <bgolaszewski@baylibre.com>2017-04-04 15:32:27 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-12 06:41:20 -0400
commitb369fd719fa455c11665700d704ac2c9ba8d0e0a (patch)
treec7396bca713dd1961013634b5947fa0d7fae2483
parentf36d3f1fe79e3cbf9af18434b3b2800e6a210cf4 (diff)
sata: ahci-da850: implement a workaround for the softreset quirk
[ Upstream commit f4d435f3265661d04e5290a0a0450e3a38898128 ] There's an issue with the da850 SATA controller: if port multiplier support is compiled in, but we're connecting the drive directly to the SATA port on the board, the drive can't be detected. To make SATA work on the da850-lcdk board: first try to softreset with pmp - if the operation fails with -EBUSY, retry without pmp. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/ata/ahci_da850.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 267a3d3e79f4..52f2674d5e89 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -54,11 +54,42 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg,
54 writel(val, ahci_base + SATA_P0PHYCR_REG); 54 writel(val, ahci_base + SATA_P0PHYCR_REG);
55} 55}
56 56
57static int ahci_da850_softreset(struct ata_link *link,
58 unsigned int *class, unsigned long deadline)
59{
60 int pmp, ret;
61
62 pmp = sata_srst_pmp(link);
63
64 /*
65 * There's an issue with the SATA controller on da850 SoCs: if we
66 * enable Port Multiplier support, but the drive is connected directly
67 * to the board, it can't be detected. As a workaround: if PMP is
68 * enabled, we first call ahci_do_softreset() and pass it the result of
69 * sata_srst_pmp(). If this call fails, we retry with pmp = 0.
70 */
71 ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
72 if (pmp && ret == -EBUSY)
73 return ahci_do_softreset(link, class, 0,
74 deadline, ahci_check_ready);
75
76 return ret;
77}
78
79static struct ata_port_operations ahci_da850_port_ops = {
80 .inherits = &ahci_platform_ops,
81 .softreset = ahci_da850_softreset,
82 /*
83 * No need to override .pmp_softreset - it's only used for actual
84 * PMP-enabled ports.
85 */
86};
87
57static const struct ata_port_info ahci_da850_port_info = { 88static const struct ata_port_info ahci_da850_port_info = {
58 .flags = AHCI_FLAG_COMMON, 89 .flags = AHCI_FLAG_COMMON,
59 .pio_mask = ATA_PIO4, 90 .pio_mask = ATA_PIO4,
60 .udma_mask = ATA_UDMA6, 91 .udma_mask = ATA_UDMA6,
61 .port_ops = &ahci_platform_ops, 92 .port_ops = &ahci_da850_port_ops,
62}; 93};
63 94
64static struct scsi_host_template ahci_platform_sht = { 95static struct scsi_host_template ahci_platform_sht = {