[PATCH] spi: pxa2xx: Only claim CS GPIOs when the slave device is created

Jan Kiszka jan.kiszka at web.de
Sun Jul 9 02:30:08 PDT 2017


On 2017-07-08 23:48, Andy Shevchenko wrote:
> On Sat, Jul 8, 2017 at 11:41 AM, Jan Kiszka <jan.kiszka at web.de> wrote:
>> From: Jan Kiszka <jan.kiszka at siemens.com>
>>
>> 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.
> 
> Can we first switch the driver to use GPIO descriptors instead of
> plain integers?

-ENOPARSE

> 
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
>> ---
>>  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);
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-spi" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170709/101bd230/attachment-0001.sig>


More information about the linux-arm-kernel mailing list