Re: [RFC 04/25] spi: gpio: Implement LSB First bitbang support

From: Andreas FÃrber
Date: Thu Dec 12 2019 - 10:15:04 EST

Hi Geert,

Am 12.12.19 um 09:40 schrieb Geert Uytterhoeven:
> On Thu, Dec 12, 2019 at 4:41 AM Andreas FÃrber <afaerber@xxxxxxx> wrote:
>> Add support for slave DT property spi-lsb-first, i.e., SPI_LSB_FIRST mode.
>> Duplicate the inline helpers bitbang_txrx_be_cpha{0,1} as LE versions.
>> Make happy by changing "unsigned" to "unsigned int".
>> Conditionally call them from all the spi-gpio txrx_word callbacks.
>> Signed-off-by: Andreas FÃrber <afaerber@xxxxxxx>
> Thanks for your patch!

NP. I prefer fixing issues at the source over awkward workarounds. :)

>> --- a/drivers/spi/spi-gpio.c
>> +++ b/drivers/spi/spi-gpio.c
>> @@ -135,25 +135,37 @@ static inline int getmiso(const struct spi_device *spi)
>> static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi,
>> unsigned nsecs, u32 word, u8 bits, unsigned flags)
>> {
>> - return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits);
>> + if (unlikely(spi->mode & SPI_LSB_FIRST))
>> + return bitbang_txrx_le_cpha0(spi, nsecs, 0, flags, word, bits);
>> + else
>> + return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits);
>> }
> Duplicating all functions sounds a bit wasteful to me.

Two functions duplicated, eight function calls duplicated.

> What about reverting the word first, and calling the normal functions?
> if (unlikely(spi->mode & SPI_LSB_FIRST)) {
> if (bits <= 8)
> word = bitrev8(word) >> (bits - 8);
> else if (bits <= 16)
> word = bitrev16(word) >> (bits - 16);
> else
> word = bitrev32(word) >> (bits - 32);
> }
> return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits);

Hm, wasn't aware of those helpers, so I opted not to loop over the bits
for reversing myself, as Thomas Gleixner disliked bit loops in irqchip.
Performance appeared to be a concern here, too.

Eight functions duplicated then. I don't like that - at least we should
pack that into an inline helper or macro, to not copy&paste even more
lines around. Who knows, maybe we'll get 64-bit support at one point?

Do you think it would be acceptable to instead encapsulate this inside
the _be inline helpers? That would lead the name ad absurdum, of course,
but we would then need to do it only twice, not eight times.

However, either way would seem to make the LSB code path slower than MSB
due to the prepended reversal.

Delays are already stubbed out, with open TODOs for further inlining
functions that are being dispatched today.

So from that angle I don't see a better way than either duplicating the
functions or using some macro magic to #include the header twice. If we
wanted to go down that path, we could probably de-duplicate the existing
two functions, too, but I was trying to err on the cautious side, since
I don't have setups to test all four code paths myself (and a ton of
more relevant but less fun patches to flush out ;)).


SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 NÃrnberg, Germany
GF: Felix ImendÃrffer
HRB 36809 (AG NÃrnberg)