diff options
author | H Hartley Sweeten <hartleys@visionengravers.com> | 2013-07-08 12:12:37 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-07-17 06:10:59 -0400 |
commit | 84ddb3c1df021c69a40af30e3e30cc7429a5d659 (patch) | |
tree | 0e4b3192f950f2519df9ac1e44e27910f02d5601 /drivers/spi/spi-ep93xx.c | |
parent | f7ef1da9e22ce390333645fc0ea70ff279eecd55 (diff) |
spi: spi-ep93xx: convert to the queued driver infrastructure
The SPI core provides infrastructure for standard message queueing. Use
that instead of handling it in the driver.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: Mika Westerberg <mika.westerberg@iki.fi>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-ep93xx.c')
-rw-r--r-- | drivers/spi/spi-ep93xx.c | 165 |
1 files changed, 19 insertions, 146 deletions
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 2e64806b40af..4c9a50ce4f6c 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/workqueue.h> | ||
30 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
31 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
32 | #include <linux/spi/spi.h> | 31 | #include <linux/spi/spi.h> |
@@ -70,19 +69,13 @@ | |||
70 | 69 | ||
71 | /** | 70 | /** |
72 | * struct ep93xx_spi - EP93xx SPI controller structure | 71 | * struct ep93xx_spi - EP93xx SPI controller structure |
73 | * @lock: spinlock that protects concurrent accesses to fields @running, | ||
74 | * @current_msg and @msg_queue | ||
75 | * @pdev: pointer to platform device | 72 | * @pdev: pointer to platform device |
76 | * @clk: clock for the controller | 73 | * @clk: clock for the controller |
77 | * @regs_base: pointer to ioremap()'d registers | 74 | * @regs_base: pointer to ioremap()'d registers |
78 | * @sspdr_phys: physical address of the SSPDR register | 75 | * @sspdr_phys: physical address of the SSPDR register |
79 | * @min_rate: minimum clock rate (in Hz) supported by the controller | 76 | * @min_rate: minimum clock rate (in Hz) supported by the controller |
80 | * @max_rate: maximum clock rate (in Hz) supported by the controller | 77 | * @max_rate: maximum clock rate (in Hz) supported by the controller |
81 | * @running: is the queue running | ||
82 | * @wq: workqueue used by the driver | ||
83 | * @msg_work: work that is queued for the driver | ||
84 | * @wait: wait here until given transfer is completed | 78 | * @wait: wait here until given transfer is completed |
85 | * @msg_queue: queue for the messages | ||
86 | * @current_msg: message that is currently processed (or %NULL if none) | 79 | * @current_msg: message that is currently processed (or %NULL if none) |
87 | * @tx: current byte in transfer to transmit | 80 | * @tx: current byte in transfer to transmit |
88 | * @rx: current byte in transfer to receive | 81 | * @rx: current byte in transfer to receive |
@@ -96,30 +89,15 @@ | |||
96 | * @tx_sgt: sg table for TX transfers | 89 | * @tx_sgt: sg table for TX transfers |
97 | * @zeropage: dummy page used as RX buffer when only TX buffer is passed in by | 90 | * @zeropage: dummy page used as RX buffer when only TX buffer is passed in by |
98 | * the client | 91 | * the client |
99 | * | ||
100 | * This structure holds EP93xx SPI controller specific information. When | ||
101 | * @running is %true, driver accepts transfer requests from protocol drivers. | ||
102 | * @current_msg is used to hold pointer to the message that is currently | ||
103 | * processed. If @current_msg is %NULL, it means that no processing is going | ||
104 | * on. | ||
105 | * | ||
106 | * Most of the fields are only written once and they can be accessed without | ||
107 | * taking the @lock. Fields that are accessed concurrently are: @current_msg, | ||
108 | * @running, and @msg_queue. | ||
109 | */ | 92 | */ |
110 | struct ep93xx_spi { | 93 | struct ep93xx_spi { |
111 | spinlock_t lock; | ||
112 | const struct platform_device *pdev; | 94 | const struct platform_device *pdev; |
113 | struct clk *clk; | 95 | struct clk *clk; |
114 | void __iomem *regs_base; | 96 | void __iomem *regs_base; |
115 | unsigned long sspdr_phys; | 97 | unsigned long sspdr_phys; |
116 | unsigned long min_rate; | 98 | unsigned long min_rate; |
117 | unsigned long max_rate; | 99 | unsigned long max_rate; |
118 | bool running; | ||
119 | struct workqueue_struct *wq; | ||
120 | struct work_struct msg_work; | ||
121 | struct completion wait; | 100 | struct completion wait; |
122 | struct list_head msg_queue; | ||
123 | struct spi_message *current_msg; | 101 | struct spi_message *current_msg; |
124 | size_t tx; | 102 | size_t tx; |
125 | size_t rx; | 103 | size_t rx; |
@@ -230,7 +208,7 @@ static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi, | |||
230 | /* | 208 | /* |
231 | * Make sure that max value is between values supported by the | 209 | * Make sure that max value is between values supported by the |
232 | * controller. Note that minimum value is already checked in | 210 | * controller. Note that minimum value is already checked in |
233 | * ep93xx_spi_transfer(). | 211 | * ep93xx_spi_transfer_one_message(). |
234 | */ | 212 | */ |
235 | rate = clamp(rate, espi->min_rate, espi->max_rate); | 213 | rate = clamp(rate, espi->min_rate, espi->max_rate); |
236 | 214 | ||
@@ -306,54 +284,6 @@ static int ep93xx_spi_setup(struct spi_device *spi) | |||
306 | } | 284 | } |
307 | 285 | ||
308 | /** | 286 | /** |
309 | * ep93xx_spi_transfer() - queue message to be transferred | ||
310 | * @spi: target SPI device | ||
311 | * @msg: message to be transferred | ||
312 | * | ||
313 | * This function is called by SPI device drivers when they are going to transfer | ||
314 | * a new message. It simply puts the message in the queue and schedules | ||
315 | * workqueue to perform the actual transfer later on. | ||
316 | * | ||
317 | * Returns %0 on success and negative error in case of failure. | ||
318 | */ | ||
319 | static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *msg) | ||
320 | { | ||
321 | struct ep93xx_spi *espi = spi_master_get_devdata(spi->master); | ||
322 | struct spi_transfer *t; | ||
323 | unsigned long flags; | ||
324 | |||
325 | if (!msg || !msg->complete) | ||
326 | return -EINVAL; | ||
327 | |||
328 | /* first validate each transfer */ | ||
329 | list_for_each_entry(t, &msg->transfers, transfer_list) { | ||
330 | if (t->speed_hz && t->speed_hz < espi->min_rate) | ||
331 | return -EINVAL; | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * Now that we own the message, let's initialize it so that it is | ||
336 | * suitable for us. We use @msg->status to signal whether there was | ||
337 | * error in transfer and @msg->state is used to hold pointer to the | ||
338 | * current transfer (or %NULL if no active current transfer). | ||
339 | */ | ||
340 | msg->state = NULL; | ||
341 | msg->status = 0; | ||
342 | msg->actual_length = 0; | ||
343 | |||
344 | spin_lock_irqsave(&espi->lock, flags); | ||
345 | if (!espi->running) { | ||
346 | spin_unlock_irqrestore(&espi->lock, flags); | ||
347 | return -ESHUTDOWN; | ||
348 | } | ||
349 | list_add_tail(&msg->queue, &espi->msg_queue); | ||
350 | queue_work(espi->wq, &espi->msg_work); | ||
351 | spin_unlock_irqrestore(&espi->lock, flags); | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | /** | ||
357 | * ep93xx_spi_cleanup() - cleans up master controller specific state | 287 | * ep93xx_spi_cleanup() - cleans up master controller specific state |
358 | * @spi: SPI device to cleanup | 288 | * @spi: SPI device to cleanup |
359 | * | 289 | * |
@@ -801,50 +731,29 @@ static void ep93xx_spi_process_message(struct ep93xx_spi *espi, | |||
801 | ep93xx_spi_disable(espi); | 731 | ep93xx_spi_disable(espi); |
802 | } | 732 | } |
803 | 733 | ||
804 | #define work_to_espi(work) (container_of((work), struct ep93xx_spi, msg_work)) | 734 | static int ep93xx_spi_transfer_one_message(struct spi_master *master, |
805 | 735 | struct spi_message *msg) | |
806 | /** | ||
807 | * ep93xx_spi_work() - EP93xx SPI workqueue worker function | ||
808 | * @work: work struct | ||
809 | * | ||
810 | * Workqueue worker function. This function is called when there are new | ||
811 | * SPI messages to be processed. Message is taken out from the queue and then | ||
812 | * passed to ep93xx_spi_process_message(). | ||
813 | * | ||
814 | * After message is transferred, protocol driver is notified by calling | ||
815 | * @msg->complete(). In case of error, @msg->status is set to negative error | ||
816 | * number, otherwise it contains zero (and @msg->actual_length is updated). | ||
817 | */ | ||
818 | static void ep93xx_spi_work(struct work_struct *work) | ||
819 | { | 736 | { |
820 | struct ep93xx_spi *espi = work_to_espi(work); | 737 | struct ep93xx_spi *espi = spi_master_get_devdata(master); |
821 | struct spi_message *msg; | 738 | struct spi_transfer *t; |
822 | 739 | ||
823 | spin_lock_irq(&espi->lock); | 740 | /* first validate each transfer */ |
824 | if (!espi->running || espi->current_msg || | 741 | list_for_each_entry(t, &msg->transfers, transfer_list) { |
825 | list_empty(&espi->msg_queue)) { | 742 | if (t->speed_hz < espi->min_rate) |
826 | spin_unlock_irq(&espi->lock); | 743 | return -EINVAL; |
827 | return; | ||
828 | } | 744 | } |
829 | msg = list_first_entry(&espi->msg_queue, struct spi_message, queue); | ||
830 | list_del_init(&msg->queue); | ||
831 | espi->current_msg = msg; | ||
832 | spin_unlock_irq(&espi->lock); | ||
833 | 745 | ||
834 | ep93xx_spi_process_message(espi, msg); | 746 | msg->state = NULL; |
747 | msg->status = 0; | ||
748 | msg->actual_length = 0; | ||
835 | 749 | ||
836 | /* | 750 | espi->current_msg = msg; |
837 | * Update the current message and re-schedule ourselves if there are | 751 | ep93xx_spi_process_message(espi, msg); |
838 | * more messages in the queue. | ||
839 | */ | ||
840 | spin_lock_irq(&espi->lock); | ||
841 | espi->current_msg = NULL; | 752 | espi->current_msg = NULL; |
842 | if (espi->running && !list_empty(&espi->msg_queue)) | ||
843 | queue_work(espi->wq, &espi->msg_work); | ||
844 | spin_unlock_irq(&espi->lock); | ||
845 | 753 | ||
846 | /* notify the protocol driver that we are done with this message */ | 754 | spi_finalize_current_message(master); |
847 | msg->complete(msg->context); | 755 | |
756 | return 0; | ||
848 | } | 757 | } |
849 | 758 | ||
850 | static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) | 759 | static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) |
@@ -984,7 +893,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev) | |||
984 | return -ENOMEM; | 893 | return -ENOMEM; |
985 | 894 | ||
986 | master->setup = ep93xx_spi_setup; | 895 | master->setup = ep93xx_spi_setup; |
987 | master->transfer = ep93xx_spi_transfer; | 896 | master->transfer_one_message = ep93xx_spi_transfer_one_message; |
988 | master->cleanup = ep93xx_spi_cleanup; | 897 | master->cleanup = ep93xx_spi_cleanup; |
989 | master->bus_num = pdev->id; | 898 | master->bus_num = pdev->id; |
990 | master->num_chipselect = info->num_chipselect; | 899 | master->num_chipselect = info->num_chipselect; |
@@ -1002,7 +911,6 @@ static int ep93xx_spi_probe(struct platform_device *pdev) | |||
1002 | goto fail_release_master; | 911 | goto fail_release_master; |
1003 | } | 912 | } |
1004 | 913 | ||
1005 | spin_lock_init(&espi->lock); | ||
1006 | init_completion(&espi->wait); | 914 | init_completion(&espi->wait); |
1007 | 915 | ||
1008 | /* | 916 | /* |
@@ -1031,23 +939,13 @@ static int ep93xx_spi_probe(struct platform_device *pdev) | |||
1031 | if (info->use_dma && ep93xx_spi_setup_dma(espi)) | 939 | if (info->use_dma && ep93xx_spi_setup_dma(espi)) |
1032 | dev_warn(&pdev->dev, "DMA setup failed. Falling back to PIO\n"); | 940 | dev_warn(&pdev->dev, "DMA setup failed. Falling back to PIO\n"); |
1033 | 941 | ||
1034 | espi->wq = create_singlethread_workqueue("ep93xx_spid"); | ||
1035 | if (!espi->wq) { | ||
1036 | dev_err(&pdev->dev, "unable to create workqueue\n"); | ||
1037 | error = -ENOMEM; | ||
1038 | goto fail_free_dma; | ||
1039 | } | ||
1040 | INIT_WORK(&espi->msg_work, ep93xx_spi_work); | ||
1041 | INIT_LIST_HEAD(&espi->msg_queue); | ||
1042 | espi->running = true; | ||
1043 | |||
1044 | /* make sure that the hardware is disabled */ | 942 | /* make sure that the hardware is disabled */ |
1045 | ep93xx_spi_write_u8(espi, SSPCR1, 0); | 943 | ep93xx_spi_write_u8(espi, SSPCR1, 0); |
1046 | 944 | ||
1047 | error = spi_register_master(master); | 945 | error = spi_register_master(master); |
1048 | if (error) { | 946 | if (error) { |
1049 | dev_err(&pdev->dev, "failed to register SPI master\n"); | 947 | dev_err(&pdev->dev, "failed to register SPI master\n"); |
1050 | goto fail_free_queue; | 948 | goto fail_free_dma; |
1051 | } | 949 | } |
1052 | 950 | ||
1053 | dev_info(&pdev->dev, "EP93xx SPI Controller at 0x%08lx irq %d\n", | 951 | dev_info(&pdev->dev, "EP93xx SPI Controller at 0x%08lx irq %d\n", |
@@ -1055,8 +953,6 @@ static int ep93xx_spi_probe(struct platform_device *pdev) | |||
1055 | 953 | ||
1056 | return 0; | 954 | return 0; |
1057 | 955 | ||
1058 | fail_free_queue: | ||
1059 | destroy_workqueue(espi->wq); | ||
1060 | fail_free_dma: | 956 | fail_free_dma: |
1061 | ep93xx_spi_release_dma(espi); | 957 | ep93xx_spi_release_dma(espi); |
1062 | fail_release_master: | 958 | fail_release_master: |
@@ -1070,29 +966,6 @@ static int ep93xx_spi_remove(struct platform_device *pdev) | |||
1070 | struct spi_master *master = platform_get_drvdata(pdev); | 966 | struct spi_master *master = platform_get_drvdata(pdev); |
1071 | struct ep93xx_spi *espi = spi_master_get_devdata(master); | 967 | struct ep93xx_spi *espi = spi_master_get_devdata(master); |
1072 | 968 | ||
1073 | spin_lock_irq(&espi->lock); | ||
1074 | espi->running = false; | ||
1075 | spin_unlock_irq(&espi->lock); | ||
1076 | |||
1077 | destroy_workqueue(espi->wq); | ||
1078 | |||
1079 | /* | ||
1080 | * Complete remaining messages with %-ESHUTDOWN status. | ||
1081 | */ | ||
1082 | spin_lock_irq(&espi->lock); | ||
1083 | while (!list_empty(&espi->msg_queue)) { | ||
1084 | struct spi_message *msg; | ||
1085 | |||
1086 | msg = list_first_entry(&espi->msg_queue, | ||
1087 | struct spi_message, queue); | ||
1088 | list_del_init(&msg->queue); | ||
1089 | msg->status = -ESHUTDOWN; | ||
1090 | spin_unlock_irq(&espi->lock); | ||
1091 | msg->complete(msg->context); | ||
1092 | spin_lock_irq(&espi->lock); | ||
1093 | } | ||
1094 | spin_unlock_irq(&espi->lock); | ||
1095 | |||
1096 | ep93xx_spi_release_dma(espi); | 969 | ep93xx_spi_release_dma(espi); |
1097 | 970 | ||
1098 | spi_unregister_master(master); | 971 | spi_unregister_master(master); |