diff options
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r-- | drivers/spi/spi.c | 40 |
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; |