Skip to content

Commit 3ae50f4

Browse files
Lee Jonesstorulf
authored andcommitted
mmc: sdhci-st: Handle interconnect clock
Some ST platforms contain interconnect (ICN) clocks which must be handed correctly in order to obtain full functionality of a given IP. In this case, if the ICN clocks are not handled properly by the ST SDHCI driver MMC will break and the following output can be observed: [ 13.916949] mmc0: Timeout waiting for hardware interrupt. [ 13.922349] sdhci: =========== REGISTER DUMP (mmc0)=========== [ 13.928175] sdhci: Sys addr: 0x00000000 | Version: 0x00001002 [ 13.933999] sdhci: Blk size: 0x00007040 | Blk cnt: 0x00000001 [ 13.939825] sdhci: Argument: 0x00fffff0 | Trn mode: 0x00000013 [ 13.945650] sdhci: Present: 0x1fff0206 | Host ctl: 0x00000011 [ 13.951475] sdhci: Power: 0x0000000f | Blk gap: 0x00000080 [ 13.957300] sdhci: Wake-up: 0x00000000 | Clock: 0x00003f07 [ 13.963126] sdhci: Timeout: 0x00000004 | Int stat: 0x00000000 [ 13.968952] sdhci: Int enab: 0x02ff008b | Sig enab: 0x02ff008b [ 13.974777] sdhci: AC12 err: 0x00000000 | Slot int: 0x00000000 [ 13.980602] sdhci: Caps: 0x21ed3281 | Caps_1: 0x00000000 [ 13.986428] sdhci: Cmd: 0x0000063a | Max curr: 0x00000000 [ 13.992252] sdhci: Host ctl2: 0x00000000 [ 13.996166] sdhci: ADMA Err: 0x00000000 | ADMA Ptr: 0x7c048200 [ 14.001990] sdhci: =========================================== [ 14.009802] mmc0: Got data interrupt 0x02000000 even though no data operation was in progress. A decent point was raised about minimising the use of a local variable that we 'could' do without. I've chosen consistency over the possibility of reducing the local variable count by 1. Thinking that it's more important for the code to be grouped and authoured in a similar manner/style for greater maintainability/readability. Cc: [email protected] Tested-by: Peter Griffin <[email protected]> Signed-off-by: Lee Jones <[email protected]> Signed-off-by: Ulf Hansson <[email protected]>
1 parent 981b178 commit 3ae50f4

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

drivers/mmc/host/sdhci-st.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
struct st_mmc_platform_data {
3030
struct reset_control *rstc;
31+
struct clk *icnclk;
3132
void __iomem *top_ioaddr;
3233
};
3334

@@ -353,7 +354,7 @@ static int sdhci_st_probe(struct platform_device *pdev)
353354
struct sdhci_host *host;
354355
struct st_mmc_platform_data *pdata;
355356
struct sdhci_pltfm_host *pltfm_host;
356-
struct clk *clk;
357+
struct clk *clk, *icnclk;
357358
int ret = 0;
358359
u16 host_version;
359360
struct resource *res;
@@ -365,6 +366,11 @@ static int sdhci_st_probe(struct platform_device *pdev)
365366
return PTR_ERR(clk);
366367
}
367368

369+
/* ICN clock isn't compulsory, but use it if it's provided. */
370+
icnclk = devm_clk_get(&pdev->dev, "icn");
371+
if (IS_ERR(icnclk))
372+
icnclk = NULL;
373+
368374
rstc = devm_reset_control_get(&pdev->dev, NULL);
369375
if (IS_ERR(rstc))
370376
rstc = NULL;
@@ -389,6 +395,7 @@ static int sdhci_st_probe(struct platform_device *pdev)
389395
}
390396

391397
clk_prepare_enable(clk);
398+
clk_prepare_enable(icnclk);
392399

393400
/* Configure the FlashSS Top registers for setting eMMC TX/RX delay */
394401
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
@@ -400,6 +407,7 @@ static int sdhci_st_probe(struct platform_device *pdev)
400407
}
401408

402409
pltfm_host->clk = clk;
410+
pdata->icnclk = icnclk;
403411

404412
/* Configure the Arasan HC inside the flashSS */
405413
st_mmcss_cconfig(np, host);
@@ -422,6 +430,7 @@ static int sdhci_st_probe(struct platform_device *pdev)
422430
return 0;
423431

424432
err_out:
433+
clk_disable_unprepare(icnclk);
425434
clk_disable_unprepare(clk);
426435
err_of:
427436
sdhci_pltfm_free(pdev);
@@ -442,6 +451,8 @@ static int sdhci_st_remove(struct platform_device *pdev)
442451

443452
ret = sdhci_pltfm_unregister(pdev);
444453

454+
clk_disable_unprepare(pdata->icnclk);
455+
445456
if (rstc)
446457
reset_control_assert(rstc);
447458

@@ -462,6 +473,7 @@ static int sdhci_st_suspend(struct device *dev)
462473
if (pdata->rstc)
463474
reset_control_assert(pdata->rstc);
464475

476+
clk_disable_unprepare(pdata->icnclk);
465477
clk_disable_unprepare(pltfm_host->clk);
466478
out:
467479
return ret;
@@ -475,6 +487,7 @@ static int sdhci_st_resume(struct device *dev)
475487
struct device_node *np = dev->of_node;
476488

477489
clk_prepare_enable(pltfm_host->clk);
490+
clk_prepare_enable(pdata->icnclk);
478491

479492
if (pdata->rstc)
480493
reset_control_deassert(pdata->rstc);

0 commit comments

Comments
 (0)