aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@freescale.com>2014-05-28 11:05:39 -0400
committerTejun Heo <tj@kernel.org>2014-06-19 10:14:58 -0400
commite6dd42a917e62d916c6e513dbf87a4dec8cf3a1c (patch)
treea520dff64c52c0dea954afcce936b29398ccb3ca /drivers/ata
parentacbd573354bb7b7b7a3891018a39f4b3976b0c43 (diff)
ahci: imx: manage only sata_ref_clk in imx_sata_enable[disable]
Doing suspend/resume on imx6q and imx53 boards with no SATA disk attached will trigger the following warning. ------------[ cut here ]------------ WARNING: CPU: 0 PID: 661 at drivers/ata/libahci.c:224 ahci_enable_ahci+0x74/0x8) Modules linked in: CPU: 0 PID: 661 Comm: sh Tainted: G W 3.15.0-rc5-next-20140521-000027 Backtrace: [<80011c90>] (dump_backtrace) from [<80011e2c>] (show_stack+0x18/0x1c) r6:803a22f4 r5:00000000 r4:00000000 r3:00000000 [<80011e14>] (show_stack) from [<80661e60>] (dump_stack+0x88/0xa4) [<80661dd8>] (dump_stack) from [<80028fdc>] (warn_slowpath_common+0x70/0x94) r5:00000009 r4:00000000 [<80028f6c>] (warn_slowpath_common) from [<80029024>] (warn_slowpath_null+0x24/) r8:808f68c4 r7:00000000 r6:00000000 r5:00000000 r4:e0810004 [<80029000>] (warn_slowpath_null) from [<803a22f4>] (ahci_enable_ahci+0x74/0x80) [<803a2280>] (ahci_enable_ahci) from [<803a2324>] (ahci_reset_controller+0x24/0) r8:ddcd9410 r7:80351178 r6:ddcd9444 r5:dde8b850 r4:e0810000 r3:ddf35e90 [<803a2300>] (ahci_reset_controller) from [<803a2c68>] (ahci_platform_resume_ho) r7:80351178 r6:ddcd9444 r5:dde8b850 r4:ddcd9410 [<803a2c30>] (ahci_platform_resume_host) from [<803a38f0>] (imx_ahci_resume+0x2) r5:00000000 r4:ddcd9410 [<803a38c4>] (imx_ahci_resume) from [<803511ac>] (platform_pm_resume+0x34/0x54) .... The reason is that the SATA controller has no working clock at this point, and thus ahci_enable_ahci() fails to enable the controller. In case that there is no SATA disk attached, the imx_sata_disable() gets called in ahci_imx_error_handler(), and both sata_clk and sata_ref_clk will be disabled there. Because all the imx_sata_enable() calls afterward will return immediately due to imxpriv->no_device check, the SATA controller working clock sata_clk will never get any chance to be enabled again. This is a regression caused by commit 90870d79d4f2 (ahci-imx: Port to library-ised ahci_platform). Before the commit, only sata_ref_clk is managed by the driver in enable/disable function. But after the commit, all the clocks are enabled/disabled in a row by ahci platform helpers ahci_platform_enable[disable]_clks. Since ahb_clk is a bus clock which does not have gate at all, and i.MX low-power hardware module already manages sata_clk across suspend/resume cycle, the only clock that needs to be managed by software is sata_ref_clk. So instead of using ahci_platform_enable[disable]_clks to manage all the clocks in a row from imx_sata_enable[disable], we should manage only sata_ref_clk in there. Reported-by: Fabio Estevam <fabio.estevam@freescale.com> Fixes: 90870d79d4f2 (ahci-imx: Port to library-ised ahci_platform) Signed-off-by: Shawn Guo <shawn.guo@freescale.com> Acked-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci_imx.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 3a901520c62b..4384a7d72133 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -58,6 +58,8 @@ enum ahci_imx_type {
58struct imx_ahci_priv { 58struct 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);
@@ -385,6 +387,19 @@ static int imx_ahci_probe(struct platform_device *pdev)
385 imxpriv->no_device = false; 387 imxpriv->no_device = false;
386 imxpriv->first_time = true; 388 imxpriv->first_time = true;
387 imxpriv->type = (enum ahci_imx_type)of_id->data; 389 imxpriv->type = (enum ahci_imx_type)of_id->data;
390
391 imxpriv->sata_clk = devm_clk_get(dev, "sata");
392 if (IS_ERR(imxpriv->sata_clk)) {
393 dev_err(dev, "can't get sata clock.\n");
394 return PTR_ERR(imxpriv->sata_clk);
395 }
396
397 imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
398 if (IS_ERR(imxpriv->sata_ref_clk)) {
399 dev_err(dev, "can't get sata_ref clock.\n");
400 return PTR_ERR(imxpriv->sata_ref_clk);
401 }
402
388 imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); 403 imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
389 if (IS_ERR(imxpriv->ahb_clk)) { 404 if (IS_ERR(imxpriv->ahb_clk)) {
390 dev_err(dev, "can't get ahb clock.\n"); 405 dev_err(dev, "can't get ahb clock.\n");
@@ -407,10 +422,14 @@ static int imx_ahci_probe(struct platform_device *pdev)
407 422
408 hpriv->plat_data = imxpriv; 423 hpriv->plat_data = imxpriv;
409 424
410 ret = imx_sata_enable(hpriv); 425 ret = clk_prepare_enable(imxpriv->sata_clk);
411 if (ret) 426 if (ret)
412 return ret; 427 return ret;
413 428
429 ret = imx_sata_enable(hpriv);
430 if (ret)
431 goto disable_clk;
432
414 /* 433 /*
415 * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, 434 * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
416 * and IP vendor specific register IMX_TIMER1MS. 435 * and IP vendor specific register IMX_TIMER1MS.
@@ -435,16 +454,24 @@ static int imx_ahci_probe(struct platform_device *pdev)
435 ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 454 ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
436 0, 0, 0); 455 0, 0, 0);
437 if (ret) 456 if (ret)
438 imx_sata_disable(hpriv); 457 goto disable_sata;
458
459 return 0;
439 460
461disable_sata:
462 imx_sata_disable(hpriv);
463disable_clk:
464 clk_disable_unprepare(imxpriv->sata_clk);
440 return ret; 465 return ret;
441} 466}
442 467
443static void ahci_imx_host_stop(struct ata_host *host) 468static void ahci_imx_host_stop(struct ata_host *host)
444{ 469{
445 struct ahci_host_priv *hpriv = host->private_data; 470 struct ahci_host_priv *hpriv = host->private_data;
471 struct imx_ahci_priv *imxpriv = hpriv->plat_data;
446 472
447 imx_sata_disable(hpriv); 473 imx_sata_disable(hpriv);
474 clk_disable_unprepare(imxpriv->sata_clk);
448} 475}
449 476
450#ifdef CONFIG_PM_SLEEP 477#ifdef CONFIG_PM_SLEEP