diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index cf007f3b83ec..4969dc10684a 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c @@ -167,6 +167,11 @@ static void sun4i_spi_set_cs(struct spi_device *spi, bool enable) sun4i_spi_write(sspi, SUN4I_CTL_REG, reg); } +static size_t sun4i_spi_max_transfer_size(struct spi_device *spi) +{ + return SUN4I_FIFO_DEPTH - 1; +} + static int sun4i_spi_transfer_one(struct spi_master *master, struct spi_device *spi, struct spi_transfer *tfr) @@ -402,6 +407,8 @@ static int sun4i_spi_probe(struct platform_device *pdev) } sspi->master = master; + master->max_speed_hz = 100 * 1000 * 1000; + master->min_speed_hz = 3 * 1000; master->set_cs = sun4i_spi_set_cs; master->transfer_one = sun4i_spi_transfer_one; master->num_chipselect = 4; @@ -409,6 +416,7 @@ static int sun4i_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_MASK(8); master->dev.of_node = pdev->dev.of_node; master->auto_runtime_pm = true; + master->max_transfer_size = sun4i_spi_max_transfer_size; sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); if (IS_ERR(sspi->hclk)) { diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 7fce79a60608..9918a57a6a6e 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -153,6 +153,10 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); } +static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) +{ + return SUN6I_FIFO_DEPTH - 1; +} static int sun6i_spi_transfer_one(struct spi_master *master, struct spi_device *spi, @@ -394,6 +398,8 @@ static int sun6i_spi_probe(struct platform_device *pdev) } sspi->master = master; + master->max_speed_hz = 100 * 1000 * 1000; + master->min_speed_hz = 3 * 1000; master->set_cs = sun6i_spi_set_cs; master->transfer_one = sun6i_spi_transfer_one; master->num_chipselect = 4; @@ -401,6 +407,7 @@ static int sun6i_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_MASK(8); master->dev.of_node = pdev->dev.of_node; master->auto_runtime_pm = true; + master->max_transfer_size = sun6i_spi_max_transfer_size; sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); if (IS_ERR(sspi->hclk)) { diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 29ea8d2f9824..ac0b072815a3 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -141,7 +141,7 @@ static int ti_qspi_setup(struct spi_device *spi) u32 clk_ctrl_reg, clk_rate, clk_mask; if (spi->master->busy) { - dev_dbg(qspi->dev, "master busy doing other trasnfers\n"); + dev_dbg(qspi->dev, "master busy doing other transfers\n"); return -EBUSY; } diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 93dfcee0f987..c54ee6674471 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -133,8 +133,6 @@ struct pch_spi_dma_ctrl { * @io_remap_addr: The remapped PCI base address * @master: Pointer to the SPI master structure * @work: Reference to work queue handler - * @wk: Workqueue for carrying out execution of the - * requests * @wait: Wait queue for waking up upon receiving an * interrupt. * @transfer_complete: Status of SPI Transfer @@ -169,7 +167,6 @@ struct pch_spi_data { unsigned long io_base_addr; struct spi_master *master; struct work_struct work; - struct workqueue_struct *wk; wait_queue_head_t wait; u8 transfer_complete; u8 bcurrent_msg_processing; @@ -517,8 +514,7 @@ static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg) dev_dbg(&pspi->dev, "%s - Invoked list_add_tail\n", __func__); - /* schedule work queue to run */ - queue_work(data->wk, &data->work); + schedule_work(&data->work); dev_dbg(&pspi->dev, "%s - Invoked queue work\n", __func__); retval = 0; @@ -674,7 +670,7 @@ static void pch_spi_nomore_transfer(struct pch_spi_data *data) *more messages) */ dev_dbg(&data->master->dev, "%s:Invoke queue_work\n", __func__); - queue_work(data->wk, &data->work); + schedule_work(&data->work); } else if (data->board_dat->suspend_sts || data->status == STATUS_EXITING) { dev_dbg(&data->master->dev, @@ -1266,14 +1262,7 @@ static void pch_spi_free_resources(struct pch_spi_board_data *board_dat, { dev_dbg(&board_dat->pdev->dev, "%s ENTRY\n", __func__); - /* free workqueue */ - if (data->wk != NULL) { - destroy_workqueue(data->wk); - data->wk = NULL; - dev_dbg(&board_dat->pdev->dev, - "%s destroy_workqueue invoked successfully\n", - __func__); - } + flush_work(&data->work); } static int pch_spi_get_resources(struct pch_spi_board_data *board_dat, @@ -1283,14 +1272,6 @@ static int pch_spi_get_resources(struct pch_spi_board_data *board_dat, dev_dbg(&board_dat->pdev->dev, "%s ENTRY\n", __func__); - /* create workqueue */ - data->wk = create_singlethread_workqueue(KBUILD_MODNAME); - if (!data->wk) { - dev_err(&board_dat->pdev->dev, - "%s create_singlet hread_workqueue failed\n", __func__); - retval = -EBUSY; - goto err_return; - } /* reset PCH SPI h/w */ pch_spi_reset(data->master); @@ -1299,7 +1280,6 @@ static int pch_spi_get_resources(struct pch_spi_board_data *board_dat, dev_dbg(&board_dat->pdev->dev, "%s data->irq_reg_sts=true\n", __func__); -err_return: if (retval != 0) { dev_err(&board_dat->pdev->dev, "%s FAIL:invoking pch_spi_free_resources\n", __func__); diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index d69f8f8f3fa6..7492ea346b43 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c @@ -72,7 +72,6 @@ struct txx9spi { - struct workqueue_struct *workqueue; struct work_struct work; spinlock_t lock; /* protect 'queue' */ struct list_head queue; @@ -315,7 +314,7 @@ static int txx9spi_transfer(struct spi_device *spi, struct spi_message *m) spin_lock_irqsave(&c->lock, flags); list_add_tail(&m->queue, &c->queue); - queue_work(c->workqueue, &c->work); + schedule_work(&c->work); spin_unlock_irqrestore(&c->lock, flags); return 0; @@ -374,10 +373,6 @@ static int txx9spi_probe(struct platform_device *dev) if (ret) goto exit; - c->workqueue = create_singlethread_workqueue( - dev_name(master->dev.parent)); - if (!c->workqueue) - goto exit_busy; c->last_chipselect = -1; dev_info(&dev->dev, "at %#llx, irq %d, %dMHz\n", @@ -400,8 +395,6 @@ static int txx9spi_probe(struct platform_device *dev) exit_busy: ret = -EBUSY; exit: - if (c->workqueue) - destroy_workqueue(c->workqueue); clk_disable(c->clk); spi_master_put(master); return ret; @@ -412,7 +405,7 @@ static int txx9spi_remove(struct platform_device *dev) struct spi_master *master = platform_get_drvdata(dev); struct txx9spi *c = spi_master_get_devdata(master); - destroy_workqueue(c->workqueue); + flush_work(&c->work); clk_disable(c->clk); return 0; } diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index e3c19f30f591..2e05046f866b 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -700,6 +701,43 @@ static const struct of_device_id spidev_dt_ids[] = { MODULE_DEVICE_TABLE(of, spidev_dt_ids); #endif +#ifdef CONFIG_ACPI + +/* Dummy SPI devices not to be used in production systems */ +#define SPIDEV_ACPI_DUMMY 1 + +static const struct acpi_device_id spidev_acpi_ids[] = { + /* + * The ACPI SPT000* devices are only meant for development and + * testing. Systems used in production should have a proper ACPI + * description of the connected peripheral and they should also use + * a proper driver instead of poking directly to the SPI bus. + */ + { "SPT0001", SPIDEV_ACPI_DUMMY }, + { "SPT0002", SPIDEV_ACPI_DUMMY }, + { "SPT0003", SPIDEV_ACPI_DUMMY }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, spidev_acpi_ids); + +static void spidev_probe_acpi(struct spi_device *spi) +{ + const struct acpi_device_id *id; + + if (!has_acpi_companion(&spi->dev)) + return; + + id = acpi_match_device(spidev_acpi_ids, &spi->dev); + if (WARN_ON(!id)) + return; + + if (id->driver_data == SPIDEV_ACPI_DUMMY) + dev_warn(&spi->dev, "do not use this driver in production systems!\n"); +} +#else +static inline void spidev_probe_acpi(struct spi_device *spi) {} +#endif + /*-------------------------------------------------------------------------*/ static int spidev_probe(struct spi_device *spi) @@ -719,6 +757,8 @@ static int spidev_probe(struct spi_device *spi) !of_match_device(spidev_dt_ids, &spi->dev)); } + spidev_probe_acpi(spi); + /* Allocate driver data */ spidev = kzalloc(sizeof(*spidev), GFP_KERNEL); if (!spidev) @@ -789,6 +829,7 @@ static struct spi_driver spidev_spi_driver = { .driver = { .name = "spidev", .of_match_table = of_match_ptr(spidev_dt_ids), + .acpi_match_table = ACPI_PTR(spidev_acpi_ids), }, .probe = spidev_probe, .remove = spidev_remove,