summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 200ca228d885..5787b723b593 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -37,6 +37,7 @@
#include <linux/kthread.h>
#include <linux/ioport.h>
#include <linux/acpi.h>
+#include <linux/highmem.h>
#define CREATE_TRACE_POINTS
#include <trace/events/spi.h>
@@ -709,6 +710,13 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
{
const bool vmalloced_buf = is_vmalloc_addr(buf);
unsigned int max_seg_size = dma_get_max_seg_size(dev);
+#ifdef CONFIG_HIGHMEM
+ const bool kmap_buf = ((unsigned long)buf >= PKMAP_BASE &&
+ (unsigned long)buf < (PKMAP_BASE +
+ (LAST_PKMAP * PAGE_SIZE)));
+#else
+ const bool kmap_buf = false;
+#endif
int desc_len;
int sgs;
struct page *vm_page;
@@ -716,7 +724,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
size_t min;
int i, ret;
- if (vmalloced_buf) {
+ if (vmalloced_buf || kmap_buf) {
desc_len = min_t(int, max_seg_size, PAGE_SIZE);
sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len);
} else if (virt_addr_valid(buf)) {
@@ -732,10 +740,13 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
for (i = 0; i < sgs; i++) {
- if (vmalloced_buf) {
+ if (vmalloced_buf || kmap_buf) {
min = min_t(size_t,
len, desc_len - offset_in_page(buf));
- vm_page = vmalloc_to_page(buf);
+ if (vmalloced_buf)
+ vm_page = vmalloc_to_page(buf);
+ else
+ vm_page = kmap_to_page(buf);
if (!vm_page) {
sg_free_table(sgt);
return -ENOMEM;
@@ -1101,7 +1112,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
/* If another context is idling the device then defer */
if (master->idling) {
- queue_kthread_work(&master->kworker, &master->pump_messages);
+ kthread_queue_work(&master->kworker, &master->pump_messages);
spin_unlock_irqrestore(&master->queue_lock, flags);
return;
}
@@ -1115,7 +1126,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
/* Only do teardown in the thread */
if (!in_kthread) {
- queue_kthread_work(&master->kworker,
+ kthread_queue_work(&master->kworker,
&master->pump_messages);
spin_unlock_irqrestore(&master->queue_lock, flags);
return;
@@ -1239,7 +1250,7 @@ static int spi_init_queue(struct spi_master *master)
master->running = false;
master->busy = false;
- init_kthread_worker(&master->kworker);
+ kthread_init_worker(&master->kworker);
master->kworker_task = kthread_run(kthread_worker_fn,
&master->kworker, "%s",
dev_name(&master->dev));
@@ -1247,7 +1258,7 @@ static int spi_init_queue(struct spi_master *master)
dev_err(&master->dev, "failed to create message pump task\n");
return PTR_ERR(master->kworker_task);
}
- init_kthread_work(&master->pump_messages, spi_pump_messages);
+ kthread_init_work(&master->pump_messages, spi_pump_messages);
/*
* Master config will indicate if this controller should run the
@@ -1320,7 +1331,7 @@ void spi_finalize_current_message(struct spi_master *master)
spin_lock_irqsave(&master->queue_lock, flags);
master->cur_msg = NULL;
master->cur_msg_prepared = false;
- queue_kthread_work(&master->kworker, &master->pump_messages);
+ kthread_queue_work(&master->kworker, &master->pump_messages);
spin_unlock_irqrestore(&master->queue_lock, flags);
trace_spi_message_done(mesg);
@@ -1346,7 +1357,7 @@ static int spi_start_queue(struct spi_master *master)
master->cur_msg = NULL;
spin_unlock_irqrestore(&master->queue_lock, flags);
- queue_kthread_work(&master->kworker, &master->pump_messages);
+ kthread_queue_work(&master->kworker, &master->pump_messages);
return 0;
}
@@ -1393,7 +1404,7 @@ static int spi_destroy_queue(struct spi_master *master)
ret = spi_stop_queue(master);
/*
- * flush_kthread_worker will block until all work is done.
+ * kthread_flush_worker will block until all work is done.
* If the reason that stop_queue timed out is that the work will never
* finish, then it does no good to call flush/stop thread, so
* return anyway.
@@ -1403,7 +1414,7 @@ static int spi_destroy_queue(struct spi_master *master)
return ret;
}
- flush_kthread_worker(&master->kworker);
+ kthread_flush_worker(&master->kworker);
kthread_stop(master->kworker_task);
return 0;
@@ -1427,7 +1438,7 @@ static int __spi_queued_transfer(struct spi_device *spi,
list_add_tail(&msg->queue, &master->queue);
if (!master->busy && need_pump)
- queue_kthread_work(&master->kworker, &master->pump_messages);
+ kthread_queue_work(&master->kworker, &master->pump_messages);
spin_unlock_irqrestore(&master->queue_lock, flags);
return 0;