]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.16.3/spi-omap2-mcspi-configure-hardware-when-slave-driver-changes-mode.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.16.3 / spi-omap2-mcspi-configure-hardware-when-slave-driver-changes-mode.patch
1 From 97ca0d6cc118716840ea443e010cb3d5f2d25eaf Mon Sep 17 00:00:00 2001
2 From: "Mark A. Greer" <mgreer@animalcreek.com>
3 Date: Tue, 1 Jul 2014 20:28:32 -0700
4 Subject: spi: omap2-mcspi: Configure hardware when slave driver changes mode
5
6 From: "Mark A. Greer" <mgreer@animalcreek.com>
7
8 commit 97ca0d6cc118716840ea443e010cb3d5f2d25eaf upstream.
9
10 Commit id 2bd16e3e23d9df41592c6b257c59b6860a9cc3ea
11 (spi: omap2-mcspi: Do not configure the controller
12 on each transfer unless needed) does its job too
13 well so omap2_mcspi_setup_transfer() isn't called
14 even when an SPI slave driver changes 'spi->mode'.
15 The result is that the mode requested by the SPI
16 slave driver never takes effect.
17
18 Fix this by adding the 'mode' member to the
19 omap2_mcspi_cs structure which holds the mode
20 value that the hardware is configured for.
21 When the SPI slave driver changes 'spi->mode'
22 it will be different than the value of this new
23 member and the SPI master driver will know that
24 the hardware must be reconfigured (by calling
25 omap2_mcspi_setup_transfer()).
26
27 Fixes: 2bd16e3e23 (spi: omap2-mcspi: Do not configure the controller on each transfer unless needed)
28 Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
29 Signed-off-by: Mark Brown <broonie@linaro.org>
30 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31
32 ---
33 drivers/spi/spi-omap2-mcspi.c | 14 ++++++++++++++
34 1 file changed, 14 insertions(+)
35
36 --- a/drivers/spi/spi-omap2-mcspi.c
37 +++ b/drivers/spi/spi-omap2-mcspi.c
38 @@ -149,6 +149,7 @@ struct omap2_mcspi_cs {
39 void __iomem *base;
40 unsigned long phys;
41 int word_len;
42 + u16 mode;
43 struct list_head node;
44 /* Context save and restore shadow register */
45 u32 chconf0, chctrl0;
46 @@ -926,6 +927,8 @@ static int omap2_mcspi_setup_transfer(st
47
48 mcspi_write_chconf0(spi, l);
49
50 + cs->mode = spi->mode;
51 +
52 dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
53 speed_hz,
54 (spi->mode & SPI_CPHA) ? "trailing" : "leading",
55 @@ -998,6 +1001,7 @@ static int omap2_mcspi_setup(struct spi_
56 return -ENOMEM;
57 cs->base = mcspi->base + spi->chip_select * 0x14;
58 cs->phys = mcspi->phys + spi->chip_select * 0x14;
59 + cs->mode = 0;
60 cs->chconf0 = 0;
61 cs->chctrl0 = 0;
62 spi->controller_state = cs;
63 @@ -1079,6 +1083,16 @@ static void omap2_mcspi_work(struct omap
64 cs = spi->controller_state;
65 cd = spi->controller_data;
66
67 + /*
68 + * The slave driver could have changed spi->mode in which case
69 + * it will be different from cs->mode (the current hardware setup).
70 + * If so, set par_override (even though its not a parity issue) so
71 + * omap2_mcspi_setup_transfer will be called to configure the hardware
72 + * with the correct mode on the first iteration of the loop below.
73 + */
74 + if (spi->mode != cs->mode)
75 + par_override = 1;
76 +
77 omap2_mcspi_set_enable(spi, 0);
78 list_for_each_entry(t, &m->transfers, transfer_list) {
79 if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {