diff options
| author | Shimoda, Yoshihiro <yoshihiro.shimoda.uh@renesas.com> | 2012-04-20 01:50:36 -0400 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2012-05-20 00:37:16 -0400 |
| commit | a3633fe7aa7022e2e9b2b799a0cbf3d6944d8ba5 (patch) | |
| tree | acd8bfc00d867708e90b8e28e84de5617c9c7ac4 | |
| parent | d195f7bebc14ece71bf11d09f1726ee6f6b4f4b9 (diff) | |
spi/rspi: add dmaengine support
This patch adds dmaengine supporting using sh_dma driver. The module
receives data by DMAC, it also needs TX DMAC to generate SPI's clocks.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
| -rw-r--r-- | drivers/spi/spi-rspi.c | 320 | ||||
| -rw-r--r-- | include/linux/spi/rspi.h | 31 |
2 files changed, 345 insertions, 6 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 354f170eab95..4894bde4bbff 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -31,7 +31,11 @@ | |||
| 31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
| 32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
| 33 | #include <linux/clk.h> | 33 | #include <linux/clk.h> |
| 34 | #include <linux/dmaengine.h> | ||
| 35 | #include <linux/dma-mapping.h> | ||
| 36 | #include <linux/sh_dma.h> | ||
| 34 | #include <linux/spi/spi.h> | 37 | #include <linux/spi/spi.h> |
| 38 | #include <linux/spi/rspi.h> | ||
| 35 | 39 | ||
| 36 | #define RSPI_SPCR 0x00 | 40 | #define RSPI_SPCR 0x00 |
| 37 | #define RSPI_SSLP 0x01 | 41 | #define RSPI_SSLP 0x01 |
| @@ -141,6 +145,16 @@ struct rspi_data { | |||
| 141 | spinlock_t lock; | 145 | spinlock_t lock; |
| 142 | struct clk *clk; | 146 | struct clk *clk; |
| 143 | unsigned char spsr; | 147 | unsigned char spsr; |
| 148 | |||
| 149 | /* for dmaengine */ | ||
| 150 | struct sh_dmae_slave dma_tx; | ||
| 151 | struct sh_dmae_slave dma_rx; | ||
| 152 | struct dma_chan *chan_tx; | ||
| 153 | struct dma_chan *chan_rx; | ||
| 154 | int irq; | ||
| 155 | |||
| 156 | unsigned dma_width_16bit:1; | ||
| 157 | unsigned dma_callbacked:1; | ||
| 144 | }; | 158 | }; |
| 145 | 159 | ||
| 146 | static void rspi_write8(struct rspi_data *rspi, u8 data, u16 offset) | 160 | static void rspi_write8(struct rspi_data *rspi, u8 data, u16 offset) |
| @@ -265,11 +279,125 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, | |||
| 265 | return 0; | 279 | return 0; |
| 266 | } | 280 | } |
| 267 | 281 | ||
| 268 | static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, | 282 | static void rspi_dma_complete(void *arg) |
| 269 | struct spi_transfer *t) | 283 | { |
| 284 | struct rspi_data *rspi = arg; | ||
| 285 | |||
| 286 | rspi->dma_callbacked = 1; | ||
| 287 | wake_up_interruptible(&rspi->wait); | ||
| 288 | } | ||
| 289 | |||
| 290 | static int rspi_dma_map_sg(struct scatterlist *sg, void *buf, unsigned len, | ||
| 291 | struct dma_chan *chan, | ||
| 292 | enum dma_transfer_direction dir) | ||
| 293 | { | ||
| 294 | sg_init_table(sg, 1); | ||
| 295 | sg_set_buf(sg, buf, len); | ||
| 296 | sg_dma_len(sg) = len; | ||
| 297 | return dma_map_sg(chan->device->dev, sg, 1, dir); | ||
| 298 | } | ||
| 299 | |||
| 300 | static void rspi_dma_unmap_sg(struct scatterlist *sg, struct dma_chan *chan, | ||
| 301 | enum dma_transfer_direction dir) | ||
| 302 | { | ||
| 303 | dma_unmap_sg(chan->device->dev, sg, 1, dir); | ||
| 304 | } | ||
| 305 | |||
| 306 | static void rspi_memory_to_8bit(void *buf, const void *data, unsigned len) | ||
| 307 | { | ||
| 308 | u16 *dst = buf; | ||
| 309 | const u8 *src = data; | ||
| 310 | |||
| 311 | while (len) { | ||
| 312 | *dst++ = (u16)(*src++); | ||
| 313 | len--; | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | static void rspi_memory_from_8bit(void *buf, const void *data, unsigned len) | ||
| 318 | { | ||
| 319 | u8 *dst = buf; | ||
| 320 | const u16 *src = data; | ||
| 321 | |||
| 322 | while (len) { | ||
| 323 | *dst++ = (u8)*src++; | ||
| 324 | len--; | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
| 328 | static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t) | ||
| 329 | { | ||
| 330 | struct scatterlist sg; | ||
| 331 | void *buf = NULL; | ||
| 332 | struct dma_async_tx_descriptor *desc; | ||
| 333 | unsigned len; | ||
| 334 | int ret = 0; | ||
| 335 | |||
| 336 | if (rspi->dma_width_16bit) { | ||
| 337 | /* | ||
| 338 | * If DMAC bus width is 16-bit, the driver allocates a dummy | ||
| 339 | * buffer. And, the driver converts original data into the | ||
| 340 | * DMAC data as the following format: | ||
| 341 | * original data: 1st byte, 2nd byte ... | ||
| 342 | * DMAC data: 1st byte, dummy, 2nd byte, dummy ... | ||
| 343 | */ | ||
| 344 | len = t->len * 2; | ||
| 345 | buf = kmalloc(len, GFP_KERNEL); | ||
| 346 | if (!buf) | ||
| 347 | return -ENOMEM; | ||
| 348 | rspi_memory_to_8bit(buf, t->tx_buf, t->len); | ||
| 349 | } else { | ||
| 350 | len = t->len; | ||
| 351 | buf = (void *)t->tx_buf; | ||
| 352 | } | ||
| 353 | |||
| 354 | if (!rspi_dma_map_sg(&sg, buf, len, rspi->chan_tx, DMA_TO_DEVICE)) { | ||
| 355 | ret = -EFAULT; | ||
| 356 | goto end_nomap; | ||
| 357 | } | ||
| 358 | desc = dmaengine_prep_slave_sg(rspi->chan_tx, &sg, 1, DMA_TO_DEVICE, | ||
| 359 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 360 | if (!desc) { | ||
| 361 | ret = -EIO; | ||
| 362 | goto end; | ||
| 363 | } | ||
| 364 | |||
| 365 | /* | ||
| 366 | * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be | ||
| 367 | * called. So, this driver disables the IRQ while DMA transfer. | ||
| 368 | */ | ||
| 369 | disable_irq(rspi->irq); | ||
| 370 | |||
| 371 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR); | ||
| 372 | rspi_enable_irq(rspi, SPCR_SPTIE); | ||
| 373 | rspi->dma_callbacked = 0; | ||
| 374 | |||
| 375 | desc->callback = rspi_dma_complete; | ||
| 376 | desc->callback_param = rspi; | ||
| 377 | dmaengine_submit(desc); | ||
| 378 | dma_async_issue_pending(rspi->chan_tx); | ||
| 379 | |||
| 380 | ret = wait_event_interruptible_timeout(rspi->wait, | ||
| 381 | rspi->dma_callbacked, HZ); | ||
| 382 | if (ret > 0 && rspi->dma_callbacked) | ||
| 383 | ret = 0; | ||
| 384 | else if (!ret) | ||
| 385 | ret = -ETIMEDOUT; | ||
| 386 | rspi_disable_irq(rspi, SPCR_SPTIE); | ||
| 387 | |||
| 388 | enable_irq(rspi->irq); | ||
| 389 | |||
| 390 | end: | ||
| 391 | rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE); | ||
| 392 | end_nomap: | ||
| 393 | if (rspi->dma_width_16bit) | ||
| 394 | kfree(buf); | ||
| 395 | |||
| 396 | return ret; | ||
| 397 | } | ||
| 398 | |||
| 399 | static void rspi_receive_init(struct rspi_data *rspi) | ||
| 270 | { | 400 | { |
| 271 | int remain = t->len; | ||
| 272 | u8 *data; | ||
| 273 | unsigned char spsr; | 401 | unsigned char spsr; |
| 274 | 402 | ||
| 275 | spsr = rspi_read8(rspi, RSPI_SPSR); | 403 | spsr = rspi_read8(rspi, RSPI_SPSR); |
| @@ -278,6 +406,15 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, | |||
| 278 | if (spsr & SPSR_OVRF) | 406 | if (spsr & SPSR_OVRF) |
| 279 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF, | 407 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF, |
| 280 | RSPI_SPCR); | 408 | RSPI_SPCR); |
| 409 | } | ||
| 410 | |||
| 411 | static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, | ||
| 412 | struct spi_transfer *t) | ||
| 413 | { | ||
| 414 | int remain = t->len; | ||
| 415 | u8 *data; | ||
| 416 | |||
| 417 | rspi_receive_init(rspi); | ||
| 281 | 418 | ||
| 282 | data = (u8 *)t->rx_buf; | 419 | data = (u8 *)t->rx_buf; |
| 283 | while (remain > 0) { | 420 | while (remain > 0) { |
| @@ -307,6 +444,120 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, | |||
| 307 | return 0; | 444 | return 0; |
| 308 | } | 445 | } |
| 309 | 446 | ||
| 447 | static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) | ||
| 448 | { | ||
| 449 | struct scatterlist sg, sg_dummy; | ||
| 450 | void *dummy = NULL, *rx_buf = NULL; | ||
| 451 | struct dma_async_tx_descriptor *desc, *desc_dummy; | ||
| 452 | unsigned len; | ||
| 453 | int ret = 0; | ||
| 454 | |||
| 455 | if (rspi->dma_width_16bit) { | ||
| 456 | /* | ||
| 457 | * If DMAC bus width is 16-bit, the driver allocates a dummy | ||
| 458 | * buffer. And, finally the driver converts the DMAC data into | ||
| 459 | * actual data as the following format: | ||
| 460 | * DMAC data: 1st byte, dummy, 2nd byte, dummy ... | ||
| 461 | * actual data: 1st byte, 2nd byte ... | ||
| 462 | */ | ||
| 463 | len = t->len * 2; | ||
| 464 | rx_buf = kmalloc(len, GFP_KERNEL); | ||
| 465 | if (!rx_buf) | ||
| 466 | return -ENOMEM; | ||
| 467 | } else { | ||
| 468 | len = t->len; | ||
| 469 | rx_buf = t->rx_buf; | ||
| 470 | } | ||
| 471 | |||
| 472 | /* prepare dummy transfer to generate SPI clocks */ | ||
| 473 | dummy = kzalloc(len, GFP_KERNEL); | ||
| 474 | if (!dummy) { | ||
| 475 | ret = -ENOMEM; | ||
| 476 | goto end_nomap; | ||
| 477 | } | ||
| 478 | if (!rspi_dma_map_sg(&sg_dummy, dummy, len, rspi->chan_tx, | ||
| 479 | DMA_TO_DEVICE)) { | ||
| 480 | ret = -EFAULT; | ||
| 481 | goto end_nomap; | ||
| 482 | } | ||
| 483 | desc_dummy = dmaengine_prep_slave_sg(rspi->chan_tx, &sg_dummy, 1, | ||
| 484 | DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 485 | if (!desc_dummy) { | ||
| 486 | ret = -EIO; | ||
| 487 | goto end_dummy_mapped; | ||
| 488 | } | ||
| 489 | |||
| 490 | /* prepare receive transfer */ | ||
| 491 | if (!rspi_dma_map_sg(&sg, rx_buf, len, rspi->chan_rx, | ||
| 492 | DMA_FROM_DEVICE)) { | ||
| 493 | ret = -EFAULT; | ||
| 494 | goto end_dummy_mapped; | ||
| 495 | |||
| 496 | } | ||
| 497 | desc = dmaengine_prep_slave_sg(rspi->chan_rx, &sg, 1, DMA_FROM_DEVICE, | ||
| 498 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 499 | if (!desc) { | ||
| 500 | ret = -EIO; | ||
| 501 | goto end; | ||
| 502 | } | ||
| 503 | |||
| 504 | rspi_receive_init(rspi); | ||
| 505 | |||
| 506 | /* | ||
| 507 | * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be | ||
| 508 | * called. So, this driver disables the IRQ while DMA transfer. | ||
| 509 | */ | ||
| 510 | disable_irq(rspi->irq); | ||
| 511 | |||
| 512 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR); | ||
| 513 | rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); | ||
| 514 | rspi->dma_callbacked = 0; | ||
| 515 | |||
| 516 | desc->callback = rspi_dma_complete; | ||
| 517 | desc->callback_param = rspi; | ||
| 518 | dmaengine_submit(desc); | ||
| 519 | dma_async_issue_pending(rspi->chan_rx); | ||
| 520 | |||
| 521 | desc_dummy->callback = NULL; /* No callback */ | ||
| 522 | dmaengine_submit(desc_dummy); | ||
| 523 | dma_async_issue_pending(rspi->chan_tx); | ||
| 524 | |||
| 525 | ret = wait_event_interruptible_timeout(rspi->wait, | ||
| 526 | rspi->dma_callbacked, HZ); | ||
| 527 | if (ret > 0 && rspi->dma_callbacked) | ||
| 528 | ret = 0; | ||
| 529 | else if (!ret) | ||
| 530 | ret = -ETIMEDOUT; | ||
| 531 | rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); | ||
| 532 | |||
| 533 | enable_irq(rspi->irq); | ||
| 534 | |||
| 535 | end: | ||
| 536 | rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE); | ||
| 537 | end_dummy_mapped: | ||
| 538 | rspi_dma_unmap_sg(&sg_dummy, rspi->chan_tx, DMA_TO_DEVICE); | ||
| 539 | end_nomap: | ||
| 540 | if (rspi->dma_width_16bit) { | ||
| 541 | if (!ret) | ||
| 542 | rspi_memory_from_8bit(t->rx_buf, rx_buf, t->len); | ||
| 543 | kfree(rx_buf); | ||
| 544 | } | ||
| 545 | kfree(dummy); | ||
| 546 | |||
| 547 | return ret; | ||
| 548 | } | ||
| 549 | |||
| 550 | static int rspi_is_dma(struct rspi_data *rspi, struct spi_transfer *t) | ||
| 551 | { | ||
| 552 | if (t->tx_buf && rspi->chan_tx) | ||
| 553 | return 1; | ||
| 554 | /* If the module receives data by DMAC, it also needs TX DMAC */ | ||
| 555 | if (t->rx_buf && rspi->chan_tx && rspi->chan_rx) | ||
| 556 | return 1; | ||
| 557 | |||
| 558 | return 0; | ||
| 559 | } | ||
| 560 | |||
| 310 | static void rspi_work(struct work_struct *work) | 561 | static void rspi_work(struct work_struct *work) |
| 311 | { | 562 | { |
| 312 | struct rspi_data *rspi = container_of(work, struct rspi_data, ws); | 563 | struct rspi_data *rspi = container_of(work, struct rspi_data, ws); |
| @@ -325,12 +576,18 @@ static void rspi_work(struct work_struct *work) | |||
| 325 | 576 | ||
| 326 | list_for_each_entry(t, &mesg->transfers, transfer_list) { | 577 | list_for_each_entry(t, &mesg->transfers, transfer_list) { |
| 327 | if (t->tx_buf) { | 578 | if (t->tx_buf) { |
| 328 | ret = rspi_send_pio(rspi, mesg, t); | 579 | if (rspi_is_dma(rspi, t)) |
| 580 | ret = rspi_send_dma(rspi, t); | ||
| 581 | else | ||
| 582 | ret = rspi_send_pio(rspi, mesg, t); | ||
| 329 | if (ret < 0) | 583 | if (ret < 0) |
| 330 | goto error; | 584 | goto error; |
| 331 | } | 585 | } |
| 332 | if (t->rx_buf) { | 586 | if (t->rx_buf) { |
| 333 | ret = rspi_receive_pio(rspi, mesg, t); | 587 | if (rspi_is_dma(rspi, t)) |
| 588 | ret = rspi_receive_dma(rspi, t); | ||
| 589 | else | ||
| 590 | ret = rspi_receive_pio(rspi, mesg, t); | ||
| 334 | if (ret < 0) | 591 | if (ret < 0) |
| 335 | goto error; | 592 | goto error; |
| 336 | } | 593 | } |
| @@ -406,11 +663,58 @@ static irqreturn_t rspi_irq(int irq, void *_sr) | |||
| 406 | return ret; | 663 | return ret; |
| 407 | } | 664 | } |
| 408 | 665 | ||
| 666 | static bool rspi_filter(struct dma_chan *chan, void *filter_param) | ||
| 667 | { | ||
| 668 | chan->private = filter_param; | ||
| 669 | return true; | ||
| 670 | } | ||
| 671 | |||
| 672 | static void __devinit rspi_request_dma(struct rspi_data *rspi, | ||
| 673 | struct platform_device *pdev) | ||
| 674 | { | ||
| 675 | struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; | ||
| 676 | dma_cap_mask_t mask; | ||
| 677 | |||
| 678 | if (!rspi_pd) | ||
| 679 | return; | ||
| 680 | |||
| 681 | rspi->dma_width_16bit = rspi_pd->dma_width_16bit; | ||
| 682 | |||
| 683 | /* If the module receives data by DMAC, it also needs TX DMAC */ | ||
| 684 | if (rspi_pd->dma_rx_id && rspi_pd->dma_tx_id) { | ||
| 685 | dma_cap_zero(mask); | ||
| 686 | dma_cap_set(DMA_SLAVE, mask); | ||
| 687 | rspi->dma_rx.slave_id = rspi_pd->dma_rx_id; | ||
| 688 | rspi->chan_rx = dma_request_channel(mask, rspi_filter, | ||
| 689 | &rspi->dma_rx); | ||
| 690 | if (rspi->chan_rx) | ||
| 691 | dev_info(&pdev->dev, "Use DMA when rx.\n"); | ||
| 692 | } | ||
| 693 | if (rspi_pd->dma_tx_id) { | ||
| 694 | dma_cap_zero(mask); | ||
| 695 | dma_cap_set(DMA_SLAVE, mask); | ||
| 696 | rspi->dma_tx.slave_id = rspi_pd->dma_tx_id; | ||
| 697 | rspi->chan_tx = dma_request_channel(mask, rspi_filter, | ||
| 698 | &rspi->dma_tx); | ||
| 699 | if (rspi->chan_tx) | ||
| 700 | dev_info(&pdev->dev, "Use DMA when tx\n"); | ||
| 701 | } | ||
| 702 | } | ||
| 703 | |||
| 704 | static void __devexit rspi_release_dma(struct rspi_data *rspi) | ||
| 705 | { | ||
| 706 | if (rspi->chan_tx) | ||
| 707 | dma_release_channel(rspi->chan_tx); | ||
| 708 | if (rspi->chan_rx) | ||
| 709 | dma_release_channel(rspi->chan_rx); | ||
| 710 | } | ||
| 711 | |||
| 409 | static int __devexit rspi_remove(struct platform_device *pdev) | 712 | static int __devexit rspi_remove(struct platform_device *pdev) |
| 410 | { | 713 | { |
| 411 | struct rspi_data *rspi = dev_get_drvdata(&pdev->dev); | 714 | struct rspi_data *rspi = dev_get_drvdata(&pdev->dev); |
| 412 | 715 | ||
| 413 | spi_unregister_master(rspi->master); | 716 | spi_unregister_master(rspi->master); |
| 717 | rspi_release_dma(rspi); | ||
| 414 | free_irq(platform_get_irq(pdev, 0), rspi); | 718 | free_irq(platform_get_irq(pdev, 0), rspi); |
| 415 | clk_put(rspi->clk); | 719 | clk_put(rspi->clk); |
| 416 | iounmap(rspi->addr); | 720 | iounmap(rspi->addr); |
| @@ -483,6 +787,9 @@ static int __devinit rspi_probe(struct platform_device *pdev) | |||
| 483 | goto error3; | 787 | goto error3; |
| 484 | } | 788 | } |
| 485 | 789 | ||
| 790 | rspi->irq = irq; | ||
| 791 | rspi_request_dma(rspi, pdev); | ||
| 792 | |||
| 486 | ret = spi_register_master(master); | 793 | ret = spi_register_master(master); |
| 487 | if (ret < 0) { | 794 | if (ret < 0) { |
| 488 | dev_err(&pdev->dev, "spi_register_master error.\n"); | 795 | dev_err(&pdev->dev, "spi_register_master error.\n"); |
| @@ -494,6 +801,7 @@ static int __devinit rspi_probe(struct platform_device *pdev) | |||
| 494 | return 0; | 801 | return 0; |
| 495 | 802 | ||
| 496 | error4: | 803 | error4: |
| 804 | rspi_release_dma(rspi); | ||
| 497 | free_irq(irq, rspi); | 805 | free_irq(irq, rspi); |
| 498 | error3: | 806 | error3: |
| 499 | clk_put(rspi->clk); | 807 | clk_put(rspi->clk); |
diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h new file mode 100644 index 000000000000..900f0e328235 --- /dev/null +++ b/include/linux/spi/rspi.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* | ||
| 2 | * Renesas SPI driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Renesas Solutions Corp. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; version 2 of the License. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __LINUX_SPI_RENESAS_SPI_H__ | ||
| 22 | #define __LINUX_SPI_RENESAS_SPI_H__ | ||
| 23 | |||
| 24 | struct rspi_plat_data { | ||
| 25 | unsigned int dma_tx_id; | ||
| 26 | unsigned int dma_rx_id; | ||
| 27 | |||
| 28 | unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */ | ||
| 29 | }; | ||
| 30 | |||
| 31 | #endif | ||
