aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-dw.c1
-rw-r--r--drivers/spi/spi-orion.c2
-rw-r--r--drivers/spi/spi-pl022.c2
-rw-r--r--drivers/spi/spi-rockchip.c50
-rw-r--r--drivers/spi/spidev.c79
5 files changed, 93 insertions, 41 deletions
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 729215885250..72e12bad14b9 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -669,6 +669,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
669 master->cleanup = dw_spi_cleanup; 669 master->cleanup = dw_spi_cleanup;
670 master->transfer_one_message = dw_spi_transfer_one_message; 670 master->transfer_one_message = dw_spi_transfer_one_message;
671 master->max_speed_hz = dws->max_freq; 671 master->max_speed_hz = dws->max_freq;
672 master->dev.of_node = dev->of_node;
672 673
673 /* Basic HW init */ 674 /* Basic HW init */
674 spi_hw_init(dws); 675 spi_hw_init(dws);
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index 835cdda6f4f5..c76b7d7879df 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -454,7 +454,7 @@ static int orion_spi_probe(struct platform_device *pdev)
454 spi->master = master; 454 spi->master = master;
455 455
456 of_id = of_match_device(orion_spi_of_match_table, &pdev->dev); 456 of_id = of_match_device(orion_spi_of_match_table, &pdev->dev);
457 devdata = of_id->data; 457 devdata = (of_id) ? of_id->data : &orion_spi_dev_data;
458 spi->devdata = devdata; 458 spi->devdata = devdata;
459 459
460 spi->clk = devm_clk_get(&pdev->dev, NULL); 460 spi->clk = devm_clk_get(&pdev->dev, NULL);
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index f35f723816ea..fc2dd8441608 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1106,7 +1106,7 @@ err_rxdesc:
1106 pl022->sgt_tx.nents, DMA_TO_DEVICE); 1106 pl022->sgt_tx.nents, DMA_TO_DEVICE);
1107err_tx_sgmap: 1107err_tx_sgmap:
1108 dma_unmap_sg(rxchan->device->dev, pl022->sgt_rx.sgl, 1108 dma_unmap_sg(rxchan->device->dev, pl022->sgt_rx.sgl,
1109 pl022->sgt_tx.nents, DMA_FROM_DEVICE); 1109 pl022->sgt_rx.nents, DMA_FROM_DEVICE);
1110err_rx_sgmap: 1110err_rx_sgmap:
1111 sg_free_table(&pl022->sgt_tx); 1111 sg_free_table(&pl022->sgt_tx);
1112err_alloc_tx_sg: 1112err_alloc_tx_sg:
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index f96ea8a38d64..87bc16f491f0 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -145,6 +145,9 @@
145#define RXBUSY (1 << 0) 145#define RXBUSY (1 << 0)
146#define TXBUSY (1 << 1) 146#define TXBUSY (1 << 1)
147 147
148/* sclk_out: spi master internal logic in rk3x can support 50Mhz */
149#define MAX_SCLK_OUT 50000000
150
148enum rockchip_ssi_type { 151enum rockchip_ssi_type {
149 SSI_MOTO_SPI = 0, 152 SSI_MOTO_SPI = 0,
150 SSI_TI_SSP, 153 SSI_TI_SSP,
@@ -325,6 +328,8 @@ static int rockchip_spi_unprepare_message(struct spi_master *master,
325 328
326 spin_unlock_irqrestore(&rs->lock, flags); 329 spin_unlock_irqrestore(&rs->lock, flags);
327 330
331 spi_enable_chip(rs, 0);
332
328 return 0; 333 return 0;
329} 334}
330 335
@@ -381,6 +386,8 @@ static int rockchip_spi_pio_transfer(struct rockchip_spi *rs)
381 if (rs->tx) 386 if (rs->tx)
382 wait_for_idle(rs); 387 wait_for_idle(rs);
383 388
389 spi_enable_chip(rs, 0);
390
384 return 0; 391 return 0;
385} 392}
386 393
@@ -392,8 +399,10 @@ static void rockchip_spi_dma_rxcb(void *data)
392 spin_lock_irqsave(&rs->lock, flags); 399 spin_lock_irqsave(&rs->lock, flags);
393 400
394 rs->state &= ~RXBUSY; 401 rs->state &= ~RXBUSY;
395 if (!(rs->state & TXBUSY)) 402 if (!(rs->state & TXBUSY)) {
403 spi_enable_chip(rs, 0);
396 spi_finalize_current_transfer(rs->master); 404 spi_finalize_current_transfer(rs->master);
405 }
397 406
398 spin_unlock_irqrestore(&rs->lock, flags); 407 spin_unlock_irqrestore(&rs->lock, flags);
399} 408}
@@ -409,8 +418,10 @@ static void rockchip_spi_dma_txcb(void *data)
409 spin_lock_irqsave(&rs->lock, flags); 418 spin_lock_irqsave(&rs->lock, flags);
410 419
411 rs->state &= ~TXBUSY; 420 rs->state &= ~TXBUSY;
412 if (!(rs->state & RXBUSY)) 421 if (!(rs->state & RXBUSY)) {
422 spi_enable_chip(rs, 0);
413 spi_finalize_current_transfer(rs->master); 423 spi_finalize_current_transfer(rs->master);
424 }
414 425
415 spin_unlock_irqrestore(&rs->lock, flags); 426 spin_unlock_irqrestore(&rs->lock, flags);
416} 427}
@@ -496,12 +507,19 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
496 dmacr |= RF_DMA_EN; 507 dmacr |= RF_DMA_EN;
497 } 508 }
498 509
510 if (WARN_ON(rs->speed > MAX_SCLK_OUT))
511 rs->speed = MAX_SCLK_OUT;
512
513 /* the minimum divsor is 2 */
514 if (rs->max_freq < 2 * rs->speed) {
515 clk_set_rate(rs->spiclk, 2 * rs->speed);
516 rs->max_freq = clk_get_rate(rs->spiclk);
517 }
518
499 /* div doesn't support odd number */ 519 /* div doesn't support odd number */
500 div = max_t(u32, rs->max_freq / rs->speed, 1); 520 div = max_t(u32, rs->max_freq / rs->speed, 1);
501 div = (div + 1) & 0xfffe; 521 div = (div + 1) & 0xfffe;
502 522
503 spi_enable_chip(rs, 0);
504
505 writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0); 523 writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
506 524
507 writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1); 525 writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
@@ -515,8 +533,6 @@ static void rockchip_spi_config(struct rockchip_spi *rs)
515 spi_set_clk(rs, div); 533 spi_set_clk(rs, div);
516 534
517 dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div); 535 dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div);
518
519 spi_enable_chip(rs, 1);
520} 536}
521 537
522static int rockchip_spi_transfer_one( 538static int rockchip_spi_transfer_one(
@@ -524,7 +540,7 @@ static int rockchip_spi_transfer_one(
524 struct spi_device *spi, 540 struct spi_device *spi,
525 struct spi_transfer *xfer) 541 struct spi_transfer *xfer)
526{ 542{
527 int ret = 0; 543 int ret = 1;
528 struct rockchip_spi *rs = spi_master_get_devdata(master); 544 struct rockchip_spi *rs = spi_master_get_devdata(master);
529 545
530 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && 546 WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
@@ -556,17 +572,27 @@ static int rockchip_spi_transfer_one(
556 rs->tmode = CR0_XFM_RO; 572 rs->tmode = CR0_XFM_RO;
557 573
558 /* we need prepare dma before spi was enabled */ 574 /* we need prepare dma before spi was enabled */
559 if (master->can_dma && master->can_dma(master, spi, xfer)) { 575 if (master->can_dma && master->can_dma(master, spi, xfer))
560 rs->use_dma = 1; 576 rs->use_dma = 1;
561 rockchip_spi_prepare_dma(rs); 577 else
562 } else {
563 rs->use_dma = 0; 578 rs->use_dma = 0;
564 }
565 579
566 rockchip_spi_config(rs); 580 rockchip_spi_config(rs);
567 581
568 if (!rs->use_dma) 582 if (rs->use_dma) {
583 if (rs->tmode == CR0_XFM_RO) {
584 /* rx: dma must be prepared first */
585 rockchip_spi_prepare_dma(rs);
586 spi_enable_chip(rs, 1);
587 } else {
588 /* tx or tr: spi must be enabled first */
589 spi_enable_chip(rs, 1);
590 rockchip_spi_prepare_dma(rs);
591 }
592 } else {
593 spi_enable_chip(rs, 1);
569 ret = rockchip_spi_pio_transfer(rs); 594 ret = rockchip_spi_pio_transfer(rs);
595 }
570 596
571 return ret; 597 return ret;
572} 598}
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index e3bc23bb5883..e50039fb1474 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -82,10 +82,11 @@ struct spidev_data {
82 struct spi_device *spi; 82 struct spi_device *spi;
83 struct list_head device_entry; 83 struct list_head device_entry;
84 84
85 /* buffer is NULL unless this device is open (users > 0) */ 85 /* TX/RX buffers are NULL unless this device is open (users > 0) */
86 struct mutex buf_lock; 86 struct mutex buf_lock;
87 unsigned users; 87 unsigned users;
88 u8 *buffer; 88 u8 *tx_buffer;
89 u8 *rx_buffer;
89}; 90};
90 91
91static LIST_HEAD(device_list); 92static LIST_HEAD(device_list);
@@ -135,7 +136,7 @@ static inline ssize_t
135spidev_sync_write(struct spidev_data *spidev, size_t len) 136spidev_sync_write(struct spidev_data *spidev, size_t len)
136{ 137{
137 struct spi_transfer t = { 138 struct spi_transfer t = {
138 .tx_buf = spidev->buffer, 139 .tx_buf = spidev->tx_buffer,
139 .len = len, 140 .len = len,
140 }; 141 };
141 struct spi_message m; 142 struct spi_message m;
@@ -149,7 +150,7 @@ static inline ssize_t
149spidev_sync_read(struct spidev_data *spidev, size_t len) 150spidev_sync_read(struct spidev_data *spidev, size_t len)
150{ 151{
151 struct spi_transfer t = { 152 struct spi_transfer t = {
152 .rx_buf = spidev->buffer, 153 .rx_buf = spidev->rx_buffer,
153 .len = len, 154 .len = len,
154 }; 155 };
155 struct spi_message m; 156 struct spi_message m;
@@ -179,7 +180,7 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
179 if (status > 0) { 180 if (status > 0) {
180 unsigned long missing; 181 unsigned long missing;
181 182
182 missing = copy_to_user(buf, spidev->buffer, status); 183 missing = copy_to_user(buf, spidev->rx_buffer, status);
183 if (missing == status) 184 if (missing == status)
184 status = -EFAULT; 185 status = -EFAULT;
185 else 186 else
@@ -206,7 +207,7 @@ spidev_write(struct file *filp, const char __user *buf,
206 spidev = filp->private_data; 207 spidev = filp->private_data;
207 208
208 mutex_lock(&spidev->buf_lock); 209 mutex_lock(&spidev->buf_lock);
209 missing = copy_from_user(spidev->buffer, buf, count); 210 missing = copy_from_user(spidev->tx_buffer, buf, count);
210 if (missing == 0) 211 if (missing == 0)
211 status = spidev_sync_write(spidev, count); 212 status = spidev_sync_write(spidev, count);
212 else 213 else
@@ -224,7 +225,7 @@ static int spidev_message(struct spidev_data *spidev,
224 struct spi_transfer *k_tmp; 225 struct spi_transfer *k_tmp;
225 struct spi_ioc_transfer *u_tmp; 226 struct spi_ioc_transfer *u_tmp;
226 unsigned n, total; 227 unsigned n, total;
227 u8 *buf; 228 u8 *tx_buf, *rx_buf;
228 int status = -EFAULT; 229 int status = -EFAULT;
229 230
230 spi_message_init(&msg); 231 spi_message_init(&msg);
@@ -236,7 +237,8 @@ static int spidev_message(struct spidev_data *spidev,
236 * We walk the array of user-provided transfers, using each one 237 * We walk the array of user-provided transfers, using each one
237 * to initialize a kernel version of the same transfer. 238 * to initialize a kernel version of the same transfer.
238 */ 239 */
239 buf = spidev->buffer; 240 tx_buf = spidev->tx_buffer;
241 rx_buf = spidev->rx_buffer;
240 total = 0; 242 total = 0;
241 for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers; 243 for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
242 n; 244 n;
@@ -250,20 +252,21 @@ static int spidev_message(struct spidev_data *spidev,
250 } 252 }
251 253
252 if (u_tmp->rx_buf) { 254 if (u_tmp->rx_buf) {
253 k_tmp->rx_buf = buf; 255 k_tmp->rx_buf = rx_buf;
254 if (!access_ok(VERIFY_WRITE, (u8 __user *) 256 if (!access_ok(VERIFY_WRITE, (u8 __user *)
255 (uintptr_t) u_tmp->rx_buf, 257 (uintptr_t) u_tmp->rx_buf,
256 u_tmp->len)) 258 u_tmp->len))
257 goto done; 259 goto done;
258 } 260 }
259 if (u_tmp->tx_buf) { 261 if (u_tmp->tx_buf) {
260 k_tmp->tx_buf = buf; 262 k_tmp->tx_buf = tx_buf;
261 if (copy_from_user(buf, (const u8 __user *) 263 if (copy_from_user(tx_buf, (const u8 __user *)
262 (uintptr_t) u_tmp->tx_buf, 264 (uintptr_t) u_tmp->tx_buf,
263 u_tmp->len)) 265 u_tmp->len))
264 goto done; 266 goto done;
265 } 267 }
266 buf += k_tmp->len; 268 tx_buf += k_tmp->len;
269 rx_buf += k_tmp->len;
267 270
268 k_tmp->cs_change = !!u_tmp->cs_change; 271 k_tmp->cs_change = !!u_tmp->cs_change;
269 k_tmp->tx_nbits = u_tmp->tx_nbits; 272 k_tmp->tx_nbits = u_tmp->tx_nbits;
@@ -290,17 +293,17 @@ static int spidev_message(struct spidev_data *spidev,
290 goto done; 293 goto done;
291 294
292 /* copy any rx data out of bounce buffer */ 295 /* copy any rx data out of bounce buffer */
293 buf = spidev->buffer; 296 rx_buf = spidev->rx_buffer;
294 for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) { 297 for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) {
295 if (u_tmp->rx_buf) { 298 if (u_tmp->rx_buf) {
296 if (__copy_to_user((u8 __user *) 299 if (__copy_to_user((u8 __user *)
297 (uintptr_t) u_tmp->rx_buf, buf, 300 (uintptr_t) u_tmp->rx_buf, rx_buf,
298 u_tmp->len)) { 301 u_tmp->len)) {
299 status = -EFAULT; 302 status = -EFAULT;
300 goto done; 303 goto done;
301 } 304 }
302 } 305 }
303 buf += u_tmp->len; 306 rx_buf += u_tmp->len;
304 } 307 }
305 status = total; 308 status = total;
306 309
@@ -508,22 +511,41 @@ static int spidev_open(struct inode *inode, struct file *filp)
508 break; 511 break;
509 } 512 }
510 } 513 }
511 if (status == 0) { 514
512 if (!spidev->buffer) { 515 if (status) {
513 spidev->buffer = kmalloc(bufsiz, GFP_KERNEL); 516 pr_debug("spidev: nothing for minor %d\n", iminor(inode));
514 if (!spidev->buffer) { 517 goto err_find_dev;
518 }
519
520 if (!spidev->tx_buffer) {
521 spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL);
522 if (!spidev->tx_buffer) {
515 dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); 523 dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
516 status = -ENOMEM; 524 status = -ENOMEM;
525 goto err_find_dev;
517 } 526 }
518 } 527 }
519 if (status == 0) { 528
520 spidev->users++; 529 if (!spidev->rx_buffer) {
521 filp->private_data = spidev; 530 spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL);
522 nonseekable_open(inode, filp); 531 if (!spidev->rx_buffer) {
532 dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
533 status = -ENOMEM;
534 goto err_alloc_rx_buf;
523 } 535 }
524 } else 536 }
525 pr_debug("spidev: nothing for minor %d\n", iminor(inode)); 537
538 spidev->users++;
539 filp->private_data = spidev;
540 nonseekable_open(inode, filp);
541
542 mutex_unlock(&device_list_lock);
543 return 0;
526 544
545err_alloc_rx_buf:
546 kfree(spidev->tx_buffer);
547 spidev->tx_buffer = NULL;
548err_find_dev:
527 mutex_unlock(&device_list_lock); 549 mutex_unlock(&device_list_lock);
528 return status; 550 return status;
529} 551}
@@ -542,8 +564,11 @@ static int spidev_release(struct inode *inode, struct file *filp)
542 if (!spidev->users) { 564 if (!spidev->users) {
543 int dofree; 565 int dofree;
544 566
545 kfree(spidev->buffer); 567 kfree(spidev->tx_buffer);
546 spidev->buffer = NULL; 568 spidev->tx_buffer = NULL;
569
570 kfree(spidev->rx_buffer);
571 spidev->rx_buffer = NULL;
547 572
548 /* ... after we unbound from the underlying device? */ 573 /* ... after we unbound from the underlying device? */
549 spin_lock_irq(&spidev->spi_lock); 574 spin_lock_irq(&spidev->spi_lock);