Commit 5d0eb26c authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'spi/topic/core' into spi-next

parents ff13a9a6 1e25cd47
...@@ -255,13 +255,12 @@ EXPORT_SYMBOL_GPL(spi_bus_type); ...@@ -255,13 +255,12 @@ EXPORT_SYMBOL_GPL(spi_bus_type);
static int spi_drv_probe(struct device *dev) static int spi_drv_probe(struct device *dev)
{ {
const struct spi_driver *sdrv = to_spi_driver(dev->driver); const struct spi_driver *sdrv = to_spi_driver(dev->driver);
struct spi_device *spi = to_spi_device(dev);
int ret; int ret;
acpi_dev_pm_attach(&spi->dev, true); acpi_dev_pm_attach(dev, true);
ret = sdrv->probe(spi); ret = sdrv->probe(to_spi_device(dev));
if (ret) if (ret)
acpi_dev_pm_detach(&spi->dev, true); acpi_dev_pm_detach(dev, true);
return ret; return ret;
} }
...@@ -269,11 +268,10 @@ static int spi_drv_probe(struct device *dev) ...@@ -269,11 +268,10 @@ static int spi_drv_probe(struct device *dev)
static int spi_drv_remove(struct device *dev) static int spi_drv_remove(struct device *dev)
{ {
const struct spi_driver *sdrv = to_spi_driver(dev->driver); const struct spi_driver *sdrv = to_spi_driver(dev->driver);
struct spi_device *spi = to_spi_device(dev);
int ret; int ret;
ret = sdrv->remove(spi); ret = sdrv->remove(to_spi_device(dev));
acpi_dev_pm_detach(&spi->dev, true); acpi_dev_pm_detach(dev, true);
return ret; return ret;
} }
...@@ -892,7 +890,7 @@ static int spi_stop_queue(struct spi_master *master) ...@@ -892,7 +890,7 @@ static int spi_stop_queue(struct spi_master *master)
*/ */
while ((!list_empty(&master->queue) || master->busy) && limit--) { while ((!list_empty(&master->queue) || master->busy) && limit--) {
spin_unlock_irqrestore(&master->queue_lock, flags); spin_unlock_irqrestore(&master->queue_lock, flags);
msleep(10); usleep_range(10000, 11000);
spin_lock_irqsave(&master->queue_lock, flags); spin_lock_irqsave(&master->queue_lock, flags);
} }
...@@ -1617,11 +1615,10 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) ...@@ -1617,11 +1615,10 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
{ {
struct spi_master *master = spi->master; struct spi_master *master = spi->master;
struct spi_transfer *xfer; struct spi_transfer *xfer;
int w_size;
if (list_empty(&message->transfers)) if (list_empty(&message->transfers))
return -EINVAL; return -EINVAL;
if (!message->complete)
return -EINVAL;
/* Half-duplex links include original MicroWire, and ones with /* Half-duplex links include original MicroWire, and ones with
* only one data pin like SPI_3WIRE (switches direction) or where * only one data pin like SPI_3WIRE (switches direction) or where
...@@ -1652,12 +1649,13 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) ...@@ -1652,12 +1649,13 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
message->frame_length += xfer->len; message->frame_length += xfer->len;
if (!xfer->bits_per_word) if (!xfer->bits_per_word)
xfer->bits_per_word = spi->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; xfer->speed_hz = spi->max_speed_hz;
if (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)
} xfer->speed_hz = master->max_speed_hz;
if (master->bits_per_word_mask) { if (master->bits_per_word_mask) {
/* Only 32 bits fit in the mask */ /* Only 32 bits fit in the mask */
...@@ -1668,12 +1666,24 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) ...@@ -1668,12 +1666,24 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
return -EINVAL; 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;
/* No partial transfers accepted */
if (xfer->len % w_size)
return -EINVAL;
if (xfer->speed_hz && master->min_speed_hz && if (xfer->speed_hz && master->min_speed_hz &&
xfer->speed_hz < master->min_speed_hz) xfer->speed_hz < master->min_speed_hz)
return -EINVAL; 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) if (xfer->tx_buf && !xfer->tx_nbits)
xfer->tx_nbits = SPI_NBITS_SINGLE; xfer->tx_nbits = SPI_NBITS_SINGLE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment