From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?Q?Andreas_F=c3=a4rber?= Subject: Re: [RFC 04/25] spi: gpio: Implement LSB First bitbang support Date: Thu, 12 Dec 2019 16:14:59 +0100 Message-ID: <9b4b6287-c1d9-1b41-88a8-7ac9fe222642@suse.de> References: <20191212033952.5967-1-afaerber@suse.de> <20191212033952.5967-5-afaerber@suse.de> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Cc: linux-realtek-soc@lists.infradead.org, linux-leds@vger.kernel.org, Linux Kernel Mailing List , linux-spi , Mark Brown , Jacek Anaszewski , Pavel Machek , Linux ARM , Dan Murphy To: Geert Uytterhoeven Return-path: In-Reply-To: Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org List-Id: linux-spi.vger.kernel.org Hi Geert, Am 12.12.19 um 09:40 schrieb Geert Uytterhoeven: > On Thu, Dec 12, 2019 at 4:41 AM Andreas Färber 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 checkpatch.pl happy by changing "unsigned" to "unsigned int". >> >> Conditionally call them from all the spi-gpio txrx_word callbacks. >> >> Signed-off-by: Andreas Färber > > 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 ;)). Regards, Andreas -- SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Felix Imendörffer HRB 36809 (AG Nürnberg)