Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752786AbdGHImD (ORCPT ); Sat, 8 Jul 2017 04:42:03 -0400 Received: from mout.web.de ([212.227.15.4]:65257 "EHLO mout.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752689AbdGHImA (ORCPT ); Sat, 8 Jul 2017 04:42:00 -0400 To: Daniel Mack , Haojian Zhuang , Robert Jarzmik , Mark Brown Cc: linux-spi@vger.kernel.org, Linux Kernel Mailing List , linux-arm-kernel From: Jan Kiszka Subject: [PATCH] spi: pxa2xx: Only claim CS GPIOs when the slave device is created Message-ID: <90b3e14d-0077-9a25-9d90-ab340577af57@web.de> Date: Sat, 8 Jul 2017 10:41:18 +0200 User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K0:KuIvbXI0h5ewTMhoqRUDK2EF5slVwI3pMSdPO5W3jFBnKhXXC7e 4H3ENfXj4DWLWBVFBdOUluAENLSMjvn3hXBudYXDbh1Ez6yRopSqRjyNVPK3ElaZ2IJD+Cy XWuPBSfnBMR3YclcMcmqAZbuTs9Nwn4R9DK4BpuIOe/WbpY4sUyFSUxhG5ot4iTkYQU7y6V 2340AzN0yk45iJtIRZisQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:XcNB3WZobtk=:9ulR+/7JSyZLL/5BjHT/IJ svBW5KQEnPkeuw+6Dujax4KnU5wa1UygbuaZzvaIDmZyb42bdj7hDl4SGhCLNXgsgMjOUKM6u KLSZPke1DL9yINRKPe00pDrlVLxVvm9OaDH3qJ2Ic/S5WivWpEf6q3vioGiZzmWDl0yMw9Yjn hOKqx5WtAW21pewEj6NEXvAriYgxTOC+kkakXALPE3Y3fbdIHKOPc4NYMps4b3GDFFwgEC4VJ Q3BJScc2bUs1IwLesFED9UOlEYrnHTalCyyCEUCySuItpVktd+NygU9HD9HKjO3UoXzWdxC7H 3abMOPdQkEm3KrN98SYqf1B35bQKEM+3Zytx5AlKTaLRqgfGyHtd1i8pTbbROXcn59zSc7xiM bG7TW7aE9kbFyzNMi0coVvyHo+pN/2M2GItOWIdYgfvMMb8N7iDkvLFS3aH3quxwRkjUglWcj n/kHHkL0gDhW7tqAR9Ek2/J4bt7kw+8O0inFzyaIlCdOjodxJ4BzIa8Yts2NHDhjn0P2qSLC7 ujrne9hy6sieOxoYWxsQdDu1eJJDUVHW9wTGuAn3QUyhVPLRUVlLErIRGDM6/ePrypkWD/mws 3PTSCrl2pFyXQM4CDqW0rBHiA9BG9iea/jPXQkbHPW3oDCDRUgxxQor0VA4Qx1A/hxrQ7YtYt ptN11MWd45yQPLFCZfwLUq0qlVA0gVZGcJmmB57ik7eaMRnEJKxacD4dl4xFfwybDvYcXQJOU qFStXyOwUrP1HUfRnKeSwXcWGFtlhAakTPZ+N2jK/AgtMu9soEW4p2aI77QhZiHMQ35Xg1ytT krXK28K Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3248 Lines: 111 From: Jan Kiszka Avoid hogging chip select GPIOs just because they are listed for the master. They might be mulitplexed and, if no slave device is attached, used for different purposes. Moreover, this strategy avoids having to allocate a cs_gpiods structure. Tested on the IOT2000 where the second SPI bus is connected to an Arduino-compatible connector and multiplexed between SPI, GPIO and PWM usage. Signed-off-by: Jan Kiszka --- drivers/spi/spi-pxa2xx.c | 59 +++++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 38d053682892..be991266a6ce 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1213,21 +1213,33 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip, struct pxa2xx_spi_chip *chip_info) { struct driver_data *drv_data = spi_master_get_devdata(spi->master); + struct device *pdev = &drv_data->pdev->dev; + struct gpio_desc *gpiod; int err = 0; + int count; if (chip == NULL) return 0; - if (drv_data->cs_gpiods) { - struct gpio_desc *gpiod; + count = gpiod_count(pdev, "cs"); + if (count > 0) { + if (spi->chip_select >= count) + return -EINVAL; + + gpiod = gpiod_get_index(pdev, "cs", spi->chip_select, + GPIOD_OUT_HIGH); + if (IS_ERR(gpiod)) { + /* Means use native chip select */ + if (PTR_ERR(gpiod) == -ENOENT) + return 0; - gpiod = drv_data->cs_gpiods[spi->chip_select]; - if (gpiod) { - chip->gpio_cs = desc_to_gpio(gpiod); - chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH; - gpiod_set_value(gpiod, chip->gpio_cs_inverted); + return PTR_ERR(gpiod); } + chip->gpio_cs = desc_to_gpio(gpiod); + chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH; + gpiod_set_value(gpiod, chip->gpio_cs_inverted); + return 0; } @@ -1415,8 +1427,7 @@ static void cleanup(struct spi_device *spi) if (!chip) return; - if (drv_data->ssp_type != CE4100_SSP && !drv_data->cs_gpiods && - gpio_is_valid(chip->gpio_cs)) + if (drv_data->ssp_type != CE4100_SSP && gpio_is_valid(chip->gpio_cs)) gpio_free(chip->gpio_cs); kfree(chip); @@ -1752,38 +1763,10 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) master->num_chipselect = platform_info->num_chipselect; count = gpiod_count(&pdev->dev, "cs"); - if (count > 0) { - int i; - + if (count > 0) master->num_chipselect = max_t(int, count, master->num_chipselect); - drv_data->cs_gpiods = devm_kcalloc(&pdev->dev, - master->num_chipselect, sizeof(struct gpio_desc *), - GFP_KERNEL); - if (!drv_data->cs_gpiods) { - status = -ENOMEM; - goto out_error_clock_enabled; - } - - for (i = 0; i < master->num_chipselect; i++) { - struct gpio_desc *gpiod; - - gpiod = devm_gpiod_get_index(dev, "cs", i, - GPIOD_OUT_HIGH); - if (IS_ERR(gpiod)) { - /* Means use native chip select */ - if (PTR_ERR(gpiod) == -ENOENT) - continue; - - status = (int)PTR_ERR(gpiod); - goto out_error_clock_enabled; - } else { - drv_data->cs_gpiods[i] = gpiod; - } - } - } - tasklet_init(&drv_data->pump_transfers, pump_transfers, (unsigned long)drv_data);