aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/spi-bcm63xx.c149
1 files changed, 89 insertions, 60 deletions
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index f01b2648452e..63b0028a8bd3 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Broadcom BCM63xx SPI controller support 2 * Broadcom BCM63xx SPI controller support
3 * 3 *
4 * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org> 4 * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
5 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com> 5 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
@@ -30,6 +30,8 @@
30#include <linux/spi/spi.h> 30#include <linux/spi/spi.h>
31#include <linux/completion.h> 31#include <linux/completion.h>
32#include <linux/err.h> 32#include <linux/err.h>
33#include <linux/workqueue.h>
34#include <linux/pm_runtime.h>
33 35
34#include <bcm63xx_dev_spi.h> 36#include <bcm63xx_dev_spi.h>
35 37
@@ -96,17 +98,12 @@ static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
96 { 391000, SPI_CLK_0_391MHZ } 98 { 391000, SPI_CLK_0_391MHZ }
97}; 99};
98 100
99static int bcm63xx_spi_setup_transfer(struct spi_device *spi, 101static int bcm63xx_spi_check_transfer(struct spi_device *spi,
100 struct spi_transfer *t) 102 struct spi_transfer *t)
101{ 103{
102 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
103 u8 bits_per_word; 104 u8 bits_per_word;
104 u8 clk_cfg, reg;
105 u32 hz;
106 int i;
107 105
108 bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; 106 bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
109 hz = (t) ? t->speed_hz : spi->max_speed_hz;
110 if (bits_per_word != 8) { 107 if (bits_per_word != 8) {
111 dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", 108 dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
112 __func__, bits_per_word); 109 __func__, bits_per_word);
@@ -119,6 +116,19 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
119 return -EINVAL; 116 return -EINVAL;
120 } 117 }
121 118
119 return 0;
120}
121
122static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
123 struct spi_transfer *t)
124{
125 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
126 u32 hz;
127 u8 clk_cfg, reg;
128 int i;
129
130 hz = (t) ? t->speed_hz : spi->max_speed_hz;
131
122 /* Find the closest clock configuration */ 132 /* Find the closest clock configuration */
123 for (i = 0; i < SPI_CLK_MASK; i++) { 133 for (i = 0; i < SPI_CLK_MASK; i++) {
124 if (hz <= bcm63xx_spi_freq_table[i][0]) { 134 if (hz <= bcm63xx_spi_freq_table[i][0]) {
@@ -139,8 +149,6 @@ static int bcm63xx_spi_setup_transfer(struct spi_device *spi,
139 bcm_spi_writeb(bs, reg, SPI_CLK_CFG); 149 bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
140 dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n", 150 dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
141 clk_cfg, hz); 151 clk_cfg, hz);
142
143 return 0;
144} 152}
145 153
146/* the spi->mode bits understood by this driver: */ 154/* the spi->mode bits understood by this driver: */
@@ -165,7 +173,7 @@ static int bcm63xx_spi_setup(struct spi_device *spi)
165 return -EINVAL; 173 return -EINVAL;
166 } 174 }
167 175
168 ret = bcm63xx_spi_setup_transfer(spi, NULL); 176 ret = bcm63xx_spi_check_transfer(spi, NULL);
169 if (ret < 0) { 177 if (ret < 0) {
170 dev_err(&spi->dev, "setup: unsupported mode bits %x\n", 178 dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
171 spi->mode & ~MODEBITS); 179 spi->mode & ~MODEBITS);
@@ -190,28 +198,29 @@ static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
190 bs->remaining_bytes -= size; 198 bs->remaining_bytes -= size;
191} 199}
192 200
193static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) 201static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
202 struct spi_transfer *t)
194{ 203{
195 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); 204 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
196 u16 msg_ctl; 205 u16 msg_ctl;
197 u16 cmd; 206 u16 cmd;
198 207
208 /* Disable the CMD_DONE interrupt */
209 bcm_spi_writeb(bs, 0, SPI_INT_MASK);
210
199 dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", 211 dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
200 t->tx_buf, t->rx_buf, t->len); 212 t->tx_buf, t->rx_buf, t->len);
201 213
202 /* Transmitter is inhibited */ 214 /* Transmitter is inhibited */
203 bs->tx_ptr = t->tx_buf; 215 bs->tx_ptr = t->tx_buf;
204 bs->rx_ptr = t->rx_buf; 216 bs->rx_ptr = t->rx_buf;
205 init_completion(&bs->done);
206 217
207 if (t->tx_buf) { 218 if (t->tx_buf) {
208 bs->remaining_bytes = t->len; 219 bs->remaining_bytes = t->len;
209 bcm63xx_spi_fill_tx_fifo(bs); 220 bcm63xx_spi_fill_tx_fifo(bs);
210 } 221 }
211 222
212 /* Enable the command done interrupt which 223 init_completion(&bs->done);
213 * we use to determine completion of a command */
214 bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
215 224
216 /* Fill in the Message control register */ 225 /* Fill in the Message control register */
217 msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); 226 msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
@@ -230,33 +239,76 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
230 cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); 239 cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
231 cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT); 240 cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
232 bcm_spi_writew(bs, cmd, SPI_CMD); 241 bcm_spi_writew(bs, cmd, SPI_CMD);
233 wait_for_completion(&bs->done);
234 242
235 /* Disable the CMD_DONE interrupt */ 243 /* Enable the CMD_DONE interrupt */
236 bcm_spi_writeb(bs, 0, SPI_INT_MASK); 244 bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
237 245
238 return t->len - bs->remaining_bytes; 246 return t->len - bs->remaining_bytes;
239} 247}
240 248
241static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m) 249static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
242{ 250{
243 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); 251 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
244 struct spi_transfer *t;
245 int ret = 0;
246 252
247 if (unlikely(list_empty(&m->transfers))) 253 pm_runtime_get_sync(&bs->pdev->dev);
248 return -EINVAL;
249 254
250 if (bs->stopping) 255 return 0;
251 return -ESHUTDOWN; 256}
257
258static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
259{
260 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
261
262 pm_runtime_put(&bs->pdev->dev);
263
264 return 0;
265}
266
267static int bcm63xx_spi_transfer_one(struct spi_master *master,
268 struct spi_message *m)
269{
270 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
271 struct spi_transfer *t;
272 struct spi_device *spi = m->spi;
273 int status = 0;
274 unsigned int timeout = 0;
252 275
253 list_for_each_entry(t, &m->transfers, transfer_list) { 276 list_for_each_entry(t, &m->transfers, transfer_list) {
254 ret += bcm63xx_txrx_bufs(spi, t); 277 unsigned int len = t->len;
255 } 278 u8 rx_tail;
256 279
257 m->complete(m->context); 280 status = bcm63xx_spi_check_transfer(spi, t);
281 if (status < 0)
282 goto exit;
258 283
259 return ret; 284 /* configure adapter for a new transfer */
285 bcm63xx_spi_setup_transfer(spi, t);
286
287 while (len) {
288 /* send the data */
289 len -= bcm63xx_txrx_bufs(spi, t);
290
291 timeout = wait_for_completion_timeout(&bs->done, HZ);
292 if (!timeout) {
293 status = -ETIMEDOUT;
294 goto exit;
295 }
296
297 /* read out all data */
298 rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
299
300 /* Read out all the data */
301 if (rx_tail)
302 memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
303 }
304
305 m->actual_length += t->len;
306 }
307exit:
308 m->status = status;
309 spi_finalize_current_message(master);
310
311 return 0;
260} 312}
261 313
262/* This driver supports single master mode only. Hence 314/* This driver supports single master mode only. Hence
@@ -267,39 +319,15 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
267 struct spi_master *master = (struct spi_master *)dev_id; 319 struct spi_master *master = (struct spi_master *)dev_id;
268 struct bcm63xx_spi *bs = spi_master_get_devdata(master); 320 struct bcm63xx_spi *bs = spi_master_get_devdata(master);
269 u8 intr; 321 u8 intr;
270 u16 cmd;
271 322
272 /* Read interupts and clear them immediately */ 323 /* Read interupts and clear them immediately */
273 intr = bcm_spi_readb(bs, SPI_INT_STATUS); 324 intr = bcm_spi_readb(bs, SPI_INT_STATUS);
274 bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); 325 bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
275 bcm_spi_writeb(bs, 0, SPI_INT_MASK); 326 bcm_spi_writeb(bs, 0, SPI_INT_MASK);
276 327
277 /* A tansfer completed */ 328 /* A transfer completed */
278 if (intr & SPI_INTR_CMD_DONE) { 329 if (intr & SPI_INTR_CMD_DONE)
279 u8 rx_tail; 330 complete(&bs->done);
280
281 rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
282
283 /* Read out all the data */
284 if (rx_tail)
285 memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
286
287 /* See if there is more data to send */
288 if (bs->remaining_bytes > 0) {
289 bcm63xx_spi_fill_tx_fifo(bs);
290
291 /* Start the transfer */
292 bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT,
293 SPI_MSG_CTL);
294 cmd = bcm_spi_readw(bs, SPI_CMD);
295 cmd |= SPI_CMD_START_IMMEDIATE;
296 cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
297 bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
298 bcm_spi_writew(bs, cmd, SPI_CMD);
299 } else {
300 complete(&bs->done);
301 }
302 }
303 331
304 return IRQ_HANDLED; 332 return IRQ_HANDLED;
305} 333}
@@ -345,7 +373,6 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
345 } 373 }
346 374
347 bs = spi_master_get_devdata(master); 375 bs = spi_master_get_devdata(master);
348 init_completion(&bs->done);
349 376
350 platform_set_drvdata(pdev, master); 377 platform_set_drvdata(pdev, master);
351 bs->pdev = pdev; 378 bs->pdev = pdev;
@@ -379,7 +406,9 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)
379 master->bus_num = pdata->bus_num; 406 master->bus_num = pdata->bus_num;
380 master->num_chipselect = pdata->num_chipselect; 407 master->num_chipselect = pdata->num_chipselect;
381 master->setup = bcm63xx_spi_setup; 408 master->setup = bcm63xx_spi_setup;
382 master->transfer = bcm63xx_transfer; 409 master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
410 master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
411 master->transfer_one_message = bcm63xx_spi_transfer_one;
383 bs->speed_hz = pdata->speed_hz; 412 bs->speed_hz = pdata->speed_hz;
384 bs->stopping = 0; 413 bs->stopping = 0;
385 bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); 414 bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));