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