From aec35f4ee6eefba616065547e6882c084cc7f5cb Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 13 Feb 2014 15:28:41 +0100 Subject: spi: Clean up probe and remove functions While backporting 33cf00e5 ("spi: attach/detach SPI device to the ACPI power domain"), I noticed that the code changes were suboptimal: * Why use &spi->dev when we have dev at hand? * After fixing the above, spi is used only once, so we don't really need a local variable for it. This results in the following clean-up. Signed-off-by: Jean Delvare Acked-by: Rafael J. Wysocki Signed-off-by: Mark Brown --- drivers/spi/spi.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 23756b0f9036..bb660145d19e 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -255,13 +255,12 @@ EXPORT_SYMBOL_GPL(spi_bus_type); static int spi_drv_probe(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); - struct spi_device *spi = to_spi_device(dev); int ret; - acpi_dev_pm_attach(&spi->dev, true); - ret = sdrv->probe(spi); + acpi_dev_pm_attach(dev, true); + ret = sdrv->probe(to_spi_device(dev)); if (ret) - acpi_dev_pm_detach(&spi->dev, true); + acpi_dev_pm_detach(dev, true); return ret; } @@ -269,11 +268,10 @@ static int spi_drv_probe(struct device *dev) static int spi_drv_remove(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); - struct spi_device *spi = to_spi_device(dev); int ret; - ret = sdrv->remove(spi); - acpi_dev_pm_detach(&spi->dev, true); + ret = sdrv->remove(to_spi_device(dev)); + acpi_dev_pm_detach(dev, true); return ret; } -- cgit v1.2.3 From 4d94bd21b333c695eba97746b615e2efb30240cc Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Thu, 20 Feb 2014 12:02:08 +0200 Subject: spi: core: Validate length of the transfers in message SPI transfer length should be multiple of SPI word size, where SPI word size should be power-of-two multiple Signed-off-by: Ivan T. Ivanov Signed-off-by: Mark Brown --- drivers/spi/spi.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index bb660145d19e..1b53eee2cbca 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1617,6 +1617,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) { struct spi_master *master = spi->master; struct spi_transfer *xfer; + int w_size, n_words; if (list_empty(&message->transfers)) return -EINVAL; @@ -1668,6 +1669,22 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) return -EINVAL; } + /* + * SPI transfer length should be multiple of SPI word size + * where SPI word size should be power-of-two multiple + */ + if (xfer->bits_per_word <= 8) + w_size = 1; + else if (xfer->bits_per_word <= 16) + w_size = 2; + else + w_size = 4; + + n_words = xfer->len / w_size; + /* No partial transfers accepted */ + if (!n_words || xfer->len % w_size) + return -EINVAL; + if (xfer->speed_hz && master->min_speed_hz && xfer->speed_hz < master->min_speed_hz) return -EINVAL; -- cgit v1.2.3 From f97b26b05b1dcd307b2f79d1f9e9d99551987dbb Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 21 Feb 2014 09:15:18 +0800 Subject: spi: core: Replace msleep with usleep_range to get more accurate sleep time Fixes below checkpatch warning: WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt + msleep(10); Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 1b53eee2cbca..d5ee965fb285 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -892,7 +892,7 @@ static int spi_stop_queue(struct spi_master *master) */ while ((!list_empty(&master->queue) || master->busy) && limit--) { spin_unlock_irqrestore(&master->queue_lock, flags); - msleep(10); + usleep_range(10000, 11000); spin_lock_irqsave(&master->queue_lock, flags); } -- cgit v1.2.3 From 6ea312936d68b557766dafa9a3c4617e14ffa076 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 28 Feb 2014 23:03:16 +0900 Subject: spi: core: make zero length transfer valid again Zero length transfer becomes invalid since "spi: core: Validate length of the transfers in message" commit, but it should be valid to support an odd device, for example, which requires long delay between chipselect and the first transfer, etc. Signed-off-by: Atsushi Nemoto Tested-by: Thierry Reding Signed-off-by: Mark Brown --- drivers/spi/spi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index d5ee965fb285..9d1405440223 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1617,7 +1617,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) { struct spi_master *master = spi->master; struct spi_transfer *xfer; - int w_size, n_words; + int w_size; if (list_empty(&message->transfers)) return -EINVAL; @@ -1680,9 +1680,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) else w_size = 4; - n_words = xfer->len / w_size; /* No partial transfers accepted */ - if (!n_words || xfer->len % w_size) + if (xfer->len % w_size) return -EINVAL; if (xfer->speed_hz && master->min_speed_hz && -- cgit v1.2.3 From a6f87fad7b5132f026592729ccf65b995cdec35d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 17 Mar 2014 10:08:12 +0800 Subject: spi: core: Use master->max_speed_hz as transfer speed when xfer->speed_hz > master->max_speed_hz When xfer->speed_hz is greater than master->max_speed_hz, it's generally safe to use master->max_speed_hz as transfer speed. Thus use master->max_speed_hz as transfer speed rather than return error when xfer->speed_hz > master->max_speed_hz. Signed-off-by: Axel Lin Tested-by: Guenter Roeck Reviewed-by: Guenter Roeck Signed-off-by: Mark Brown --- drivers/spi/spi.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 9d1405440223..38e1c315bb13 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1653,12 +1653,13 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) message->frame_length += xfer->len; if (!xfer->bits_per_word) xfer->bits_per_word = spi->bits_per_word; - if (!xfer->speed_hz) { + + if (!xfer->speed_hz) xfer->speed_hz = spi->max_speed_hz; - if (master->max_speed_hz && - xfer->speed_hz > master->max_speed_hz) - xfer->speed_hz = master->max_speed_hz; - } + + if (master->max_speed_hz && + xfer->speed_hz > master->max_speed_hz) + xfer->speed_hz = master->max_speed_hz; if (master->bits_per_word_mask) { /* Only 32 bits fit in the mask */ @@ -1687,9 +1688,6 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) if (xfer->speed_hz && master->min_speed_hz && xfer->speed_hz < master->min_speed_hz) return -EINVAL; - if (xfer->speed_hz && master->max_speed_hz && - xfer->speed_hz > master->max_speed_hz) - return -EINVAL; if (xfer->tx_buf && !xfer->tx_nbits) xfer->tx_nbits = SPI_NBITS_SINGLE; -- cgit v1.2.3 From 1e25cd4729bd76662d02b142a6a7f8504bb6aea7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 25 Mar 2014 19:28:22 +0000 Subject: spi: Do not require a completion There is no real reason why we require transfers to have a completion and the only user of the completion now checks to see if one has been provided before using it so stop enforcing this. This makes it more convenient for drivers to chain multiple asynchronous transfers together. Signed-off-by: Mark Brown --- drivers/spi/spi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/spi/spi.c') diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 38e1c315bb13..d94782340b47 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1621,8 +1621,6 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) if (list_empty(&message->transfers)) return -EINVAL; - if (!message->complete) - return -EINVAL; /* Half-duplex links include original MicroWire, and ones with * only one data pin like SPI_3WIRE (switches direction) or where -- cgit v1.2.3