diff options
Diffstat (limited to 'drivers/ata/ahci_imx.c')
-rw-r--r-- | drivers/ata/ahci_imx.c | 38 |
1 files changed, 34 insertions, 4 deletions
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 |