ar71xx: move the watchdog driver to the kernel
[openwrt/svn-archive/archive.git] / target / linux / ar71xx / patches-3.8 / 005-spi-ath79-avoid-multiple-initialization-of-the-SPI-c.patch
1 From d731c08cf1d264fd6113b9a97790c5a3a86ea520 Mon Sep 17 00:00:00 2001
2 From: Gabor Juhos <juhosg@openwrt.org>
3 Date: Thu, 27 Dec 2012 10:42:28 +0100
4 Subject: [PATCH] spi/ath79: avoid multiple initialization of the SPI
5 controller
6
7 commit c4a31f43005512b366e8bfc346e7f14c1a7a1ba7 upstream.
8
9 Currently we are initializing the SPI controller in
10 the chip select line function, and that function is
11 called once for each SPI device on the bus. If a
12 board has multiple SPI devices, the controller will
13 be initialized multiple times.
14
15 Introduce ath79_spi_{en,dis}able helper functions,
16 and call those from probe/response in order to avoid
17 the mutliple initialization of the controller.
18
19 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
20 Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
21 ---
22 drivers/spi/spi-ath79.c | 41 ++++++++++++++++++++++++-----------------
23 1 file changed, 24 insertions(+), 17 deletions(-)
24
25 --- a/drivers/spi/spi-ath79.c
26 +++ b/drivers/spi/spi-ath79.c
27 @@ -96,16 +96,8 @@ static void ath79_spi_chipselect(struct
28
29 }
30
31 -static int ath79_spi_setup_cs(struct spi_device *spi)
32 +static void ath79_spi_enable(struct ath79_spi *sp)
33 {
34 - struct ath79_spi *sp = ath79_spidev_to_sp(spi);
35 - struct ath79_spi_controller_data *cdata;
36 - int status;
37 -
38 - cdata = spi->controller_data;
39 - if (spi->chip_select && !cdata)
40 - return -EINVAL;
41 -
42 /* enable GPIO mode */
43 ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
44
45 @@ -115,6 +107,24 @@ static int ath79_spi_setup_cs(struct spi
46
47 /* TODO: setup speed? */
48 ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
49 +}
50 +
51 +static void ath79_spi_disable(struct ath79_spi *sp)
52 +{
53 + /* restore CTRL register */
54 + ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
55 + /* disable GPIO mode */
56 + ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
57 +}
58 +
59 +static int ath79_spi_setup_cs(struct spi_device *spi)
60 +{
61 + struct ath79_spi_controller_data *cdata;
62 + int status;
63 +
64 + cdata = spi->controller_data;
65 + if (spi->chip_select && !cdata)
66 + return -EINVAL;
67
68 status = 0;
69 if (spi->chip_select) {
70 @@ -135,17 +145,10 @@ static int ath79_spi_setup_cs(struct spi
71
72 static void ath79_spi_cleanup_cs(struct spi_device *spi)
73 {
74 - struct ath79_spi *sp = ath79_spidev_to_sp(spi);
75 -
76 if (spi->chip_select) {
77 struct ath79_spi_controller_data *cdata = spi->controller_data;
78 gpio_free(cdata->gpio);
79 }
80 -
81 - /* restore CTRL register */
82 - ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
83 - /* disable GPIO mode */
84 - ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
85 }
86
87 static int ath79_spi_setup(struct spi_device *spi)
88 @@ -268,12 +271,15 @@ static int ath79_spi_probe(struct platfo
89 dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n",
90 sp->rrw_delay);
91
92 + ath79_spi_enable(sp);
93 ret = spi_bitbang_start(&sp->bitbang);
94 if (ret)
95 - goto err_clk_disable;
96 + goto err_disable;
97
98 return 0;
99
100 +err_disable:
101 + ath79_spi_disable(sp);
102 err_clk_disable:
103 clk_disable(sp->clk);
104 err_clk_put:
105 @@ -292,6 +298,7 @@ static int ath79_spi_remove(struct platf
106 struct ath79_spi *sp = platform_get_drvdata(pdev);
107
108 spi_bitbang_stop(&sp->bitbang);
109 + ath79_spi_disable(sp);
110 clk_disable(sp->clk);
111 clk_put(sp->clk);
112 iounmap(sp->base);