aboutsummaryrefslogtreecommitdiff
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-20 17:26:11 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-20 17:26:11 -0800
commit85adbcd54f0982040c8cc7a086f01554b8f64427 (patch)
treeb5210dcee692b928bd133541dba31f487e246ac8 /drivers/spi/spi.c
parentf790bd9c8e826434ab6c326b225276ed0f73affe (diff)
parent57f22cd29cf1b4ff2aea8505eae2d3ed71ca5de4 (diff)
Merge tag 'spi-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown: "This release is mainly a collection of driver specific updates, including a few nice cleanups to make drivers use more core features. - automatically use the parent device to allocate DMA buffers if there wasn't an explicitly configured device. - fixes for leaks on allocation. - a small piece of the start of SPI slave support, a feature that's been on the cards for over a decade!" * tag 'spi-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (55 commits) spi: spi-ti-qspi: Fix error handling spi: spi-ti-qspi: Fix error handling spi: lantiq-ssc: activate under COMPILE_TEST spi: armada-3700: Remove spi_master_put in a3700_spi_remove() spi: ti-qspi: revise ti_qspi_probe() failure flow spi: spi-ep93xx: simplify GPIO chip selects spi: rspi: Replaces "n" by "len" in qspi_transfer_*() spi: rspi: Fixes bogus received byte in qspi_transfer_in() spi: bcm-qspi: Remove unnecessary platform_set_drvdata() spi: bcm-qspi: Fix bcm_qspi_bspi_read() performance spi: lantiq-ssc: add support for Lantiq SSC SPI controller spi: s3c64xx: fix inconsistency between binding and driver spi: armada-3700: Remove .owner field for driver spi: bcm-qspi: Added mspi read fallback in bcm_qspi_flash_read() spi: fix device-node leaks spi: mediatek: Only do dma for 4-byte aligned buffers spi: When no dma_chan map buffers with spi_master's parent spi: pca2xx-pci: Allow MSI spi: pxa2xx: Prepare for edge-triggered interrupts spi: pxa2xx: Add support for Intel Gemini Lake ...
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 656dd3e3220c..f274df9e0e3e 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -621,8 +621,10 @@ void spi_unregister_device(struct spi_device *spi)
if (!spi)
return;
- if (spi->dev.of_node)
+ if (spi->dev.of_node) {
of_node_clear_flag(spi->dev.of_node, OF_POPULATED);
+ of_node_put(spi->dev.of_node);
+ }
if (ACPI_COMPANION(&spi->dev))
acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev));
device_unregister(&spi->dev);
@@ -672,7 +674,7 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
if (!n)
return -EINVAL;
- bi = kzalloc(n * sizeof(*bi), GFP_KERNEL);
+ bi = kcalloc(n, sizeof(*bi), GFP_KERNEL);
if (!bi)
return -ENOMEM;
@@ -805,12 +807,12 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg)
if (master->dma_tx)
tx_dev = master->dma_tx->device->dev;
else
- tx_dev = &master->dev;
+ tx_dev = master->dev.parent;
if (master->dma_rx)
rx_dev = master->dma_rx->device->dev;
else
- rx_dev = &master->dev;
+ rx_dev = master->dev.parent;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (!master->can_dma(master, msg->spi, xfer))
@@ -852,12 +854,12 @@ static int __spi_unmap_msg(struct spi_master *master, struct spi_message *msg)
if (master->dma_tx)
tx_dev = master->dma_tx->device->dev;
else
- tx_dev = &master->dev;
+ tx_dev = master->dev.parent;
if (master->dma_rx)
rx_dev = master->dma_rx->device->dev;
else
- rx_dev = &master->dev;
+ rx_dev = master->dev.parent;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (!master->can_dma(master, msg->spi, xfer))
@@ -1502,37 +1504,18 @@ err_init_queue:
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_OF)
-static struct spi_device *
-of_register_spi_device(struct spi_master *master, struct device_node *nc)
+static int of_spi_parse_dt(struct spi_master *master, struct spi_device *spi,
+ struct device_node *nc)
{
- struct spi_device *spi;
- int rc;
u32 value;
-
- /* Alloc an spi_device */
- spi = spi_alloc_device(master);
- if (!spi) {
- dev_err(&master->dev, "spi_device alloc error for %s\n",
- nc->full_name);
- rc = -ENOMEM;
- goto err_out;
- }
-
- /* Select device driver */
- rc = of_modalias_node(nc, spi->modalias,
- sizeof(spi->modalias));
- if (rc < 0) {
- dev_err(&master->dev, "cannot find modalias for %s\n",
- nc->full_name);
- goto err_out;
- }
+ int rc;
/* Device address */
rc = of_property_read_u32(nc, "reg", &value);
if (rc) {
dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n",
nc->full_name, rc);
- goto err_out;
+ return rc;
}
spi->chip_select = value;
@@ -1590,10 +1573,41 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc)
if (rc) {
dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n",
nc->full_name, rc);
- goto err_out;
+ return rc;
}
spi->max_speed_hz = value;
+ return 0;
+}
+
+static struct spi_device *
+of_register_spi_device(struct spi_master *master, struct device_node *nc)
+{
+ struct spi_device *spi;
+ int rc;
+
+ /* Alloc an spi_device */
+ spi = spi_alloc_device(master);
+ if (!spi) {
+ dev_err(&master->dev, "spi_device alloc error for %s\n",
+ nc->full_name);
+ rc = -ENOMEM;
+ goto err_out;
+ }
+
+ /* Select device driver */
+ rc = of_modalias_node(nc, spi->modalias,
+ sizeof(spi->modalias));
+ if (rc < 0) {
+ dev_err(&master->dev, "cannot find modalias for %s\n",
+ nc->full_name);
+ goto err_out;
+ }
+
+ rc = of_spi_parse_dt(master, spi, nc);
+ if (rc)
+ goto err_out;
+
/* Store a pointer to the node in the device structure */
of_node_get(nc);
spi->dev.of_node = nc;
@@ -1603,11 +1617,13 @@ of_register_spi_device(struct spi_master *master, struct device_node *nc)
if (rc) {
dev_err(&master->dev, "spi_device register error %s\n",
nc->full_name);
- goto err_out;
+ goto err_of_node_put;
}
return spi;
+err_of_node_put:
+ of_node_put(nc);
err_out:
spi_dev_put(spi);
return ERR_PTR(rc);