ar71xx: improve SPI flash read/write performance
[openwrt/svn-archive/archive.git] / target / linux / ar71xx / patches-3.2 / 205-spi-ath79-avoid-multiple-initialization-of-the-SPI-c.patch
1 From 25e681989198e94656eab9df22b8b761abd2ae26 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 5/7] 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 @@ -271,12 +274,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 @@ -295,6 +301,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);