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.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 8708da7c8140..656dd3e3220c 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -725,6 +725,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
int desc_len;
int sgs;
struct page *vm_page;
+ struct scatterlist *sg;
void *sg_buf;
size_t min;
int i, ret;
@@ -743,6 +744,7 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
if (ret != 0)
return ret;
+ sg = &sgt->sgl[0];
for (i = 0; i < sgs; i++) {
if (vmalloced_buf || kmap_buf) {
@@ -756,16 +758,17 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
sg_free_table(sgt);
return -ENOMEM;
}
- sg_set_page(&sgt->sgl[i], vm_page,
+ sg_set_page(sg, vm_page,
min, offset_in_page(buf));
} else {
min = min_t(size_t, len, desc_len);
sg_buf = buf;
- sg_set_buf(&sgt->sgl[i], sg_buf, min);
+ sg_set_buf(sg, sg_buf, min);
}
buf += min;
len -= min;
+ sg = sg_next(sg);
}
ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
@@ -1039,8 +1042,14 @@ static int spi_transfer_one_message(struct spi_master *master,
if (msg->status != -EINPROGRESS)
goto out;
- if (xfer->delay_usecs)
- udelay(xfer->delay_usecs);
+ if (xfer->delay_usecs) {
+ u16 us = xfer->delay_usecs;
+
+ if (us <= 10)
+ udelay(us);
+ else
+ usleep_range(us, us + DIV_ROUND_UP(us, 10));
+ }
if (xfer->cs_change) {
if (list_is_last(&xfer->transfer_list,
@@ -1117,7 +1126,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;
}
@@ -1131,7 +1140,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;
@@ -1255,7 +1264,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));
@@ -1263,7 +1272,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
@@ -1336,7 +1345,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);
@@ -1362,7 +1371,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;
}
@@ -1409,7 +1418,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.
@@ -1419,7 +1428,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;
@@ -1443,7 +1452,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;
@@ -1623,9 +1632,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
@@ -3136,6 +3147,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;