diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/spi-dw-mmio.c | 22 | ||||
-rw-r--r-- | drivers/spi/spi-dw.c | 197 | ||||
-rw-r--r-- | drivers/spi/spi-dw.h | 24 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-dspi.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-espi.c | 40 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-lib.c | 6 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-lib.h | 1 | ||||
-rw-r--r-- | drivers/spi/spi-fsl-spi.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-gpio.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-qup.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-tegra114.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-tegra20-sflash.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-tegra20-slink.c | 2 |
13 files changed, 95 insertions, 209 deletions
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 1492f5ee9aaa..a5cba14ac3d2 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
17 | #include <linux/scatterlist.h> | 17 | #include <linux/scatterlist.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/of_gpio.h> | ||
19 | 20 | ||
20 | #include "spi-dw.h" | 21 | #include "spi-dw.h" |
21 | 22 | ||
@@ -70,6 +71,27 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) | |||
70 | dws->num_cs = 4; | 71 | dws->num_cs = 4; |
71 | dws->max_freq = clk_get_rate(dwsmmio->clk); | 72 | dws->max_freq = clk_get_rate(dwsmmio->clk); |
72 | 73 | ||
74 | if (pdev->dev.of_node) { | ||
75 | int i; | ||
76 | |||
77 | for (i = 0; i < dws->num_cs; i++) { | ||
78 | int cs_gpio = of_get_named_gpio(pdev->dev.of_node, | ||
79 | "cs-gpios", i); | ||
80 | |||
81 | if (cs_gpio == -EPROBE_DEFER) { | ||
82 | ret = cs_gpio; | ||
83 | goto out; | ||
84 | } | ||
85 | |||
86 | if (gpio_is_valid(cs_gpio)) { | ||
87 | ret = devm_gpio_request(&pdev->dev, cs_gpio, | ||
88 | dev_name(&pdev->dev)); | ||
89 | if (ret) | ||
90 | goto out; | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
73 | ret = dw_spi_add_host(&pdev->dev, dws); | 95 | ret = dw_spi_add_host(&pdev->dev, dws); |
74 | if (ret) | 96 | if (ret) |
75 | goto out; | 97 | goto out; |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 712ac5629cd4..29f33143b795 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
27 | #include <linux/gpio.h> | ||
27 | 28 | ||
28 | #include "spi-dw.h" | 29 | #include "spi-dw.h" |
29 | 30 | ||
@@ -36,12 +37,6 @@ | |||
36 | #define DONE_STATE ((void *)2) | 37 | #define DONE_STATE ((void *)2) |
37 | #define ERROR_STATE ((void *)-1) | 38 | #define ERROR_STATE ((void *)-1) |
38 | 39 | ||
39 | #define QUEUE_RUNNING 0 | ||
40 | #define QUEUE_STOPPED 1 | ||
41 | |||
42 | #define MRST_SPI_DEASSERT 0 | ||
43 | #define MRST_SPI_ASSERT 1 | ||
44 | |||
45 | /* Slave spi_dev related */ | 40 | /* Slave spi_dev related */ |
46 | struct chip_data { | 41 | struct chip_data { |
47 | u16 cr0; | 42 | u16 cr0; |
@@ -263,28 +258,22 @@ static int map_dma_buffers(struct dw_spi *dws) | |||
263 | static void giveback(struct dw_spi *dws) | 258 | static void giveback(struct dw_spi *dws) |
264 | { | 259 | { |
265 | struct spi_transfer *last_transfer; | 260 | struct spi_transfer *last_transfer; |
266 | unsigned long flags; | ||
267 | struct spi_message *msg; | 261 | struct spi_message *msg; |
268 | 262 | ||
269 | spin_lock_irqsave(&dws->lock, flags); | ||
270 | msg = dws->cur_msg; | 263 | msg = dws->cur_msg; |
271 | dws->cur_msg = NULL; | 264 | dws->cur_msg = NULL; |
272 | dws->cur_transfer = NULL; | 265 | dws->cur_transfer = NULL; |
273 | dws->prev_chip = dws->cur_chip; | 266 | dws->prev_chip = dws->cur_chip; |
274 | dws->cur_chip = NULL; | 267 | dws->cur_chip = NULL; |
275 | dws->dma_mapped = 0; | 268 | dws->dma_mapped = 0; |
276 | queue_work(dws->workqueue, &dws->pump_messages); | ||
277 | spin_unlock_irqrestore(&dws->lock, flags); | ||
278 | 269 | ||
279 | last_transfer = list_last_entry(&msg->transfers, struct spi_transfer, | 270 | last_transfer = list_last_entry(&msg->transfers, struct spi_transfer, |
280 | transfer_list); | 271 | transfer_list); |
281 | 272 | ||
282 | if (!last_transfer->cs_change && dws->cs_control) | 273 | if (!last_transfer->cs_change) |
283 | dws->cs_control(MRST_SPI_DEASSERT); | 274 | spi_chip_sel(dws, dws->cur_msg->spi, 0); |
284 | 275 | ||
285 | msg->state = NULL; | 276 | spi_finalize_current_message(dws->master); |
286 | if (msg->complete) | ||
287 | msg->complete(msg->context); | ||
288 | } | 277 | } |
289 | 278 | ||
290 | static void int_error_stop(struct dw_spi *dws, const char *msg) | 279 | static void int_error_stop(struct dw_spi *dws, const char *msg) |
@@ -502,7 +491,7 @@ static void pump_transfers(unsigned long data) | |||
502 | dw_writew(dws, DW_SPI_CTRL0, cr0); | 491 | dw_writew(dws, DW_SPI_CTRL0, cr0); |
503 | 492 | ||
504 | spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); | 493 | spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); |
505 | spi_chip_sel(dws, spi->chip_select); | 494 | spi_chip_sel(dws, spi, 1); |
506 | 495 | ||
507 | /* Set the interrupt mask, for poll mode just disable all int */ | 496 | /* Set the interrupt mask, for poll mode just disable all int */ |
508 | spi_mask_intr(dws, 0xff); | 497 | spi_mask_intr(dws, 0xff); |
@@ -529,30 +518,12 @@ early_exit: | |||
529 | return; | 518 | return; |
530 | } | 519 | } |
531 | 520 | ||
532 | static void pump_messages(struct work_struct *work) | 521 | static int dw_spi_transfer_one_message(struct spi_master *master, |
522 | struct spi_message *msg) | ||
533 | { | 523 | { |
534 | struct dw_spi *dws = | 524 | struct dw_spi *dws = spi_master_get_devdata(master); |
535 | container_of(work, struct dw_spi, pump_messages); | ||
536 | unsigned long flags; | ||
537 | |||
538 | /* Lock queue and check for queue work */ | ||
539 | spin_lock_irqsave(&dws->lock, flags); | ||
540 | if (list_empty(&dws->queue) || dws->run == QUEUE_STOPPED) { | ||
541 | dws->busy = 0; | ||
542 | spin_unlock_irqrestore(&dws->lock, flags); | ||
543 | return; | ||
544 | } | ||
545 | |||
546 | /* Make sure we are not already running a message */ | ||
547 | if (dws->cur_msg) { | ||
548 | spin_unlock_irqrestore(&dws->lock, flags); | ||
549 | return; | ||
550 | } | ||
551 | |||
552 | /* Extract head of queue */ | ||
553 | dws->cur_msg = list_entry(dws->queue.next, struct spi_message, queue); | ||
554 | list_del_init(&dws->cur_msg->queue); | ||
555 | 525 | ||
526 | dws->cur_msg = msg; | ||
556 | /* Initial message state*/ | 527 | /* Initial message state*/ |
557 | dws->cur_msg->state = START_STATE; | 528 | dws->cur_msg->state = START_STATE; |
558 | dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, | 529 | dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, |
@@ -560,46 +531,9 @@ static void pump_messages(struct work_struct *work) | |||
560 | transfer_list); | 531 | transfer_list); |
561 | dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi); | 532 | dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi); |
562 | 533 | ||
563 | /* Mark as busy and launch transfers */ | 534 | /* Launch transfers */ |
564 | tasklet_schedule(&dws->pump_transfers); | 535 | tasklet_schedule(&dws->pump_transfers); |
565 | 536 | ||
566 | dws->busy = 1; | ||
567 | spin_unlock_irqrestore(&dws->lock, flags); | ||
568 | } | ||
569 | |||
570 | /* spi_device use this to queue in their spi_msg */ | ||
571 | static int dw_spi_transfer(struct spi_device *spi, struct spi_message *msg) | ||
572 | { | ||
573 | struct dw_spi *dws = spi_master_get_devdata(spi->master); | ||
574 | unsigned long flags; | ||
575 | |||
576 | spin_lock_irqsave(&dws->lock, flags); | ||
577 | |||
578 | if (dws->run == QUEUE_STOPPED) { | ||
579 | spin_unlock_irqrestore(&dws->lock, flags); | ||
580 | return -ESHUTDOWN; | ||
581 | } | ||
582 | |||
583 | msg->actual_length = 0; | ||
584 | msg->status = -EINPROGRESS; | ||
585 | msg->state = START_STATE; | ||
586 | |||
587 | list_add_tail(&msg->queue, &dws->queue); | ||
588 | |||
589 | if (dws->run == QUEUE_RUNNING && !dws->busy) { | ||
590 | |||
591 | if (dws->cur_transfer || dws->cur_msg) | ||
592 | queue_work(dws->workqueue, | ||
593 | &dws->pump_messages); | ||
594 | else { | ||
595 | /* If no other data transaction in air, just go */ | ||
596 | spin_unlock_irqrestore(&dws->lock, flags); | ||
597 | pump_messages(&dws->pump_messages); | ||
598 | return 0; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | spin_unlock_irqrestore(&dws->lock, flags); | ||
603 | return 0; | 537 | return 0; |
604 | } | 538 | } |
605 | 539 | ||
@@ -608,6 +542,7 @@ static int dw_spi_setup(struct spi_device *spi) | |||
608 | { | 542 | { |
609 | struct dw_spi_chip *chip_info = NULL; | 543 | struct dw_spi_chip *chip_info = NULL; |
610 | struct chip_data *chip; | 544 | struct chip_data *chip; |
545 | int ret; | ||
611 | 546 | ||
612 | /* Only alloc on first setup */ | 547 | /* Only alloc on first setup */ |
613 | chip = spi_get_ctldata(spi); | 548 | chip = spi_get_ctldata(spi); |
@@ -661,81 +596,13 @@ static int dw_spi_setup(struct spi_device *spi) | |||
661 | | (spi->mode << SPI_MODE_OFFSET) | 596 | | (spi->mode << SPI_MODE_OFFSET) |
662 | | (chip->tmode << SPI_TMOD_OFFSET); | 597 | | (chip->tmode << SPI_TMOD_OFFSET); |
663 | 598 | ||
664 | return 0; | 599 | if (gpio_is_valid(spi->cs_gpio)) { |
665 | } | 600 | ret = gpio_direction_output(spi->cs_gpio, |
666 | 601 | !(spi->mode & SPI_CS_HIGH)); | |
667 | static int init_queue(struct dw_spi *dws) | 602 | if (ret) |
668 | { | 603 | return ret; |
669 | INIT_LIST_HEAD(&dws->queue); | ||
670 | spin_lock_init(&dws->lock); | ||
671 | |||
672 | dws->run = QUEUE_STOPPED; | ||
673 | dws->busy = 0; | ||
674 | |||
675 | tasklet_init(&dws->pump_transfers, | ||
676 | pump_transfers, (unsigned long)dws); | ||
677 | |||
678 | INIT_WORK(&dws->pump_messages, pump_messages); | ||
679 | dws->workqueue = create_singlethread_workqueue( | ||
680 | dev_name(dws->master->dev.parent)); | ||
681 | if (dws->workqueue == NULL) | ||
682 | return -EBUSY; | ||
683 | |||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | static int start_queue(struct dw_spi *dws) | ||
688 | { | ||
689 | unsigned long flags; | ||
690 | |||
691 | spin_lock_irqsave(&dws->lock, flags); | ||
692 | |||
693 | if (dws->run == QUEUE_RUNNING || dws->busy) { | ||
694 | spin_unlock_irqrestore(&dws->lock, flags); | ||
695 | return -EBUSY; | ||
696 | } | 604 | } |
697 | 605 | ||
698 | dws->run = QUEUE_RUNNING; | ||
699 | dws->cur_msg = NULL; | ||
700 | dws->cur_transfer = NULL; | ||
701 | dws->cur_chip = NULL; | ||
702 | dws->prev_chip = NULL; | ||
703 | spin_unlock_irqrestore(&dws->lock, flags); | ||
704 | |||
705 | queue_work(dws->workqueue, &dws->pump_messages); | ||
706 | |||
707 | return 0; | ||
708 | } | ||
709 | |||
710 | static int stop_queue(struct dw_spi *dws) | ||
711 | { | ||
712 | unsigned long flags; | ||
713 | unsigned limit = 50; | ||
714 | int status = 0; | ||
715 | |||
716 | spin_lock_irqsave(&dws->lock, flags); | ||
717 | dws->run = QUEUE_STOPPED; | ||
718 | while ((!list_empty(&dws->queue) || dws->busy) && limit--) { | ||
719 | spin_unlock_irqrestore(&dws->lock, flags); | ||
720 | msleep(10); | ||
721 | spin_lock_irqsave(&dws->lock, flags); | ||
722 | } | ||
723 | |||
724 | if (!list_empty(&dws->queue) || dws->busy) | ||
725 | status = -EBUSY; | ||
726 | spin_unlock_irqrestore(&dws->lock, flags); | ||
727 | |||
728 | return status; | ||
729 | } | ||
730 | |||
731 | static int destroy_queue(struct dw_spi *dws) | ||
732 | { | ||
733 | int status; | ||
734 | |||
735 | status = stop_queue(dws); | ||
736 | if (status != 0) | ||
737 | return status; | ||
738 | destroy_workqueue(dws->workqueue); | ||
739 | return 0; | 606 | return 0; |
740 | } | 607 | } |
741 | 608 | ||
@@ -794,7 +661,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
794 | master->bus_num = dws->bus_num; | 661 | master->bus_num = dws->bus_num; |
795 | master->num_chipselect = dws->num_cs; | 662 | master->num_chipselect = dws->num_cs; |
796 | master->setup = dw_spi_setup; | 663 | master->setup = dw_spi_setup; |
797 | master->transfer = dw_spi_transfer; | 664 | master->transfer_one_message = dw_spi_transfer_one_message; |
798 | master->max_speed_hz = dws->max_freq; | 665 | master->max_speed_hz = dws->max_freq; |
799 | 666 | ||
800 | /* Basic HW init */ | 667 | /* Basic HW init */ |
@@ -808,33 +675,21 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
808 | } | 675 | } |
809 | } | 676 | } |
810 | 677 | ||
811 | /* Initial and start queue */ | 678 | tasklet_init(&dws->pump_transfers, pump_transfers, (unsigned long)dws); |
812 | ret = init_queue(dws); | ||
813 | if (ret) { | ||
814 | dev_err(&master->dev, "problem initializing queue\n"); | ||
815 | goto err_diable_hw; | ||
816 | } | ||
817 | ret = start_queue(dws); | ||
818 | if (ret) { | ||
819 | dev_err(&master->dev, "problem starting queue\n"); | ||
820 | goto err_diable_hw; | ||
821 | } | ||
822 | 679 | ||
823 | spi_master_set_devdata(master, dws); | 680 | spi_master_set_devdata(master, dws); |
824 | ret = devm_spi_register_master(dev, master); | 681 | ret = devm_spi_register_master(dev, master); |
825 | if (ret) { | 682 | if (ret) { |
826 | dev_err(&master->dev, "problem registering spi master\n"); | 683 | dev_err(&master->dev, "problem registering spi master\n"); |
827 | goto err_queue_alloc; | 684 | goto err_dma_exit; |
828 | } | 685 | } |
829 | 686 | ||
830 | mrst_spi_debugfs_init(dws); | 687 | mrst_spi_debugfs_init(dws); |
831 | return 0; | 688 | return 0; |
832 | 689 | ||
833 | err_queue_alloc: | 690 | err_dma_exit: |
834 | destroy_queue(dws); | ||
835 | if (dws->dma_ops && dws->dma_ops->dma_exit) | 691 | if (dws->dma_ops && dws->dma_ops->dma_exit) |
836 | dws->dma_ops->dma_exit(dws); | 692 | dws->dma_ops->dma_exit(dws); |
837 | err_diable_hw: | ||
838 | spi_enable_chip(dws, 0); | 693 | spi_enable_chip(dws, 0); |
839 | err_free_master: | 694 | err_free_master: |
840 | spi_master_put(master); | 695 | spi_master_put(master); |
@@ -844,18 +699,10 @@ EXPORT_SYMBOL_GPL(dw_spi_add_host); | |||
844 | 699 | ||
845 | void dw_spi_remove_host(struct dw_spi *dws) | 700 | void dw_spi_remove_host(struct dw_spi *dws) |
846 | { | 701 | { |
847 | int status = 0; | ||
848 | |||
849 | if (!dws) | 702 | if (!dws) |
850 | return; | 703 | return; |
851 | mrst_spi_debugfs_remove(dws); | 704 | mrst_spi_debugfs_remove(dws); |
852 | 705 | ||
853 | /* Remove the queue */ | ||
854 | status = destroy_queue(dws); | ||
855 | if (status != 0) | ||
856 | dev_err(&dws->master->dev, | ||
857 | "dw_spi_remove: workqueue will not complete, message memory not freed\n"); | ||
858 | |||
859 | if (dws->dma_ops && dws->dma_ops->dma_exit) | 706 | if (dws->dma_ops && dws->dma_ops->dma_exit) |
860 | dws->dma_ops->dma_exit(dws); | 707 | dws->dma_ops->dma_exit(dws); |
861 | spi_enable_chip(dws, 0); | 708 | spi_enable_chip(dws, 0); |
@@ -868,7 +715,7 @@ int dw_spi_suspend_host(struct dw_spi *dws) | |||
868 | { | 715 | { |
869 | int ret = 0; | 716 | int ret = 0; |
870 | 717 | ||
871 | ret = stop_queue(dws); | 718 | ret = spi_master_suspend(dws->master); |
872 | if (ret) | 719 | if (ret) |
873 | return ret; | 720 | return ret; |
874 | spi_enable_chip(dws, 0); | 721 | spi_enable_chip(dws, 0); |
@@ -882,7 +729,7 @@ int dw_spi_resume_host(struct dw_spi *dws) | |||
882 | int ret; | 729 | int ret; |
883 | 730 | ||
884 | spi_hw_init(dws); | 731 | spi_hw_init(dws); |
885 | ret = start_queue(dws); | 732 | ret = spi_master_resume(dws->master); |
886 | if (ret) | 733 | if (ret) |
887 | dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret); | 734 | dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret); |
888 | return ret; | 735 | return ret; |
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 587643dae11e..6d2acad34f64 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/io.h> | 4 | #include <linux/io.h> |
5 | #include <linux/scatterlist.h> | 5 | #include <linux/scatterlist.h> |
6 | #include <linux/gpio.h> | ||
6 | 7 | ||
7 | /* Register offsets */ | 8 | /* Register offsets */ |
8 | #define DW_SPI_CTRL0 0x00 | 9 | #define DW_SPI_CTRL0 0x00 |
@@ -104,14 +105,6 @@ struct dw_spi { | |||
104 | u16 bus_num; | 105 | u16 bus_num; |
105 | u16 num_cs; /* supported slave numbers */ | 106 | u16 num_cs; /* supported slave numbers */ |
106 | 107 | ||
107 | /* Driver message queue */ | ||
108 | struct workqueue_struct *workqueue; | ||
109 | struct work_struct pump_messages; | ||
110 | spinlock_t lock; | ||
111 | struct list_head queue; | ||
112 | int busy; | ||
113 | int run; | ||
114 | |||
115 | /* Message Transfer pump */ | 108 | /* Message Transfer pump */ |
116 | struct tasklet_struct pump_transfers; | 109 | struct tasklet_struct pump_transfers; |
117 | 110 | ||
@@ -186,15 +179,20 @@ static inline void spi_set_clk(struct dw_spi *dws, u16 div) | |||
186 | dw_writel(dws, DW_SPI_BAUDR, div); | 179 | dw_writel(dws, DW_SPI_BAUDR, div); |
187 | } | 180 | } |
188 | 181 | ||
189 | static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) | 182 | static inline void spi_chip_sel(struct dw_spi *dws, struct spi_device *spi, |
183 | int active) | ||
190 | { | 184 | { |
191 | if (cs > dws->num_cs) | 185 | u16 cs = spi->chip_select; |
192 | return; | 186 | int gpio_val = active ? (spi->mode & SPI_CS_HIGH) : |
187 | !(spi->mode & SPI_CS_HIGH); | ||
193 | 188 | ||
194 | if (dws->cs_control) | 189 | if (dws->cs_control) |
195 | dws->cs_control(1); | 190 | dws->cs_control(active); |
191 | if (gpio_is_valid(spi->cs_gpio)) | ||
192 | gpio_set_value(spi->cs_gpio, gpio_val); | ||
196 | 193 | ||
197 | dw_writel(dws, DW_SPI_SER, 1 << cs); | 194 | if (active) |
195 | dw_writel(dws, DW_SPI_SER, 1 << cs); | ||
198 | } | 196 | } |
199 | 197 | ||
200 | /* Disable IRQ bits */ | 198 | /* Disable IRQ bits */ |
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index d565eeee3bd8..5021ddf03f60 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
@@ -406,7 +406,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) | |||
406 | return IRQ_HANDLED; | 406 | return IRQ_HANDLED; |
407 | } | 407 | } |
408 | 408 | ||
409 | static struct of_device_id fsl_dspi_dt_ids[] = { | 409 | static const struct of_device_id fsl_dspi_dt_ids[] = { |
410 | { .compatible = "fsl,vf610-dspi", .data = NULL, }, | 410 | { .compatible = "fsl,vf610-dspi", .data = NULL, }, |
411 | { /* sentinel */ } | 411 | { /* sentinel */ } |
412 | }; | 412 | }; |
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index e767f5831b9c..8ebd724e4c59 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c | |||
@@ -348,7 +348,7 @@ static void fsl_espi_cmd_trans(struct spi_message *m, | |||
348 | } | 348 | } |
349 | 349 | ||
350 | espi_trans->tx_buf = local_buf; | 350 | espi_trans->tx_buf = local_buf; |
351 | espi_trans->rx_buf = local_buf + espi_trans->n_tx; | 351 | espi_trans->rx_buf = local_buf; |
352 | fsl_espi_do_trans(m, espi_trans); | 352 | fsl_espi_do_trans(m, espi_trans); |
353 | 353 | ||
354 | espi_trans->actual_length = espi_trans->len; | 354 | espi_trans->actual_length = espi_trans->len; |
@@ -397,7 +397,7 @@ static void fsl_espi_rw_trans(struct spi_message *m, | |||
397 | espi_trans->n_rx = trans_len; | 397 | espi_trans->n_rx = trans_len; |
398 | espi_trans->len = trans_len + n_tx; | 398 | espi_trans->len = trans_len + n_tx; |
399 | espi_trans->tx_buf = local_buf; | 399 | espi_trans->tx_buf = local_buf; |
400 | espi_trans->rx_buf = local_buf + n_tx; | 400 | espi_trans->rx_buf = local_buf; |
401 | fsl_espi_do_trans(m, espi_trans); | 401 | fsl_espi_do_trans(m, espi_trans); |
402 | 402 | ||
403 | memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len); | 403 | memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len); |
@@ -458,7 +458,7 @@ static int fsl_espi_setup(struct spi_device *spi) | |||
458 | return -EINVAL; | 458 | return -EINVAL; |
459 | 459 | ||
460 | if (!cs) { | 460 | if (!cs) { |
461 | cs = kzalloc(sizeof *cs, GFP_KERNEL); | 461 | cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL); |
462 | if (!cs) | 462 | if (!cs) |
463 | return -ENOMEM; | 463 | return -ENOMEM; |
464 | spi->controller_state = cs; | 464 | spi->controller_state = cs; |
@@ -586,8 +586,10 @@ static struct spi_master * fsl_espi_probe(struct device *dev, | |||
586 | struct spi_master *master; | 586 | struct spi_master *master; |
587 | struct mpc8xxx_spi *mpc8xxx_spi; | 587 | struct mpc8xxx_spi *mpc8xxx_spi; |
588 | struct fsl_espi_reg *reg_base; | 588 | struct fsl_espi_reg *reg_base; |
589 | u32 regval; | 589 | struct device_node *nc; |
590 | int i, ret = 0; | 590 | const __be32 *prop; |
591 | u32 regval, csmode; | ||
592 | int i, len, ret = 0; | ||
591 | 593 | ||
592 | master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); | 594 | master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi)); |
593 | if (!master) { | 595 | if (!master) { |
@@ -634,8 +636,32 @@ static struct spi_master * fsl_espi_probe(struct device *dev, | |||
634 | mpc8xxx_spi_write_reg(®_base->event, 0xffffffff); | 636 | mpc8xxx_spi_write_reg(®_base->event, 0xffffffff); |
635 | 637 | ||
636 | /* Init eSPI CS mode register */ | 638 | /* Init eSPI CS mode register */ |
637 | for (i = 0; i < pdata->max_chipselect; i++) | 639 | for_each_available_child_of_node(master->dev.of_node, nc) { |
638 | mpc8xxx_spi_write_reg(®_base->csmode[i], CSMODE_INIT_VAL); | 640 | /* get chip select */ |
641 | prop = of_get_property(nc, "reg", &len); | ||
642 | if (!prop || len < sizeof(*prop)) | ||
643 | continue; | ||
644 | i = be32_to_cpup(prop); | ||
645 | if (i < 0 || i >= pdata->max_chipselect) | ||
646 | continue; | ||
647 | |||
648 | csmode = CSMODE_INIT_VAL; | ||
649 | /* check if CSBEF is set in device tree */ | ||
650 | prop = of_get_property(nc, "fsl,csbef", &len); | ||
651 | if (prop && len >= sizeof(*prop)) { | ||
652 | csmode &= ~(CSMODE_BEF(0xf)); | ||
653 | csmode |= CSMODE_BEF(be32_to_cpup(prop)); | ||
654 | } | ||
655 | /* check if CSAFT is set in device tree */ | ||
656 | prop = of_get_property(nc, "fsl,csaft", &len); | ||
657 | if (prop && len >= sizeof(*prop)) { | ||
658 | csmode &= ~(CSMODE_AFT(0xf)); | ||
659 | csmode |= CSMODE_AFT(be32_to_cpup(prop)); | ||
660 | } | ||
661 | mpc8xxx_spi_write_reg(®_base->csmode[i], csmode); | ||
662 | |||
663 | dev_info(dev, "cs=%d, init_csmode=0x%x\n", i, csmode); | ||
664 | } | ||
639 | 665 | ||
640 | /* Enable SPI interface */ | 666 | /* Enable SPI interface */ |
641 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; | 667 | regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; |
diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c index e5d45fca3551..95212ea96c8d 100644 --- a/drivers/spi/spi-fsl-lib.c +++ b/drivers/spi/spi-fsl-lib.c | |||
@@ -99,11 +99,6 @@ int mpc8xxx_spi_transfer(struct spi_device *spi, | |||
99 | return 0; | 99 | return 0; |
100 | } | 100 | } |
101 | 101 | ||
102 | void mpc8xxx_spi_cleanup(struct spi_device *spi) | ||
103 | { | ||
104 | kfree(spi->controller_state); | ||
105 | } | ||
106 | |||
107 | const char *mpc8xxx_spi_strmode(unsigned int flags) | 102 | const char *mpc8xxx_spi_strmode(unsigned int flags) |
108 | { | 103 | { |
109 | if (flags & SPI_QE_CPU_MODE) { | 104 | if (flags & SPI_QE_CPU_MODE) { |
@@ -134,7 +129,6 @@ int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, | |||
134 | | SPI_LSB_FIRST | SPI_LOOP; | 129 | | SPI_LSB_FIRST | SPI_LOOP; |
135 | 130 | ||
136 | master->transfer = mpc8xxx_spi_transfer; | 131 | master->transfer = mpc8xxx_spi_transfer; |
137 | master->cleanup = mpc8xxx_spi_cleanup; | ||
138 | master->dev.of_node = dev->of_node; | 132 | master->dev.of_node = dev->of_node; |
139 | 133 | ||
140 | mpc8xxx_spi = spi_master_get_devdata(master); | 134 | mpc8xxx_spi = spi_master_get_devdata(master); |
diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index 52db6936778e..2fcbfd01d109 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h | |||
@@ -124,7 +124,6 @@ extern struct mpc8xxx_spi_probe_info *to_of_pinfo( | |||
124 | extern int mpc8xxx_spi_bufs(struct mpc8xxx_spi *mspi, | 124 | extern int mpc8xxx_spi_bufs(struct mpc8xxx_spi *mspi, |
125 | struct spi_transfer *t, unsigned int len); | 125 | struct spi_transfer *t, unsigned int len); |
126 | extern int mpc8xxx_spi_transfer(struct spi_device *spi, struct spi_message *m); | 126 | extern int mpc8xxx_spi_transfer(struct spi_device *spi, struct spi_message *m); |
127 | extern void mpc8xxx_spi_cleanup(struct spi_device *spi); | ||
128 | extern const char *mpc8xxx_spi_strmode(unsigned int flags); | 127 | extern const char *mpc8xxx_spi_strmode(unsigned int flags); |
129 | extern int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, | 128 | extern int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, |
130 | unsigned int irq); | 129 | unsigned int irq); |
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index b3e7775034db..98ccd231bf00 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c | |||
@@ -431,7 +431,7 @@ static int fsl_spi_setup(struct spi_device *spi) | |||
431 | return -EINVAL; | 431 | return -EINVAL; |
432 | 432 | ||
433 | if (!cs) { | 433 | if (!cs) { |
434 | cs = kzalloc(sizeof *cs, GFP_KERNEL); | 434 | cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL); |
435 | if (!cs) | 435 | if (!cs) |
436 | return -ENOMEM; | 436 | return -ENOMEM; |
437 | spi->controller_state = cs; | 437 | spi->controller_state = cs; |
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 09823076df88..9f595535cf27 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
@@ -340,7 +340,7 @@ done: | |||
340 | } | 340 | } |
341 | 341 | ||
342 | #ifdef CONFIG_OF | 342 | #ifdef CONFIG_OF |
343 | static struct of_device_id spi_gpio_dt_ids[] = { | 343 | static const struct of_device_id spi_gpio_dt_ids[] = { |
344 | { .compatible = "spi-gpio" }, | 344 | { .compatible = "spi-gpio" }, |
345 | {} | 345 | {} |
346 | }; | 346 | }; |
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c index 943f973a59aa..fc1de86d3c8a 100644 --- a/drivers/spi/spi-qup.c +++ b/drivers/spi/spi-qup.c | |||
@@ -749,7 +749,7 @@ static int spi_qup_remove(struct platform_device *pdev) | |||
749 | return 0; | 749 | return 0; |
750 | } | 750 | } |
751 | 751 | ||
752 | static struct of_device_id spi_qup_dt_match[] = { | 752 | static const struct of_device_id spi_qup_dt_match[] = { |
753 | { .compatible = "qcom,spi-qup-v2.1.1", }, | 753 | { .compatible = "qcom,spi-qup-v2.1.1", }, |
754 | { .compatible = "qcom,spi-qup-v2.2.1", }, | 754 | { .compatible = "qcom,spi-qup-v2.2.1", }, |
755 | { } | 755 | { } |
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 400649595505..e4a85ada861d 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c | |||
@@ -1012,7 +1012,7 @@ static irqreturn_t tegra_spi_isr(int irq, void *context_data) | |||
1012 | return IRQ_WAKE_THREAD; | 1012 | return IRQ_WAKE_THREAD; |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | static struct of_device_id tegra_spi_of_match[] = { | 1015 | static const struct of_device_id tegra_spi_of_match[] = { |
1016 | { .compatible = "nvidia,tegra114-spi", }, | 1016 | { .compatible = "nvidia,tegra114-spi", }, |
1017 | {} | 1017 | {} |
1018 | }; | 1018 | }; |
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 47869ea636e1..3548ce25c08f 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c | |||
@@ -419,7 +419,7 @@ static irqreturn_t tegra_sflash_isr(int irq, void *context_data) | |||
419 | return handle_cpu_based_xfer(tsd); | 419 | return handle_cpu_based_xfer(tsd); |
420 | } | 420 | } |
421 | 421 | ||
422 | static struct of_device_id tegra_sflash_of_match[] = { | 422 | static const struct of_device_id tegra_sflash_of_match[] = { |
423 | { .compatible = "nvidia,tegra20-sflash", }, | 423 | { .compatible = "nvidia,tegra20-sflash", }, |
424 | {} | 424 | {} |
425 | }; | 425 | }; |
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index e3c1b93e45d1..0b9e32e9f493 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c | |||
@@ -1001,7 +1001,7 @@ static const struct tegra_slink_chip_data tegra20_spi_cdata = { | |||
1001 | .cs_hold_time = false, | 1001 | .cs_hold_time = false, |
1002 | }; | 1002 | }; |
1003 | 1003 | ||
1004 | static struct of_device_id tegra_slink_of_match[] = { | 1004 | static const struct of_device_id tegra_slink_of_match[] = { |
1005 | { .compatible = "nvidia,tegra30-slink", .data = &tegra30_spi_cdata, }, | 1005 | { .compatible = "nvidia,tegra30-slink", .data = &tegra30_spi_cdata, }, |
1006 | { .compatible = "nvidia,tegra20-slink", .data = &tegra20_spi_cdata, }, | 1006 | { .compatible = "nvidia,tegra20-slink", .data = &tegra20_spi_cdata, }, |
1007 | {} | 1007 | {} |