>> +static int setup_cs(struct spi_device *spi, struct chip_data *chip,
>> +                 struct pxa2xx_spi_chip *chip_info)
>
> My understanding is that it is legal to call setup without a defined
> pointer to a struct pxa2xx_spi_chip in spi_dev->controller_data, if the
> chip is happy with the defaults (only works for a single chip bus that
> needs no CS, a degenerate case, but still legal).  Thus you should allow
> for that by always checking for existence (chip_info not NULL) before use.
>

OK.

>> +{
>> +     int err = 0;
>> +
>> +     if (chip_info == NULL)
>> +             return 0;
>> +
>> +     /* NOTE: setup() can be called multiple times, possibly with
>> +      * different chip_info, previously requested GPIO shall be
>> +      * released, stumped :(
>> +      */
>
> That is why the GPIO allocation function belongs in the controller
> driver, and not in the master driver.  The master serves many
> controllers, and only the controller drivers know when they are loaded
> and unloaded, and thus when they need to allocate and initialize a GPIO
> pin and when to release it.  Additionally, on a multi-chip bus (which
> may have chips with CS assertion of differing polarity) it may be that
> only the board init code can configure all the CS pins to an idle state
> to get anything on the bus to work at all.  That is why cs_control
> shifts the burden of configuring CS pins outside of the master driver.
> I don't think that this function can work as written; perhaps this can
> be converted to a non-static helper function to be called by either
> board init or controller drivers.
>

This is because chip selects are usually done by GPIO in this case,
what about those SPI masters with a couple of CS(s) controlled
completely by the master registers?

>> +     if (gpio_is_valid(chip->gpio_cs))
>> +             gpio_free(chip->gpio_cs);
>> +
>> +     if (chip_info->cs_control) {
>> +             chip->cs_control = chip_info->cs_control;
>> +             return 0;
>> +     }
>> +
>> +     if (gpio_is_valid(chip_info->gpio_cs)) {
>> +             err = gpio_request(chip_info->gpio_cs, "SPI_CS");
>> +             if (err) {
>> +                     dev_err(&spi->dev, "failed to request CS GPIO%d\n",
>> +                                     chip_info->gpio_cs);
>
> I do not agree that this is an error, though David may argue that it is.
>  Feel free to reduce this to KERN_INFO and eliminate the following
> return.  It is not illegal to omit the chip select on a one-chip bus,
> when the chip does not use CS; there is no need to allocate and waste a
> pin if it is not connected to anything.

Well, if chip->gpio_cs is specified and not able to be requested, this
is obviously a serious error. If someone wants to use NULL CS,
chances are he will not make this "gpio_cs" valid.

>
>> +                     return err;
>> +             }
>> +
>> +             chip->gpio_cs = chip_info->gpio_cs;
>> +             chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH;
>> +
>> +             gpio_direction_output(chip->gpio_cs, !chip->gpio_cs_inverted);
>> +     }
>> +
>> +     return err;
>> +}
>> +
>>  static int setup(struct spi_device *spi)
>>  {
>>       struct pxa2xx_spi_chip *chip_info = NULL;
>> @@ -1141,7 +1203,7 @@ static int setup(struct spi_device *spi)
>>                       return -ENOMEM;
>>               }
>>
>> -             chip->cs_control = null_cs_control;
>
> Based on cs_assert/cs_deassert, above, chip->cs_control needs to be
> initialized to 0 here.  It's initialization should not be removed.

It's already been initialized to 0 by kzalloc(), explicitly.

>
>> +             chip->gpio_cs = -1;
>>               chip->enable_dma = 0;
>>               chip->timeout = 1000;
>>               chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
>> @@ -1156,9 +1218,6 @@ static int setup(struct spi_device *spi)
>>       /* chip_info isn't always needed */
>>       chip->cr1 = 0;
>>       if (chip_info) {
>> -             if (chip_info->cs_control)
>> -                     chip->cs_control = chip_info->cs_control;
>> -
>
> This should not be removed.  This is where legacy drivers establish the
> pointer for a cs_control routine.

This is done by setup_cs(), FYI.

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to