brcm2708: update linux 4.4 patches to latest version
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0234-bcm2835-sdhost-Reset-the-clock-in-task-context.patch
1 From d17f0605ff4b3197eb6667368adc07c5ca859679 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
5
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
8 is not a task.
9
10 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
11 ---
12 drivers/mmc/host/bcm2835-sdhost.c | 25 ++++++++++++++++++-------
13 1 file changed, 18 insertions(+), 7 deletions(-)
14
15 --- a/drivers/mmc/host/bcm2835-sdhost.c
16 +++ b/drivers/mmc/host/bcm2835-sdhost.c
17 @@ -185,6 +185,7 @@ struct bcm2835_host {
18
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 */
22
23 /*DMA part*/
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
26 {
27 int div = 0; /* Initialized for compiler warning */
28 unsigned int input_clock = clock;
29 + unsigned long flags;
30
31 if (host->debug)
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
34 &msg, sizeof(msg));
35
36 clock = max(msg[1], msg[2]);
37 + spin_lock_irqsave(&host->lock, flags);
38 } else {
39 + spin_lock_irqsave(&host->lock, flags);
40 if (clock < 100000) {
41 /* Can't stop the clock, but make it as slow as
42 * possible to show willing
43 */
44 host->cdiv = SDCDIV_MAX_CDIV;
45 bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
46 + mmiowb();
47 + spin_unlock_irqrestore(&host->lock, flags);
48 return;
49 }
50
51 @@ -1605,6 +1611,11 @@ void bcm2835_sdhost_set_clock(struct bcm
52 bcm2835_sdhost_write(host, clock/2, SDTOUT);
53
54 host->mmc->actual_clock = clock;
55 + host->clock = input_clock;
56 + host->reset_clock = 0;
57 +
58 + mmiowb();
59 + spin_unlock_irqrestore(&host->lock, flags);
60 }
61
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);
66
67 + if (host->reset_clock)
68 + bcm2835_sdhost_set_clock(host, host->clock);
69 +
70 spin_lock_irqsave(&host->lock, flags);
71
72 WARN_ON(host->mrq != NULL);
73 @@ -1731,14 +1745,12 @@ static void bcm2835_sdhost_set_ios(struc
74
75 bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
76
77 - if (!ios->clock || ios->clock != host->clock) {
78 - bcm2835_sdhost_set_clock(host, ios->clock);
79 - host->clock = ios->clock;
80 - }
81 -
82 mmiowb();
83
84 spin_unlock_irqrestore(&host->lock, flags);
85 +
86 + if (!ios->clock || ios->clock != host->clock)
87 + bcm2835_sdhost_set_clock(host, ios->clock);
88 }
89
90 static struct mmc_host_ops bcm2835_sdhost_ops = {
91 @@ -1810,7 +1822,7 @@ static void bcm2835_sdhost_tasklet_finis
92 host->overclock_50--;
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;
99 }
100 @@ -1979,7 +1991,6 @@ static int bcm2835_sdhost_probe(struct p
101 mmc->ops = &bcm2835_sdhost_ops;
102 host = mmc_priv(mmc);
103 host->mmc = mmc;
104 - host->cmd_quick_poll_retries = 0;
105 host->pio_timeout = msecs_to_jiffies(500);
106 host->pio_limit = 1;
107 host->max_delay = 1; /* Warn if over 1ms */