diff mbox series

spi: set right CS polarity depend on gpiolib

Message ID 20210507145117.43221-1-zhangliguang@linux.alibaba.com (mailing list archive)
State New, archived
Headers show
Series spi: set right CS polarity depend on gpiolib | expand

Commit Message

luanshi May 7, 2021, 2:51 p.m. UTC
After a kernel upgrade from 4.19 to 5.10, we found that tpm flow control
always causes TIMEOUT which caused by wrong CS polarity setting depend
on gpiolib.

Signed-off-by: Liguang Zhang <zhangliguang@linux.alibaba.com>
---
 drivers/spi/spi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Mark Brown May 7, 2021, 3:30 p.m. UTC | #1
On Fri, May 07, 2021 at 10:51:17PM +0800, Liguang Zhang wrote:
> After a kernel upgrade from 4.19 to 5.10, we found that tpm flow control
> always causes TIMEOUT which caused by wrong CS polarity setting depend
> on gpiolib.

>  			if (spi->cs_gpiod)
>  				/* polarity handled by gpiolib */
> -				gpiod_set_value_cansleep(spi->cs_gpiod, activate);
> +				gpiod_set_value_cansleep(spi->cs_gpiod, !enable);

Whatever is going on here it doesn't seem likely that this is a problem
in the SPI core given the widespread use of gpiod based chip selects -
can you provide more explanation of what you're seeing here, how is the
chip select configured, what is the hardware expectation and what
actually ends up happening?
luanshi May 8, 2021, 1:01 a.m. UTC | #2
Hi,
在 2021/5/7 23:30, Mark Brown 写道:
> On Fri, May 07, 2021 at 10:51:17PM +0800, Liguang Zhang wrote:
>> After a kernel upgrade from 4.19 to 5.10, we found that tpm flow control
>> always causes TIMEOUT which caused by wrong CS polarity setting depend
>> on gpiolib.
>>   			if (spi->cs_gpiod)
>>   				/* polarity handled by gpiolib */
>> -				gpiod_set_value_cansleep(spi->cs_gpiod, activate);
>> +				gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
> Whatever is going on here it doesn't seem likely that this is a problem
> in the SPI core given the widespread use of gpiod based chip selects -
> can you provide more explanation of what you're seeing here, how is the
> chip select configured, what is the hardware expectation and what
> actually ends up happening?

The arm platform is  kunpeng-920, detail dsdt information here:

         Device (SPI0)
         {
             Name (_HID, "HISI0173")  // _HID: Hardware ID
             Name (_ADR, Zero)  // _ADR: Address
             Name (_UID, Zero)  // _UID: Unique ID
             Name (RBUF, ResourceTemplate ()
             {
                 GpioIo (Exclusive, PullUp, 0x0000, 0x0000, 
IoRestrictionNone,
                     "\\_SB.GPO1", 0x00, ResourceConsumer, ,
                     )
                     {   // Pin list
                         0x0006
                     }
                 QWordMemory (ResourceConsumer, PosDecode, MinFixed, 
MaxFixed, NonCacheable, ReadWrite,
                     0x0000000000000000, // Granularity
                     0x00000002011A0000, // Range Minimum
                     0x00000002011AFFFF, // Range Maximum
                     0x0000000000000000, // Translation Offset
                     0x0000000000010000, // Length
                     ,, , AddressRangeMemory, TypeStatic)
                 Interrupt (ResourceConsumer, Level, ActiveHigh, 
Exclusive, ,, )
                 {
                     0x000001EB,
                 }
             })
             Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource 
Settings
             {
                 Return (RBUF) /* \_SB_.SPI0.RBUF */
             }

             Name (_DSD, Package (0x02)  // _DSD: Device-Specific Data
             {
                 ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* 
Device Properties for _DSD */,
                 Package (0x03)
                 {
                     Package (0x02)
                     {
                         "reg-io-width",
                         0x04
                     },

                     Package (0x02)
                     {
                         "num-cs",
                         One
                     },

                     Package (0x02)
                     {
                         "cs-gpios",
                         Package (0x04)
                         {
                             SPI0,
                             Zero,
                             Zero,
                             Zero
                         }
                     }
                 }
             })
         }

         Scope (SPI0)
         {
             Device (TPM)
             {
                 Name (_ADR, Zero)  // _ADR: Address
                 Name (_CID, Package (0x01)  // _CID: Compatible ID
                 {
                     "SMO0768"
                 })
                 Name (_UID, Zero)  // _UID: Unique ID
                 Name (_DSD, Package (0x02)  // _DSD: Device-Specific Data
                 {
                     ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* 
Device Properties for _DSD */,
                     Package (0x00){}
                 })
                 Method (_CRS, 0, NotSerialized)  // _CRS: Current 
Resource Settings
                 {
                     Name (RBUF, ResourceTemplate ()
                     {
                         SpiSerialBusV2 (0x0000, PolarityLow, 
FourWireMode, 0x08,
                             ControllerInitiated, 0x000F4240, 
ClockPolarityLow,
                             ClockPhaseFirst, "\\_SB.SPI0",
                             0x00, ResourceConsumer, , Exclusive,
                             )
                     })
                     Return (RBUF) /* \_SB_.SPI0.TPM_._CRS.RBUF */
                 }

                 Method (_STA, 0, NotSerialized)  // _STA: Status
                 {
                     If ((TPEN == One))
                     {
                         Return (0x0F)
                     }
                     Else
                     {
                         Return (Zero)
                     }
                 }
             }
         }
     }


The problem I meet is:

    tpm_tis_spi_init

        tpm_tis_core_init

             wait_startup     // Timeout is occured, appear every time.

If the modification below done, probe succeed.

gpiod_set_value_cansleep(spi->cs_gpiod, !enable)
diff mbox series

Patch

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index ba425b9c7700..9ee2b92b4506 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -816,7 +816,7 @@  static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
 		if (!(spi->mode & SPI_NO_CS)) {
 			if (spi->cs_gpiod)
 				/* polarity handled by gpiolib */
-				gpiod_set_value_cansleep(spi->cs_gpiod, activate);
+				gpiod_set_value_cansleep(spi->cs_gpiod, !enable);
 			else
 				/*
 				 * invert the enable line, as active low is