diff mbox

[PATCH/RFC] spi: core: Fix logic mismatch in spi_master.set_cs()

Message ID 1389699411-29135-1-git-send-email-geert@linux-m68k.org (mailing list archive)
State Changes Requested
Headers show

Commit Message

Geert Uytterhoeven Jan. 14, 2014, 11:36 a.m. UTC
From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>

The documentation for spi_master.set_cs() says:

    assert or deassert chip select, true to assert

i.e. its "enable" parameter uses assertion-level logic.

This does not match the implementation of spi_set_cs(), which calls
spi_master.set_cs() with the wanted logical value of the chip select line,
i.e. "false" to assert an active low chip select, and "true" to assert an
active high chip select.

Correct the implementation to use assertion-level logic.

For GPIO-based chip selects, active high chip selects are still handled in
spi_set_cs(), as this is a direct GPIO level.
For SPI controller-based chip selects, active high chip selects must be
handled by the SPI master driver, if supported (some SPI controllers have
configurable chip select polarity).

Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
---
 drivers/spi/spi.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

Comments

Mark Brown Jan. 14, 2014, 12:52 p.m. UTC | #1
On Tue, Jan 14, 2014 at 12:36:51PM +0100, Geert Uytterhoeven wrote:

>  {
> -	if (spi->mode & SPI_CS_HIGH)
> -		enable = !enable;
> -
> -	if (spi->cs_gpio >= 0)
> +	if (spi->cs_gpio >= 0) {
> +		if (spi->mode & SPI_CS_HIGH)
> +			enable = !enable;
>  		gpio_set_value(spi->cs_gpio, !enable);
> -	else if (spi->master->set_cs)
> -		spi->master->set_cs(spi, !enable);
> +	} else if (spi->master->set_cs)
> +		spi->master->set_cs(spi, enable);
>  }

Coding style, braces on all branches of an if statement.

This also pushes the handling of CS_HIGH back out into the driver which
doesn't seem like it's helping anything.  Flipping the sense of enable
when calling set_cs() is probably OK though.
Geert Uytterhoeven Jan. 14, 2014, 1:23 p.m. UTC | #2
Hi Mark,

On Tue, Jan 14, 2014 at 1:52 PM, Mark Brown <broonie@kernel.org> wrote:
>On Tue, Jan 14, 2014 at 12:36:51PM +0100, Geert Uytterhoeven wrote:
>
>> The documentation for spi_master.set_cs() says:
>>
>>     assert or deassert chip select, true to assert
>>
>> i.e. its "enable" parameter uses assertion-level logic.

>> For SPI controller-based chip selects, active high chip selects must be
>> handled by the SPI master driver, if supported (some SPI controllers have
>> configurable chip select polarity).
>
> This also pushes the handling of CS_HIGH back out into the driver which
> doesn't seem like it's helping anything.  Flipping the sense of enable

It depends: on hardware with separate register bits for chip select polarity
and chip select assertion it avoids having to invert the enable value a second
time.

> when calling set_cs() is probably OK though.

Just flipping the sense of enable still needs a documentation update.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mark Brown Jan. 14, 2014, 1:45 p.m. UTC | #3
On Tue, Jan 14, 2014 at 02:23:37PM +0100, Geert Uytterhoeven wrote:
> On Tue, Jan 14, 2014 at 1:52 PM, Mark Brown <broonie@kernel.org> wrote:
> >On Tue, Jan 14, 2014 at 12:36:51PM +0100, Geert Uytterhoeven wrote:

> > This also pushes the handling of CS_HIGH back out into the driver which
> > doesn't seem like it's helping anything.  Flipping the sense of enable

> It depends: on hardware with separate register bits for chip select polarity
> and chip select assertion it avoids having to invert the enable value a second
> time.

If we're manually setting /CS it really makes no difference what the
chip thinks the polarity is - something that is controlling /CS
autonomously can't implement this operation and something that can just
set it at any time doesn't need to worry if the chip thinks it's
asserted or not.

> > when calling set_cs() is probably OK though.

> Just flipping the sense of enable still needs a documentation update.

Huh?  Why were you updating the code then...
Geert Uytterhoeven Jan. 14, 2014, 2:44 p.m. UTC | #4
On Tue, Jan 14, 2014 at 2:45 PM, Mark Brown <broonie@kernel.org> wrote:
> On Tue, Jan 14, 2014 at 02:23:37PM +0100, Geert Uytterhoeven wrote:
>> On Tue, Jan 14, 2014 at 1:52 PM, Mark Brown <broonie@kernel.org> wrote:
>> >On Tue, Jan 14, 2014 at 12:36:51PM +0100, Geert Uytterhoeven wrote:
>
>> > This also pushes the handling of CS_HIGH back out into the driver which
>> > doesn't seem like it's helping anything.  Flipping the sense of enable
>
>> It depends: on hardware with separate register bits for chip select polarity
>> and chip select assertion it avoids having to invert the enable value a second
>> time.
>
> If we're manually setting /CS it really makes no difference what the
> chip thinks the polarity is - something that is controlling /CS
> autonomously can't implement this operation and something that can just
> set it at any time doesn't need to worry if the chip thinks it's
> asserted or not.

Doh, so I'm the only one where it does matter, as RSPI has separate
Slave Select Signal Polarity (high/low) and Slave Select Output Setting
(enable/disable)...

>> > when calling set_cs() is probably OK though.
>
>> Just flipping the sense of enable still needs a documentation update.
>
> Huh?  Why were you updating the code then...

"true to assert" in the documentation means that enable is true when
enabling the chip select.
Currently the value of enable depends on SPI_CS_HIGH. Just "flipping
the sense of enable" doesn't change that dependency.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mark Brown Jan. 14, 2014, 2:50 p.m. UTC | #5
On Tue, Jan 14, 2014 at 03:44:43PM +0100, Geert Uytterhoeven wrote:
> On Tue, Jan 14, 2014 at 2:45 PM, Mark Brown <broonie@kernel.org> wrote:

> > If we're manually setting /CS it really makes no difference what the
> > chip thinks the polarity is - something that is controlling /CS
> > autonomously can't implement this operation and something that can just
> > set it at any time doesn't need to worry if the chip thinks it's
> > asserted or not.

> Doh, so I'm the only one where it does matter, as RSPI has separate
> Slave Select Signal Polarity (high/low) and Slave Select Output Setting
> (enable/disable)...

I'm sure there's other hardware out there which has such control, it's
just that there's no value in actually using the polarity select if
we have manual control over the enable.  All you're doing is adding
complexity in drivers.

> >> > when calling set_cs() is probably OK though.

> >> Just flipping the sense of enable still needs a documentation update.

> > Huh?  Why were you updating the code then...

> "true to assert" in the documentation means that enable is true when
> enabling the chip select.
> Currently the value of enable depends on SPI_CS_HIGH. Just "flipping
> the sense of enable" doesn't change that dependency.

Oh, so the code update was purely about factoring that out of the core?
Geert Uytterhoeven Jan. 14, 2014, 3:18 p.m. UTC | #6
Hi Mark,

On Tue, Jan 14, 2014 at 3:50 PM, Mark Brown <broonie@kernel.org> wrote:
> On Tue, Jan 14, 2014 at 03:44:43PM +0100, Geert Uytterhoeven wrote:
>> On Tue, Jan 14, 2014 at 2:45 PM, Mark Brown <broonie@kernel.org> wrote:
>> >> > when calling set_cs() is probably OK though.
>
>> >> Just flipping the sense of enable still needs a documentation update.
>
>> > Huh?  Why were you updating the code then...
>
>> "true to assert" in the documentation means that enable is true when
>> enabling the chip select.
>> Currently the value of enable depends on SPI_CS_HIGH. Just "flipping
>> the sense of enable" doesn't change that dependency.
>
> Oh, so the code update was purely about factoring that out of the core?

No, it was about fixing the mismatch between code and documentation.

There are two ways to correct the mismatch:
  1. Make the code match the documentation.
      That's what I did, as it avoids a double conditional inversion on RSPI.
  2. Make the documentation match the code.
      It seems this is what you prefer?
      So "assert or deassert chip select, true to assert" has to be replaced by
      "Set the logical level of the chip select line"? Or do you have a better
      suggestion?

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mark Brown Jan. 17, 2014, 6:03 p.m. UTC | #7
On Tue, Jan 14, 2014 at 04:18:06PM +0100, Geert Uytterhoeven wrote:

>   2. Make the documentation match the code.
>       It seems this is what you prefer?

Yes.
Geert Uytterhoeven Jan. 17, 2014, 7:04 p.m. UTC | #8
On Fri, Jan 17, 2014 at 7:03 PM, Mark Brown <broonie@kernel.org> wrote:
>>   2. Make the documentation match the code.
>>       It seems this is what you prefer?
>
> Yes.

Thanks, will do.
diff mbox

Patch

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a86569e1f178..eb20169e84e8 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -561,13 +561,12 @@  int spi_register_board_info(struct spi_board_info const *info, unsigned n)
 
 static void spi_set_cs(struct spi_device *spi, bool enable)
 {
-	if (spi->mode & SPI_CS_HIGH)
-		enable = !enable;
-
-	if (spi->cs_gpio >= 0)
+	if (spi->cs_gpio >= 0) {
+		if (spi->mode & SPI_CS_HIGH)
+			enable = !enable;
 		gpio_set_value(spi->cs_gpio, !enable);
-	else if (spi->master->set_cs)
-		spi->master->set_cs(spi, !enable);
+	} else if (spi->master->set_cs)
+		spi->master->set_cs(spi, enable);
 }
 
 /*