aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2016-11-08 12:48:52 -0500
committerMark Brown <broonie@kernel.org>2016-11-09 08:04:17 -0500
commit9610620078a3900e7fad82de620ce809fd29ba60 (patch)
tree2b1a6a4eab45a3e472eff39a7e23ff5211b2bc37
parent1001354ca34179f3db924eb66672442a173147dc (diff)
spi: atmel: use managed resource for gpio chip select
Use the managed gpio CS pin request so that we avoid having trouble in the cleanup code. In fact, if module was configured with DT, cleanup code released invalid pin. Since resource wasn't freed, module cannot be reinserted. This require to extract the gpio request call from the "setup" function and call it in the appropriate probe function. Reported-by: Alexander Morozov <linux@meltdown.ru> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-atmel.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 8feac599e9ab..d3affa6afe7e 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -24,6 +24,7 @@
24 24
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/gpio.h> 26#include <linux/gpio.h>
27#include <linux/of_gpio.h>
27#include <linux/pinctrl/consumer.h> 28#include <linux/pinctrl/consumer.h>
28#include <linux/pm_runtime.h> 29#include <linux/pm_runtime.h>
29 30
@@ -1204,7 +1205,6 @@ static int atmel_spi_setup(struct spi_device *spi)
1204 u32 csr; 1205 u32 csr;
1205 unsigned int bits = spi->bits_per_word; 1206 unsigned int bits = spi->bits_per_word;
1206 unsigned int npcs_pin; 1207 unsigned int npcs_pin;
1207 int ret;
1208 1208
1209 as = spi_master_get_devdata(spi->master); 1209 as = spi_master_get_devdata(spi->master);
1210 1210
@@ -1247,16 +1247,9 @@ static int atmel_spi_setup(struct spi_device *spi)
1247 if (!asd) 1247 if (!asd)
1248 return -ENOMEM; 1248 return -ENOMEM;
1249 1249
1250 if (as->use_cs_gpios) { 1250 if (as->use_cs_gpios)
1251 ret = gpio_request(npcs_pin, dev_name(&spi->dev));
1252 if (ret) {
1253 kfree(asd);
1254 return ret;
1255 }
1256
1257 gpio_direction_output(npcs_pin, 1251 gpio_direction_output(npcs_pin,
1258 !(spi->mode & SPI_CS_HIGH)); 1252 !(spi->mode & SPI_CS_HIGH));
1259 }
1260 1253
1261 asd->npcs_pin = npcs_pin; 1254 asd->npcs_pin = npcs_pin;
1262 spi->controller_state = asd; 1255 spi->controller_state = asd;
@@ -1471,13 +1464,11 @@ msg_done:
1471static void atmel_spi_cleanup(struct spi_device *spi) 1464static void atmel_spi_cleanup(struct spi_device *spi)
1472{ 1465{
1473 struct atmel_spi_device *asd = spi->controller_state; 1466 struct atmel_spi_device *asd = spi->controller_state;
1474 unsigned gpio = (unsigned long) spi->controller_data;
1475 1467
1476 if (!asd) 1468 if (!asd)
1477 return; 1469 return;
1478 1470
1479 spi->controller_state = NULL; 1471 spi->controller_state = NULL;
1480 gpio_free(gpio);
1481 kfree(asd); 1472 kfree(asd);
1482} 1473}
1483 1474
@@ -1499,6 +1490,39 @@ static void atmel_get_caps(struct atmel_spi *as)
1499} 1490}
1500 1491
1501/*-------------------------------------------------------------------------*/ 1492/*-------------------------------------------------------------------------*/
1493static int atmel_spi_gpio_cs(struct platform_device *pdev)
1494{
1495 struct spi_master *master = platform_get_drvdata(pdev);
1496 struct atmel_spi *as = spi_master_get_devdata(master);
1497 struct device_node *np = master->dev.of_node;
1498 int i;
1499 int ret = 0;
1500 int nb = 0;
1501
1502 if (!as->use_cs_gpios)
1503 return 0;
1504
1505 if (!np)
1506 return 0;
1507
1508 nb = of_gpio_named_count(np, "cs-gpios");
1509 for (i = 0; i < nb; i++) {
1510 int cs_gpio = of_get_named_gpio(pdev->dev.of_node,
1511 "cs-gpios", i);
1512
1513 if (cs_gpio == -EPROBE_DEFER)
1514 return cs_gpio;
1515
1516 if (gpio_is_valid(cs_gpio)) {
1517 ret = devm_gpio_request(&pdev->dev, cs_gpio,
1518 dev_name(&pdev->dev));
1519 if (ret)
1520 return ret;
1521 }
1522 }
1523
1524 return 0;
1525}
1502 1526
1503static int atmel_spi_probe(struct platform_device *pdev) 1527static int atmel_spi_probe(struct platform_device *pdev)
1504{ 1528{
@@ -1577,6 +1601,10 @@ static int atmel_spi_probe(struct platform_device *pdev)
1577 master->num_chipselect = 4; 1601 master->num_chipselect = 4;
1578 } 1602 }
1579 1603
1604 ret = atmel_spi_gpio_cs(pdev);
1605 if (ret)
1606 goto out_unmap_regs;
1607
1580 as->use_dma = false; 1608 as->use_dma = false;
1581 as->use_pdc = false; 1609 as->use_pdc = false;
1582 if (as->caps.has_dma_support) { 1610 if (as->caps.has_dma_support) {