Merge tag 'gcc-plugins-v4.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / spi / spi.c
index 200ca22..838783c 100644 (file)
@@ -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;
@@ -1607,9 +1618,11 @@ static void of_register_spi_devices(struct spi_master *master)
                if (of_node_test_and_set_flag(nc, OF_POPULATED))
                        continue;
                spi = of_register_spi_device(master, nc);
-               if (IS_ERR(spi))
+               if (IS_ERR(spi)) {
                        dev_warn(&master->dev, "Failed to create SPI device for %s\n",
                                nc->full_name);
+                       of_node_clear_flag(nc, OF_POPULATED);
+               }
        }
 }
 #else
@@ -3120,6 +3133,7 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action,
                if (IS_ERR(spi)) {
                        pr_err("%s: failed to create for '%s'\n",
                                        __func__, rd->dn->full_name);
+                       of_node_clear_flag(rd->dn, OF_POPULATED);
                        return notifier_from_errno(PTR_ERR(spi));
                }
                break;