1 From b61249080d5492fdb4bcf22e1672dc773a9bd95a Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Mon, 11 Apr 2016 12:50:58 +0100
4 Subject: [PATCH] bcm2835-sdhost: Reset the clock in task context
6 Since reprogramming the clock can now involve a round-trip to the
7 firmware it must not be done at atomic context, and a tasklet
10 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
12 drivers/mmc/host/bcm2835-sdhost.c | 25 ++++++++++++++++++-------
13 1 file changed, 18 insertions(+), 7 deletions(-)
15 --- a/drivers/mmc/host/bcm2835-sdhost.c
16 +++ b/drivers/mmc/host/bcm2835-sdhost.c
17 @@ -185,6 +185,7 @@ struct bcm2835_host {
19 unsigned int debug:1; /* Enable debug output */
20 unsigned int firmware_sets_cdiv:1; /* Let the firmware manage the clock */
21 + unsigned int reset_clock:1; /* Reset the clock fore the next request */
24 struct dma_chan *dma_chan_rxtx; /* DMA channel for reads and writes */
25 @@ -1505,6 +1506,7 @@ void bcm2835_sdhost_set_clock(struct bcm
27 int div = 0; /* Initialized for compiler warning */
28 unsigned int input_clock = clock;
29 + unsigned long flags;
32 pr_info("%s: set_clock(%d)\n", mmc_hostname(host->mmc), clock);
33 @@ -1544,13 +1546,17 @@ void bcm2835_sdhost_set_clock(struct bcm
36 clock = max(msg[1], msg[2]);
37 + spin_lock_irqsave(&host->lock, flags);
39 + spin_lock_irqsave(&host->lock, flags);
41 /* Can't stop the clock, but make it as slow as
42 * possible to show willing
44 host->cdiv = SDCDIV_MAX_CDIV;
45 bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
47 + spin_unlock_irqrestore(&host->lock, flags);
51 @@ -1605,6 +1611,11 @@ void bcm2835_sdhost_set_clock(struct bcm
52 bcm2835_sdhost_write(host, clock/2, SDTOUT);
54 host->mmc->actual_clock = clock;
55 + host->clock = input_clock;
56 + host->reset_clock = 0;
59 + spin_unlock_irqrestore(&host->lock, flags);
62 static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
63 @@ -1653,6 +1664,9 @@ static void bcm2835_sdhost_request(struc
64 (mrq->data->blocks > host->pio_limit))
65 bcm2835_sdhost_prepare_dma(host, mrq->data);
67 + if (host->reset_clock)
68 + bcm2835_sdhost_set_clock(host, host->clock);
70 spin_lock_irqsave(&host->lock, flags);
72 WARN_ON(host->mrq != NULL);
73 @@ -1731,14 +1745,12 @@ static void bcm2835_sdhost_set_ios(struc
75 bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
77 - if (!ios->clock || ios->clock != host->clock) {
78 - bcm2835_sdhost_set_clock(host, ios->clock);
79 - host->clock = ios->clock;
84 spin_unlock_irqrestore(&host->lock, flags);
86 + if (!ios->clock || ios->clock != host->clock)
87 + bcm2835_sdhost_set_clock(host, ios->clock);
90 static struct mmc_host_ops bcm2835_sdhost_ops = {
91 @@ -1810,7 +1822,7 @@ static void bcm2835_sdhost_tasklet_finis
93 pr_warn("%s: reducing overclock due to errors\n",
94 mmc_hostname(host->mmc));
95 - bcm2835_sdhost_set_clock(host,50*MHZ);
96 + host->reset_clock = 1;
97 mrq->cmd->error = -EILSEQ;
98 mrq->cmd->retries = 1;
100 @@ -1979,7 +1991,6 @@ static int bcm2835_sdhost_probe(struct p
101 mmc->ops = &bcm2835_sdhost_ops;
102 host = mmc_priv(mmc);
104 - host->cmd_quick_poll_retries = 0;
105 host->pio_timeout = msecs_to_jiffies(500);
107 host->max_delay = 1; /* Warn if over 1ms */