diff options
author | David S. Miller <davem@davemloft.net> | 2014-07-16 17:09:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-16 17:09:34 -0400 |
commit | 1a98c69af1ecd97bfd1f4e4539924a9192434e36 (patch) | |
tree | a243defcf921ea174f8e43fce11d06830a6a9c36 /drivers/ata | |
parent | 7a575f6b907ea5d207d2b5010293c189616eae34 (diff) | |
parent | b6603fe574af289dbe9eb9fb4c540bca04f5a053 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.h | 2 | ||||
-rw-r--r-- | drivers/ata/ahci_imx.c | 38 | ||||
-rw-r--r-- | drivers/ata/ahci_platform.c | 2 | ||||
-rw-r--r-- | drivers/ata/ahci_xgene.c | 60 | ||||
-rw-r--r-- | drivers/ata/libahci.c | 7 | ||||
-rw-r--r-- | drivers/ata/libahci_platform.c | 7 |
6 files changed, 94 insertions, 22 deletions
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 05882e4445a6..5513296e5e2e 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -371,7 +371,9 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, | |||
371 | int pmp, unsigned long deadline, | 371 | int pmp, unsigned long deadline, |
372 | int (*check_ready)(struct ata_link *link)); | 372 | int (*check_ready)(struct ata_link *link)); |
373 | 373 | ||
374 | unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | ||
374 | int ahci_stop_engine(struct ata_port *ap); | 375 | int ahci_stop_engine(struct ata_port *ap); |
376 | void ahci_start_fis_rx(struct ata_port *ap); | ||
375 | void ahci_start_engine(struct ata_port *ap); | 377 | void ahci_start_engine(struct ata_port *ap); |
376 | int ahci_check_ready(struct ata_link *link); | 378 | int ahci_check_ready(struct ata_link *link); |
377 | int ahci_kick_engine(struct ata_port *ap); | 379 | int ahci_kick_engine(struct ata_port *ap); |
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 3a901520c62b..cac4360f272a 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c | |||
@@ -58,6 +58,8 @@ enum ahci_imx_type { | |||
58 | struct imx_ahci_priv { | 58 | struct imx_ahci_priv { |
59 | struct platform_device *ahci_pdev; | 59 | struct platform_device *ahci_pdev; |
60 | enum ahci_imx_type type; | 60 | enum ahci_imx_type type; |
61 | struct clk *sata_clk; | ||
62 | struct clk *sata_ref_clk; | ||
61 | struct clk *ahb_clk; | 63 | struct clk *ahb_clk; |
62 | struct regmap *gpr; | 64 | struct regmap *gpr; |
63 | bool no_device; | 65 | bool no_device; |
@@ -224,7 +226,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv) | |||
224 | return ret; | 226 | return ret; |
225 | } | 227 | } |
226 | 228 | ||
227 | ret = ahci_platform_enable_clks(hpriv); | 229 | ret = clk_prepare_enable(imxpriv->sata_ref_clk); |
228 | if (ret < 0) | 230 | if (ret < 0) |
229 | goto disable_regulator; | 231 | goto disable_regulator; |
230 | 232 | ||
@@ -291,7 +293,7 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv) | |||
291 | !IMX6Q_GPR13_SATA_MPLL_CLK_EN); | 293 | !IMX6Q_GPR13_SATA_MPLL_CLK_EN); |
292 | } | 294 | } |
293 | 295 | ||
294 | ahci_platform_disable_clks(hpriv); | 296 | clk_disable_unprepare(imxpriv->sata_ref_clk); |
295 | 297 | ||
296 | if (hpriv->target_pwr) | 298 | if (hpriv->target_pwr) |
297 | regulator_disable(hpriv->target_pwr); | 299 | regulator_disable(hpriv->target_pwr); |
@@ -324,6 +326,9 @@ static void ahci_imx_error_handler(struct ata_port *ap) | |||
324 | writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR); | 326 | writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR); |
325 | imx_sata_disable(hpriv); | 327 | imx_sata_disable(hpriv); |
326 | imxpriv->no_device = true; | 328 | imxpriv->no_device = true; |
329 | |||
330 | dev_info(ap->dev, "no device found, disabling link.\n"); | ||
331 | dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX ".hotplug=1 to enable hotplug\n"); | ||
327 | } | 332 | } |
328 | 333 | ||
329 | static int ahci_imx_softreset(struct ata_link *link, unsigned int *class, | 334 | static int ahci_imx_softreset(struct ata_link *link, unsigned int *class, |
@@ -385,6 +390,19 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
385 | imxpriv->no_device = false; | 390 | imxpriv->no_device = false; |
386 | imxpriv->first_time = true; | 391 | imxpriv->first_time = true; |
387 | imxpriv->type = (enum ahci_imx_type)of_id->data; | 392 | imxpriv->type = (enum ahci_imx_type)of_id->data; |
393 | |||
394 | imxpriv->sata_clk = devm_clk_get(dev, "sata"); | ||
395 | if (IS_ERR(imxpriv->sata_clk)) { | ||
396 | dev_err(dev, "can't get sata clock.\n"); | ||
397 | return PTR_ERR(imxpriv->sata_clk); | ||
398 | } | ||
399 | |||
400 | imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref"); | ||
401 | if (IS_ERR(imxpriv->sata_ref_clk)) { | ||
402 | dev_err(dev, "can't get sata_ref clock.\n"); | ||
403 | return PTR_ERR(imxpriv->sata_ref_clk); | ||
404 | } | ||
405 | |||
388 | imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); | 406 | imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); |
389 | if (IS_ERR(imxpriv->ahb_clk)) { | 407 | if (IS_ERR(imxpriv->ahb_clk)) { |
390 | dev_err(dev, "can't get ahb clock.\n"); | 408 | dev_err(dev, "can't get ahb clock.\n"); |
@@ -407,10 +425,14 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
407 | 425 | ||
408 | hpriv->plat_data = imxpriv; | 426 | hpriv->plat_data = imxpriv; |
409 | 427 | ||
410 | ret = imx_sata_enable(hpriv); | 428 | ret = clk_prepare_enable(imxpriv->sata_clk); |
411 | if (ret) | 429 | if (ret) |
412 | return ret; | 430 | return ret; |
413 | 431 | ||
432 | ret = imx_sata_enable(hpriv); | ||
433 | if (ret) | ||
434 | goto disable_clk; | ||
435 | |||
414 | /* | 436 | /* |
415 | * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, | 437 | * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, |
416 | * and IP vendor specific register IMX_TIMER1MS. | 438 | * and IP vendor specific register IMX_TIMER1MS. |
@@ -435,16 +457,24 @@ static int imx_ahci_probe(struct platform_device *pdev) | |||
435 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, | 457 | ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, |
436 | 0, 0, 0); | 458 | 0, 0, 0); |
437 | if (ret) | 459 | if (ret) |
438 | imx_sata_disable(hpriv); | 460 | goto disable_sata; |
439 | 461 | ||
462 | return 0; | ||
463 | |||
464 | disable_sata: | ||
465 | imx_sata_disable(hpriv); | ||
466 | disable_clk: | ||
467 | clk_disable_unprepare(imxpriv->sata_clk); | ||
440 | return ret; | 468 | return ret; |
441 | } | 469 | } |
442 | 470 | ||
443 | static void ahci_imx_host_stop(struct ata_host *host) | 471 | static void ahci_imx_host_stop(struct ata_host *host) |
444 | { | 472 | { |
445 | struct ahci_host_priv *hpriv = host->private_data; | 473 | struct ahci_host_priv *hpriv = host->private_data; |
474 | struct imx_ahci_priv *imxpriv = hpriv->plat_data; | ||
446 | 475 | ||
447 | imx_sata_disable(hpriv); | 476 | imx_sata_disable(hpriv); |
477 | clk_disable_unprepare(imxpriv->sata_clk); | ||
448 | } | 478 | } |
449 | 479 | ||
450 | #ifdef CONFIG_PM_SLEEP | 480 | #ifdef CONFIG_PM_SLEEP |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index ebe505c17763..b10d81ddb528 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -58,7 +58,7 @@ static int ahci_probe(struct platform_device *pdev) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) | 60 | if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) |
61 | hflags |= AHCI_HFLAG_NO_FBS; | 61 | hflags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; |
62 | 62 | ||
63 | rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, | 63 | rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, |
64 | hflags, 0, 0); | 64 | hflags, 0, 0); |
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 042a9bb45c86..ee3a3659bd9e 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c | |||
@@ -78,6 +78,7 @@ | |||
78 | struct xgene_ahci_context { | 78 | struct xgene_ahci_context { |
79 | struct ahci_host_priv *hpriv; | 79 | struct ahci_host_priv *hpriv; |
80 | struct device *dev; | 80 | struct device *dev; |
81 | u8 last_cmd[MAX_AHCI_CHN_PERCTR]; /* tracking the last command issued*/ | ||
81 | void __iomem *csr_core; /* Core CSR address of IP */ | 82 | void __iomem *csr_core; /* Core CSR address of IP */ |
82 | void __iomem *csr_diag; /* Diag CSR address of IP */ | 83 | void __iomem *csr_diag; /* Diag CSR address of IP */ |
83 | void __iomem *csr_axi; /* AXI CSR address of IP */ | 84 | void __iomem *csr_axi; /* AXI CSR address of IP */ |
@@ -98,20 +99,62 @@ static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx) | |||
98 | } | 99 | } |
99 | 100 | ||
100 | /** | 101 | /** |
102 | * xgene_ahci_restart_engine - Restart the dma engine. | ||
103 | * @ap : ATA port of interest | ||
104 | * | ||
105 | * Restarts the dma engine inside the controller. | ||
106 | */ | ||
107 | static int xgene_ahci_restart_engine(struct ata_port *ap) | ||
108 | { | ||
109 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
110 | |||
111 | ahci_stop_engine(ap); | ||
112 | ahci_start_fis_rx(ap); | ||
113 | hpriv->start_engine(ap); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * xgene_ahci_qc_issue - Issue commands to the device | ||
120 | * @qc: Command to issue | ||
121 | * | ||
122 | * Due to Hardware errata for IDENTIFY DEVICE command, the controller cannot | ||
123 | * clear the BSY bit after receiving the PIO setup FIS. This results in the dma | ||
124 | * state machine goes into the CMFatalErrorUpdate state and locks up. By | ||
125 | * restarting the dma engine, it removes the controller out of lock up state. | ||
126 | */ | ||
127 | static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) | ||
128 | { | ||
129 | struct ata_port *ap = qc->ap; | ||
130 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
131 | struct xgene_ahci_context *ctx = hpriv->plat_data; | ||
132 | int rc = 0; | ||
133 | |||
134 | if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA)) | ||
135 | xgene_ahci_restart_engine(ap); | ||
136 | |||
137 | rc = ahci_qc_issue(qc); | ||
138 | |||
139 | /* Save the last command issued */ | ||
140 | ctx->last_cmd[ap->port_no] = qc->tf.command; | ||
141 | |||
142 | return rc; | ||
143 | } | ||
144 | |||
145 | /** | ||
101 | * xgene_ahci_read_id - Read ID data from the specified device | 146 | * xgene_ahci_read_id - Read ID data from the specified device |
102 | * @dev: device | 147 | * @dev: device |
103 | * @tf: proposed taskfile | 148 | * @tf: proposed taskfile |
104 | * @id: data buffer | 149 | * @id: data buffer |
105 | * | 150 | * |
106 | * This custom read ID function is required due to the fact that the HW | 151 | * This custom read ID function is required due to the fact that the HW |
107 | * does not support DEVSLP and the controller state machine may get stuck | 152 | * does not support DEVSLP. |
108 | * after processing the ID query command. | ||
109 | */ | 153 | */ |
110 | static unsigned int xgene_ahci_read_id(struct ata_device *dev, | 154 | static unsigned int xgene_ahci_read_id(struct ata_device *dev, |
111 | struct ata_taskfile *tf, u16 *id) | 155 | struct ata_taskfile *tf, u16 *id) |
112 | { | 156 | { |
113 | u32 err_mask; | 157 | u32 err_mask; |
114 | void __iomem *port_mmio = ahci_port_base(dev->link->ap); | ||
115 | 158 | ||
116 | err_mask = ata_do_dev_read_id(dev, tf, id); | 159 | err_mask = ata_do_dev_read_id(dev, tf, id); |
117 | if (err_mask) | 160 | if (err_mask) |
@@ -133,16 +176,6 @@ static unsigned int xgene_ahci_read_id(struct ata_device *dev, | |||
133 | */ | 176 | */ |
134 | id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8); | 177 | id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8); |
135 | 178 | ||
136 | /* | ||
137 | * Due to HW errata, restart the port if no other command active. | ||
138 | * Otherwise the controller may get stuck. | ||
139 | */ | ||
140 | if (!readl(port_mmio + PORT_CMD_ISSUE)) { | ||
141 | writel(PORT_CMD_FIS_RX, port_mmio + PORT_CMD); | ||
142 | readl(port_mmio + PORT_CMD); /* Force a barrier */ | ||
143 | writel(PORT_CMD_FIS_RX | PORT_CMD_START, port_mmio + PORT_CMD); | ||
144 | readl(port_mmio + PORT_CMD); /* Force a barrier */ | ||
145 | } | ||
146 | return 0; | 179 | return 0; |
147 | } | 180 | } |
148 | 181 | ||
@@ -300,6 +333,7 @@ static struct ata_port_operations xgene_ahci_ops = { | |||
300 | .host_stop = xgene_ahci_host_stop, | 333 | .host_stop = xgene_ahci_host_stop, |
301 | .hardreset = xgene_ahci_hardreset, | 334 | .hardreset = xgene_ahci_hardreset, |
302 | .read_id = xgene_ahci_read_id, | 335 | .read_id = xgene_ahci_read_id, |
336 | .qc_issue = xgene_ahci_qc_issue, | ||
303 | }; | 337 | }; |
304 | 338 | ||
305 | static const struct ata_port_info xgene_ahci_port_info = { | 339 | static const struct ata_port_info xgene_ahci_port_info = { |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 40ea583d3610..d72ce0470309 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -68,7 +68,6 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | |||
68 | 68 | ||
69 | static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); | 69 | static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); |
70 | static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); | 70 | static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); |
71 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | ||
72 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); | 71 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); |
73 | static int ahci_port_start(struct ata_port *ap); | 72 | static int ahci_port_start(struct ata_port *ap); |
74 | static void ahci_port_stop(struct ata_port *ap); | 73 | static void ahci_port_stop(struct ata_port *ap); |
@@ -620,7 +619,7 @@ int ahci_stop_engine(struct ata_port *ap) | |||
620 | } | 619 | } |
621 | EXPORT_SYMBOL_GPL(ahci_stop_engine); | 620 | EXPORT_SYMBOL_GPL(ahci_stop_engine); |
622 | 621 | ||
623 | static void ahci_start_fis_rx(struct ata_port *ap) | 622 | void ahci_start_fis_rx(struct ata_port *ap) |
624 | { | 623 | { |
625 | void __iomem *port_mmio = ahci_port_base(ap); | 624 | void __iomem *port_mmio = ahci_port_base(ap); |
626 | struct ahci_host_priv *hpriv = ap->host->private_data; | 625 | struct ahci_host_priv *hpriv = ap->host->private_data; |
@@ -646,6 +645,7 @@ static void ahci_start_fis_rx(struct ata_port *ap) | |||
646 | /* flush */ | 645 | /* flush */ |
647 | readl(port_mmio + PORT_CMD); | 646 | readl(port_mmio + PORT_CMD); |
648 | } | 647 | } |
648 | EXPORT_SYMBOL_GPL(ahci_start_fis_rx); | ||
649 | 649 | ||
650 | static int ahci_stop_fis_rx(struct ata_port *ap) | 650 | static int ahci_stop_fis_rx(struct ata_port *ap) |
651 | { | 651 | { |
@@ -1945,7 +1945,7 @@ irqreturn_t ahci_interrupt(int irq, void *dev_instance) | |||
1945 | } | 1945 | } |
1946 | EXPORT_SYMBOL_GPL(ahci_interrupt); | 1946 | EXPORT_SYMBOL_GPL(ahci_interrupt); |
1947 | 1947 | ||
1948 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | 1948 | unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) |
1949 | { | 1949 | { |
1950 | struct ata_port *ap = qc->ap; | 1950 | struct ata_port *ap = qc->ap; |
1951 | void __iomem *port_mmio = ahci_port_base(ap); | 1951 | void __iomem *port_mmio = ahci_port_base(ap); |
@@ -1974,6 +1974,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
1974 | 1974 | ||
1975 | return 0; | 1975 | return 0; |
1976 | } | 1976 | } |
1977 | EXPORT_SYMBOL_GPL(ahci_qc_issue); | ||
1977 | 1978 | ||
1978 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) | 1979 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) |
1979 | { | 1980 | { |
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 3a5b4ed25a4f..b0077589f065 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c | |||
@@ -250,8 +250,13 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev) | |||
250 | if (IS_ERR(hpriv->phy)) { | 250 | if (IS_ERR(hpriv->phy)) { |
251 | rc = PTR_ERR(hpriv->phy); | 251 | rc = PTR_ERR(hpriv->phy); |
252 | switch (rc) { | 252 | switch (rc) { |
253 | case -ENODEV: | ||
254 | case -ENOSYS: | 253 | case -ENOSYS: |
254 | /* No PHY support. Check if PHY is required. */ | ||
255 | if (of_find_property(dev->of_node, "phys", NULL)) { | ||
256 | dev_err(dev, "couldn't get sata-phy: ENOSYS\n"); | ||
257 | goto err_out; | ||
258 | } | ||
259 | case -ENODEV: | ||
255 | /* continue normally */ | 260 | /* continue normally */ |
256 | hpriv->phy = NULL; | 261 | hpriv->phy = NULL; |
257 | break; | 262 | break; |