aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorChris Blair <chris.blair@stericsson.com>2012-02-02 07:59:34 -0500
committerGrant Likely <grant.likely@secretlab.ca>2012-02-02 13:32:16 -0500
commit14af60b6fb3b76634278364b697dae2f9f360abf (patch)
tree7b454608c85bb6823384009a90ebe290431f17cf /drivers/spi
parent90bbf4fdf2dc64aa7c20a93a9744c56a566baf26 (diff)
spi/pl022: Add high priority message pump support
This switches the PL022 worker to a kthread in order to get hold of a mechanism to control the message pump priority. On low-latency systems elevating the message kthread to realtime priority give a real sleek response curve. This has been confirmed by measurements. Realtime priority elevation for a certain PL022 port can be requested from platform data. Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Chris Blair <chris.blair@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-pl022.c77
1 files changed, 52 insertions, 25 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 2f9cb43a2398..81847c9a7586 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -29,7 +29,7 @@
29#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/spi/spi.h> 31#include <linux/spi/spi.h>
32#include <linux/workqueue.h> 32#include <linux/kthread.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/clk.h> 34#include <linux/clk.h>
35#include <linux/err.h> 35#include <linux/err.h>
@@ -41,6 +41,7 @@
41#include <linux/dma-mapping.h> 41#include <linux/dma-mapping.h>
42#include <linux/scatterlist.h> 42#include <linux/scatterlist.h>
43#include <linux/pm_runtime.h> 43#include <linux/pm_runtime.h>
44#include <linux/sched.h>
44 45
45/* 46/*
46 * This macro is used to define some register default values. 47 * This macro is used to define some register default values.
@@ -330,12 +331,13 @@ struct vendor_data {
330 * @clk: outgoing clock "SPICLK" for the SPI bus 331 * @clk: outgoing clock "SPICLK" for the SPI bus
331 * @master: SPI framework hookup 332 * @master: SPI framework hookup
332 * @master_info: controller-specific data from machine setup 333 * @master_info: controller-specific data from machine setup
333 * @workqueue: a workqueue on which any spi_message request is queued 334 * @kworker: thread struct for message pump
334 * @pump_messages: work struct for scheduling work to the workqueue 335 * @kworker_task: pointer to task for message pump kworker thread
336 * @pump_messages: work struct for scheduling work to the message pump
335 * @queue_lock: spinlock to syncronise access to message queue 337 * @queue_lock: spinlock to syncronise access to message queue
336 * @queue: message queue 338 * @queue: message queue
337 * @busy: workqueue is busy 339 * @busy: message pump is busy
338 * @running: workqueue is running 340 * @running: message pump is running
339 * @pump_transfers: Tasklet used in Interrupt Transfer mode 341 * @pump_transfers: Tasklet used in Interrupt Transfer mode
340 * @cur_msg: Pointer to current spi_message being processed 342 * @cur_msg: Pointer to current spi_message being processed
341 * @cur_transfer: Pointer to current spi_transfer 343 * @cur_transfer: Pointer to current spi_transfer
@@ -365,9 +367,10 @@ struct pl022 {
365 struct clk *clk; 367 struct clk *clk;
366 struct spi_master *master; 368 struct spi_master *master;
367 struct pl022_ssp_controller *master_info; 369 struct pl022_ssp_controller *master_info;
368 /* Driver message queue */ 370 /* Driver message pump */
369 struct workqueue_struct *workqueue; 371 struct kthread_worker kworker;
370 struct work_struct pump_messages; 372 struct task_struct *kworker_task;
373 struct kthread_work pump_messages;
371 spinlock_t queue_lock; 374 spinlock_t queue_lock;
372 struct list_head queue; 375 struct list_head queue;
373 bool busy; 376 bool busy;
@@ -504,7 +507,7 @@ static void giveback(struct pl022 *pl022)
504 pl022->cur_msg = NULL; 507 pl022->cur_msg = NULL;
505 pl022->cur_transfer = NULL; 508 pl022->cur_transfer = NULL;
506 pl022->cur_chip = NULL; 509 pl022->cur_chip = NULL;
507 queue_work(pl022->workqueue, &pl022->pump_messages); 510 queue_kthread_work(&pl022->kworker, &pl022->pump_messages);
508 spin_unlock_irqrestore(&pl022->queue_lock, flags); 511 spin_unlock_irqrestore(&pl022->queue_lock, flags);
509 512
510 msg->state = NULL; 513 msg->state = NULL;
@@ -1494,8 +1497,8 @@ out:
1494} 1497}
1495 1498
1496/** 1499/**
1497 * pump_messages - Workqueue function which processes spi message queue 1500 * pump_messages - kthread work function which processes spi message queue
1498 * @data: pointer to private data of SSP driver 1501 * @work: pointer to kthread work struct contained in the pl022 private struct
1499 * 1502 *
1500 * This function checks if there is any spi message in the queue that 1503 * This function checks if there is any spi message in the queue that
1501 * needs processing and delegate control to appropriate function 1504 * needs processing and delegate control to appropriate function
@@ -1503,7 +1506,7 @@ out:
1503 * based on the kind of the transfer 1506 * based on the kind of the transfer
1504 * 1507 *
1505 */ 1508 */
1506static void pump_messages(struct work_struct *work) 1509static void pump_messages(struct kthread_work *work)
1507{ 1510{
1508 struct pl022 *pl022 = 1511 struct pl022 *pl022 =
1509 container_of(work, struct pl022, pump_messages); 1512 container_of(work, struct pl022, pump_messages);
@@ -1556,7 +1559,7 @@ static void pump_messages(struct work_struct *work)
1556 if (!was_busy) 1559 if (!was_busy)
1557 /* 1560 /*
1558 * We enable the core voltage and clocks here, then the clocks 1561 * We enable the core voltage and clocks here, then the clocks
1559 * and core will be disabled when this workqueue is run again 1562 * and core will be disabled when this thread is run again
1560 * and there is no more work to be done. 1563 * and there is no more work to be done.
1561 */ 1564 */
1562 pm_runtime_get_sync(&pl022->adev->dev); 1565 pm_runtime_get_sync(&pl022->adev->dev);
@@ -1572,6 +1575,8 @@ static void pump_messages(struct work_struct *work)
1572 1575
1573static int __init init_queue(struct pl022 *pl022) 1576static int __init init_queue(struct pl022 *pl022)
1574{ 1577{
1578 struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
1579
1575 INIT_LIST_HEAD(&pl022->queue); 1580 INIT_LIST_HEAD(&pl022->queue);
1576 spin_lock_init(&pl022->queue_lock); 1581 spin_lock_init(&pl022->queue_lock);
1577 1582
@@ -1581,11 +1586,29 @@ static int __init init_queue(struct pl022 *pl022)
1581 tasklet_init(&pl022->pump_transfers, pump_transfers, 1586 tasklet_init(&pl022->pump_transfers, pump_transfers,
1582 (unsigned long)pl022); 1587 (unsigned long)pl022);
1583 1588
1584 INIT_WORK(&pl022->pump_messages, pump_messages); 1589 init_kthread_worker(&pl022->kworker);
1585 pl022->workqueue = create_singlethread_workqueue( 1590 pl022->kworker_task = kthread_run(kthread_worker_fn,
1591 &pl022->kworker,
1586 dev_name(pl022->master->dev.parent)); 1592 dev_name(pl022->master->dev.parent));
1587 if (pl022->workqueue == NULL) 1593 if (IS_ERR(pl022->kworker_task)) {
1588 return -EBUSY; 1594 dev_err(&pl022->adev->dev,
1595 "failed to create message pump task\n");
1596 return -ENOMEM;
1597 }
1598 init_kthread_work(&pl022->pump_messages, pump_messages);
1599
1600 /*
1601 * Board config will indicate if this controller should run the
1602 * message pump with high (realtime) priority to reduce the transfer
1603 * latency on the bus by minimising the delay between a transfer
1604 * request and the scheduling of the message pump thread. Without this
1605 * setting the message pump thread will remain at default priority.
1606 */
1607 if (pl022->master_info->rt) {
1608 dev_info(&pl022->adev->dev,
1609 "will run message pump with realtime priority\n");
1610 sched_setscheduler(pl022->kworker_task, SCHED_FIFO, &param);
1611 }
1589 1612
1590 return 0; 1613 return 0;
1591} 1614}
@@ -1608,7 +1631,7 @@ static int start_queue(struct pl022 *pl022)
1608 pl022->next_msg_cs_active = false; 1631 pl022->next_msg_cs_active = false;
1609 spin_unlock_irqrestore(&pl022->queue_lock, flags); 1632 spin_unlock_irqrestore(&pl022->queue_lock, flags);
1610 1633
1611 queue_work(pl022->workqueue, &pl022->pump_messages); 1634 queue_kthread_work(&pl022->kworker, &pl022->pump_messages);
1612 1635
1613 return 0; 1636 return 0;
1614} 1637}
@@ -1646,16 +1669,20 @@ static int destroy_queue(struct pl022 *pl022)
1646 int status; 1669 int status;
1647 1670
1648 status = stop_queue(pl022); 1671 status = stop_queue(pl022);
1649 /* we are unloading the module or failing to load (only two calls 1672
1673 /*
1674 * We are unloading the module or failing to load (only two calls
1650 * to this routine), and neither call can handle a return value. 1675 * to this routine), and neither call can handle a return value.
1651 * However, destroy_workqueue calls flush_workqueue, and that will 1676 * However, flush_kthread_worker will block until all work is done.
1652 * block until all work is done. If the reason that stop_queue 1677 * If the reason that stop_queue timed out is that the work will never
1653 * timed out is that the work will never finish, then it does no 1678 * finish, then it does no good to call flush/stop thread, so
1654 * good to call destroy_workqueue, so return anyway. */ 1679 * return anyway.
1680 */
1655 if (status != 0) 1681 if (status != 0)
1656 return status; 1682 return status;
1657 1683
1658 destroy_workqueue(pl022->workqueue); 1684 flush_kthread_worker(&pl022->kworker);
1685 kthread_stop(pl022->kworker_task);
1659 1686
1660 return 0; 1687 return 0;
1661} 1688}
@@ -1802,7 +1829,7 @@ static int pl022_transfer(struct spi_device *spi, struct spi_message *msg)
1802 1829
1803 list_add_tail(&msg->queue, &pl022->queue); 1830 list_add_tail(&msg->queue, &pl022->queue);
1804 if (pl022->running && !pl022->busy) 1831 if (pl022->running && !pl022->busy)
1805 queue_work(pl022->workqueue, &pl022->pump_messages); 1832 queue_kthread_work(&pl022->kworker, &pl022->pump_messages);
1806 1833
1807 spin_unlock_irqrestore(&pl022->queue_lock, flags); 1834 spin_unlock_irqrestore(&pl022->queue_lock, flags);
1808 return 0; 1835 return 0;