aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci_xgene.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-07-30 12:49:04 -0400
committerTejun Heo <tj@kernel.org>2014-07-30 12:49:04 -0400
commite8f781836dc3335b5533f6e177a105bbe3ee7345 (patch)
treeb6f05b7bf6e69bcc436ab894b7dc84c28c746d1a /drivers/ata/ahci_xgene.c
parent19f5be0f40922717e2b6e39a9822e7e7f30fd81f (diff)
parent1a112d10f03e83fb3a2fdc4c9165865dec8a3ca6 (diff)
Merge branch 'for-3.16-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata into for-3.17
The scheduled ahci platform patches depend on change in for-3.16-fixes. Pull it into for-3.17. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata/ahci_xgene.c')
-rw-r--r--drivers/ata/ahci_xgene.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index 997b4178249a..1cfbdca638d2 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -81,6 +81,7 @@
81struct xgene_ahci_context { 81struct xgene_ahci_context {
82 struct ahci_host_priv *hpriv; 82 struct ahci_host_priv *hpriv;
83 struct device *dev; 83 struct device *dev;
84 u8 last_cmd[MAX_AHCI_CHN_PERCTR]; /* tracking the last command issued*/
84 void __iomem *csr_core; /* Core CSR address of IP */ 85 void __iomem *csr_core; /* Core CSR address of IP */
85 void __iomem *csr_diag; /* Diag CSR address of IP */ 86 void __iomem *csr_diag; /* Diag CSR address of IP */
86 void __iomem *csr_axi; /* AXI CSR address of IP */ 87 void __iomem *csr_axi; /* AXI CSR address of IP */
@@ -101,20 +102,62 @@ static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx)
101} 102}
102 103
103/** 104/**
105 * xgene_ahci_restart_engine - Restart the dma engine.
106 * @ap : ATA port of interest
107 *
108 * Restarts the dma engine inside the controller.
109 */
110static int xgene_ahci_restart_engine(struct ata_port *ap)
111{
112 struct ahci_host_priv *hpriv = ap->host->private_data;
113
114 ahci_stop_engine(ap);
115 ahci_start_fis_rx(ap);
116 hpriv->start_engine(ap);
117
118 return 0;
119}
120
121/**
122 * xgene_ahci_qc_issue - Issue commands to the device
123 * @qc: Command to issue
124 *
125 * Due to Hardware errata for IDENTIFY DEVICE command, the controller cannot
126 * clear the BSY bit after receiving the PIO setup FIS. This results in the dma
127 * state machine goes into the CMFatalErrorUpdate state and locks up. By
128 * restarting the dma engine, it removes the controller out of lock up state.
129 */
130static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
131{
132 struct ata_port *ap = qc->ap;
133 struct ahci_host_priv *hpriv = ap->host->private_data;
134 struct xgene_ahci_context *ctx = hpriv->plat_data;
135 int rc = 0;
136
137 if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA))
138 xgene_ahci_restart_engine(ap);
139
140 rc = ahci_qc_issue(qc);
141
142 /* Save the last command issued */
143 ctx->last_cmd[ap->port_no] = qc->tf.command;
144
145 return rc;
146}
147
148/**
104 * xgene_ahci_read_id - Read ID data from the specified device 149 * xgene_ahci_read_id - Read ID data from the specified device
105 * @dev: device 150 * @dev: device
106 * @tf: proposed taskfile 151 * @tf: proposed taskfile
107 * @id: data buffer 152 * @id: data buffer
108 * 153 *
109 * This custom read ID function is required due to the fact that the HW 154 * This custom read ID function is required due to the fact that the HW
110 * does not support DEVSLP and the controller state machine may get stuck 155 * does not support DEVSLP.
111 * after processing the ID query command.
112 */ 156 */
113static unsigned int xgene_ahci_read_id(struct ata_device *dev, 157static unsigned int xgene_ahci_read_id(struct ata_device *dev,
114 struct ata_taskfile *tf, u16 *id) 158 struct ata_taskfile *tf, u16 *id)
115{ 159{
116 u32 err_mask; 160 u32 err_mask;
117 void __iomem *port_mmio = ahci_port_base(dev->link->ap);
118 161
119 err_mask = ata_do_dev_read_id(dev, tf, id); 162 err_mask = ata_do_dev_read_id(dev, tf, id);
120 if (err_mask) 163 if (err_mask)
@@ -136,16 +179,6 @@ static unsigned int xgene_ahci_read_id(struct ata_device *dev,
136 */ 179 */
137 id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8); 180 id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8);
138 181
139 /*
140 * Due to HW errata, restart the port if no other command active.
141 * Otherwise the controller may get stuck.
142 */
143 if (!readl(port_mmio + PORT_CMD_ISSUE)) {
144 writel(PORT_CMD_FIS_RX, port_mmio + PORT_CMD);
145 readl(port_mmio + PORT_CMD); /* Force a barrier */
146 writel(PORT_CMD_FIS_RX | PORT_CMD_START, port_mmio + PORT_CMD);
147 readl(port_mmio + PORT_CMD); /* Force a barrier */
148 }
149 return 0; 182 return 0;
150} 183}
151 184
@@ -307,6 +340,7 @@ static struct ata_port_operations xgene_ahci_ops = {
307 .host_stop = xgene_ahci_host_stop, 340 .host_stop = xgene_ahci_host_stop,
308 .hardreset = xgene_ahci_hardreset, 341 .hardreset = xgene_ahci_hardreset,
309 .read_id = xgene_ahci_read_id, 342 .read_id = xgene_ahci_read_id,
343 .qc_issue = xgene_ahci_qc_issue,
310}; 344};
311 345
312static const struct ata_port_info xgene_ahci_port_info = { 346static const struct ata_port_info xgene_ahci_port_info = {