aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabor Juhos <juhosg@openwrt.org>2012-12-27 04:42:28 -0500
committerGrant Likely <grant.likely@secretlab.ca>2013-02-05 07:59:47 -0500
commitc4a31f43005512b366e8bfc346e7f14c1a7a1ba7 (patch)
treeb1f49e52ffc5abc0563480bd8ac36cae142ef5d4
parent95d79419feffb326a3d5cb50e2248129dec06bb0 (diff)
spi/ath79: avoid multiple initialization of the SPI controller
Currently we are initializing the SPI controller in the chip select line function, and that function is called once for each SPI device on the bus. If a board has multiple SPI devices, the controller will be initialized multiple times. Introduce ath79_spi_{en,dis}able helper functions, and call those from probe/response in order to avoid the mutliple initialization of the controller. Signed-off-by: Gabor Juhos <juhosg@openwrt.org> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--drivers/spi/spi-ath79.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c
index 19d539e36300..842acd8983e6 100644
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -96,16 +96,8 @@ static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
96 96
97} 97}
98 98
99static int ath79_spi_setup_cs(struct spi_device *spi) 99static void ath79_spi_enable(struct ath79_spi *sp)
100{ 100{
101 struct ath79_spi *sp = ath79_spidev_to_sp(spi);
102 struct ath79_spi_controller_data *cdata;
103 int status;
104
105 cdata = spi->controller_data;
106 if (spi->chip_select && !cdata)
107 return -EINVAL;
108
109 /* enable GPIO mode */ 101 /* enable GPIO mode */
110 ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO); 102 ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
111 103
@@ -115,6 +107,24 @@ static int ath79_spi_setup_cs(struct spi_device *spi)
115 107
116 /* TODO: setup speed? */ 108 /* TODO: setup speed? */
117 ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43); 109 ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
110}
111
112static void ath79_spi_disable(struct ath79_spi *sp)
113{
114 /* restore CTRL register */
115 ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
116 /* disable GPIO mode */
117 ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
118}
119
120static int ath79_spi_setup_cs(struct spi_device *spi)
121{
122 struct ath79_spi_controller_data *cdata;
123 int status;
124
125 cdata = spi->controller_data;
126 if (spi->chip_select && !cdata)
127 return -EINVAL;
118 128
119 status = 0; 129 status = 0;
120 if (spi->chip_select) { 130 if (spi->chip_select) {
@@ -135,17 +145,10 @@ static int ath79_spi_setup_cs(struct spi_device *spi)
135 145
136static void ath79_spi_cleanup_cs(struct spi_device *spi) 146static void ath79_spi_cleanup_cs(struct spi_device *spi)
137{ 147{
138 struct ath79_spi *sp = ath79_spidev_to_sp(spi);
139
140 if (spi->chip_select) { 148 if (spi->chip_select) {
141 struct ath79_spi_controller_data *cdata = spi->controller_data; 149 struct ath79_spi_controller_data *cdata = spi->controller_data;
142 gpio_free(cdata->gpio); 150 gpio_free(cdata->gpio);
143 } 151 }
144
145 /* restore CTRL register */
146 ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
147 /* disable GPIO mode */
148 ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
149} 152}
150 153
151static int ath79_spi_setup(struct spi_device *spi) 154static int ath79_spi_setup(struct spi_device *spi)
@@ -268,12 +271,15 @@ static int ath79_spi_probe(struct platform_device *pdev)
268 dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n", 271 dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n",
269 sp->rrw_delay); 272 sp->rrw_delay);
270 273
274 ath79_spi_enable(sp);
271 ret = spi_bitbang_start(&sp->bitbang); 275 ret = spi_bitbang_start(&sp->bitbang);
272 if (ret) 276 if (ret)
273 goto err_clk_disable; 277 goto err_disable;
274 278
275 return 0; 279 return 0;
276 280
281err_disable:
282 ath79_spi_disable(sp);
277err_clk_disable: 283err_clk_disable:
278 clk_disable(sp->clk); 284 clk_disable(sp->clk);
279err_clk_put: 285err_clk_put:
@@ -292,6 +298,7 @@ static int ath79_spi_remove(struct platform_device *pdev)
292 struct ath79_spi *sp = platform_get_drvdata(pdev); 298 struct ath79_spi *sp = platform_get_drvdata(pdev);
293 299
294 spi_bitbang_stop(&sp->bitbang); 300 spi_bitbang_stop(&sp->bitbang);
301 ath79_spi_disable(sp);
295 clk_disable(sp->clk); 302 clk_disable(sp->clk);
296 clk_put(sp->clk); 303 clk_put(sp->clk);
297 iounmap(sp->base); 304 iounmap(sp->base);