95 Commits

Author SHA1 Message Date
Yann Sionneau
2409205acd i2c: designware: fix __i2c_dw_disable() in case master is holding SCL low
The DesignWare IP can be synthesized with the IC_EMPTYFIFO_HOLD_MASTER_EN
parameter.
In this case, when the TX FIFO gets empty and the last command didn't have
the STOP bit (IC_DATA_CMD[9]), the controller will hold SCL low until
a new command is pushed into the TX FIFO or the transfer is aborted.

When the controller is holding SCL low, it cannot be disabled.
The transfer must first be aborted.
Also, the bus recovery won't work because SCL is held low by the master.

Check if the master is holding SCL low in __i2c_dw_disable() before trying
to disable the controller. If SCL is held low, an abort is initiated.
When the abort is done, then proceed with disabling the controller.

This whole situation can happen for instance during SMBus read data block
if the slave just responds with "byte count == 0".
This puts the driver in an unrecoverable state, because the controller is
holding SCL low and the current __i2c_dw_disable() procedure is not
working. In this situation only a SoC reset can fix the i2c bus.

Co-developed-by: Jonathan Borne <jborne@kalray.eu>
Signed-off-by: Jonathan Borne <jborne@kalray.eu>
Signed-off-by: Yann Sionneau <ysionneau@kalray.eu>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2023-09-19 21:57:11 +02:00
Linus Torvalds
5def00ca25 Biggest news is not a patch this time
* I2C has now a co-maintainer taking care of the host drivers. Welcome
   Andi Shyti and have fun!
 * platform remove callback converted to return void in drivers
 * simplify drivers by using devm_clk_get_enabled()
 * introduce i2c_get_match_data() to avoid more boilerplate code
   (especially since the core stopped delivering an i2c_device_id)
 * and the usual bunch of driver updates
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEOZGx6rniZ1Gk92RdFA3kzBSgKbYFAmShZJ0ACgkQFA3kzBSg
 Kbbcaw/9ERpYjDr3ILftlDDAz3hKnmMiFNdwgTxwxnFb8xzRi4vBr6mOIUQUiuNe
 ks+Zq8JVu9+LklKzDbYSV8HM7wId2MYK7m/zoNDB3C0nIv1iGxTW4HM4BDF/TRkd
 /NBWT29dmG2DYb0cOp66thZXSi01qi0iqD+hraa6Z8HV+mKjHTYCtgaqvxF6XKEU
 GJWL8c9brbBc6nFkszQz/q8GGbh3sXi2shLE/KeF/B5o1z0qTNP9szUW1hwMCMIE
 aB/EAzGtMsJ89fi1qphACFAigTUMzRPFrvUHAQUMOEXZlpWUE7T9Hx2raJU0iOme
 tCjfpqm0yVKueBcOEKZfn+O2BfhGpMBdz3f01kvELtUolGzOiqYUF4MiWqiuK7eJ
 IppUZiArgP0BMo94qa2MnGlD1jWLTWJPqYeuqKGLjBAhJMrcMEXqKpuwDS1CRr6h
 KKfJPNZFB7BFNIq5Qs1GPpnlRRnzmjzIusAI55X8xIfAj3DHuluRP5QGY2eOSbnK
 P/2bQnUh83ApJURotihH1hToIXIhxczj2UYHs+m4y6AfWtEh8I/ePp+DrvVoyKQl
 UCRRHPgEpW9vHtW28vPMARJ/dPjqfaa6Kpp1i9NBoAiZsm4Sl7sQaRjTXn/1FuCO
 cK3cePwJsfFYn/VPKccM5khmF/v70U09Fb2um3yY5X7vJDUoQzc=
 =60K9
 -----END PGP SIGNATURE-----

Merge tag 'i2c-for-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:

 - I2C has now a co-maintainer taking care of the host drivers. Welcome
   Andi Shyti and have fun!

 - platform remove callback converted to return void in drivers

 - simplify drivers by using devm_clk_get_enabled()

 - introduce i2c_get_match_data() to avoid more boilerplate code
   (especially since the core stopped delivering an i2c_device_id)

 - and the usual bunch of driver updates

* tag 'i2c-for-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (38 commits)
  i2c: uniphier: Use devm_clk_get_enabled()
  i2c: uniphier-f: Use devm_clk_get_enabled()
  i2c: owl: Use devm_clk_get_enabled()
  i2c: lpc2k: Use devm_clk_get_enabled()
  i2c: hix5hd2: Use devm_clk_get_enabled()
  i2c: sun6i-p2wi: Use devm_clk_get_enabled()
  i2c: pasemi-platform: Use devm_clk_get_enabled()
  i2c: mt7621: Use devm_clk_get_enabled()
  i2c: xiic: Use devm_clk_get_enabled()
  i2c: davinci: Use platform table macro over module_alias
  i2c: ocores: use devm_ managed clks
  i2c: nomadik: Use dev_err_probe() whenever possible
  i2c: nomadik: Use devm_clk_get_enabled()
  i2c: nomadik: Remove unnecessary goto label
  usb: typec: ucsi: Mark dGPUs as DEVICE scope
  i2c: wmt: Use devm_platform_get_and_ioremap_resource()
  i2c: versatile: Use devm_platform_get_and_ioremap_resource()
  i2c: hix5hd2: Add I2C_M_STOP flag support for i2c-hix5hd2 driver.
  i2c: mpc: Use of_property_read_reg() to parse "reg"
  i2c: imx-lpi2c: Don't open-code DIV_ROUND_UP
  ...
2023-07-02 10:22:38 -07:00
David Zheng
1acfc6e753 i2c: designware: fix idx_write_cnt in read loop
With IC_INTR_RX_FULL slave interrupt handler reads data in a loop until
RX FIFO is empty. When testing with the slave-eeprom, each transaction
has 2 bytes for address/index and 1 byte for value, the address byte
can be written as data byte due to dropping STOP condition.

In the test below, the master continuously writes to the slave, first 2
bytes are index, 3rd byte is value and follow by a STOP condition.

 i2c_write: i2c-3 #0 a=04b f=0000 l=3 [00-D1-D1]
 i2c_write: i2c-3 #0 a=04b f=0000 l=3 [00-D2-D2]
 i2c_write: i2c-3 #0 a=04b f=0000 l=3 [00-D3-D3]

Upon receiving STOP condition slave eeprom would reset `idx_write_cnt` so
next 2 bytes can be treated as buffer index for upcoming transaction.
Supposedly the slave eeprom buffer would be written as

 EEPROM[0x00D1] = 0xD1
 EEPROM[0x00D2] = 0xD2
 EEPROM[0x00D3] = 0xD3

When CPU load is high the slave irq handler may not read fast enough,
the interrupt status can be seen as 0x204 with both DW_IC_INTR_STOP_DET
(0x200) and DW_IC_INTR_RX_FULL (0x4) bits. The slave device may see
the transactions below.

 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x1594 : INTR_STAT=0x4
 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x1594 : INTR_STAT=0x4
 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x1594 : INTR_STAT=0x4
 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x1794 : INTR_STAT=0x204
 0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x1790 : INTR_STAT=0x200
 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x1594 : INTR_STAT=0x4
 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x1594 : INTR_STAT=0x4
 0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x1594 : INTR_STAT=0x4

After `D1` is received, read loop continues to read `00` which is the
first bype of next index. Since STOP condition is ignored by the loop,
eeprom buffer index increased to `D2` and `00` is written as value.

So the slave eeprom buffer becomes

 EEPROM[0x00D1] = 0xD1
 EEPROM[0x00D2] = 0x00
 EEPROM[0x00D3] = 0xD3

The fix is to use `FIRST_DATA_BYTE` (bit 11) in `IC_DATA_CMD` to split
the transactions. The first index byte in this case would have bit 11
set. Check this indication to inject I2C_SLAVE_WRITE_REQUESTED event
which will reset `idx_write_cnt` in slave eeprom.

Signed-off-by: David Zheng <david.zheng@intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2023-06-05 11:58:20 +02:00
Jiawen Wu
2f8d1ed793 i2c: designware: Add driver support for Wangxun 10Gb NIC
Wangxun 10Gb ethernet chip is connected to Designware I2C, to communicate
with SFP.

Introduce the property "wx,i2c-snps-model" to match device data for Wangxun
in software node case. Since IO resource was mapped on the ethernet driver,
add a model quirk to get regmap from parent device.

The exists IP limitations are dealt as workarounds:
- IP does not support interrupt mode, it works on polling mode.
- Additionally set FIFO depth address the chip issue.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Reviewed-by: Piotr Raczynski <piotr.raczynski@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2023-06-05 11:30:28 +02:00
Mario Limonciello
440da737cf i2c: designware: Use PCI PSP driver for communication
Currently the PSP semaphore communication base address is discovered
by using an MSR that is not architecturally guaranteed for future
platforms.  Also the mailbox that is utilized for communication with
the PSP may have other consumers in the kernel, so it's better to
make all communication go through a single driver.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Reviewed-by: Mark Hasemeyer <markhas@chromium.org>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Tested-by: Mark Hasemeyer <markhas@chromium.org>
Acked-by: Wolfram Sang <wsa@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2023-04-20 18:20:05 +08:00
Shyam Sundar S K
1c7c5fca52 i2c: designware: Change from u32 to unsigned int for regmap_read() calls
regmap_read() API signature expects the caller to send "unsigned int"
type to return back the read value, but there are some occurrences of 'u32'
across i2c-designware-* files.

Change them to match the regmap_read() signature.

Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2023-01-28 20:05:32 +01:00
Shyam Sundar S K
60a1f9f286 i2c: designware: add a new bit check for IC_CON control
On some AMD platforms, based on the new designware datasheet,
BIOS sets the BIT(11) within the IC_CON register to advertise
the "bus clear feature capability".

AMD/Designware datasheet says:

Bit(11) BUS_CLEAR_FEATURE_CTRL. Read-write,Volatile. Reset: 0.
Description: In Master mode:
- 1'b1: Bus Clear Feature is enabled.
- 1'b0: Bus Clear Feature is Disabled.
In Slave mode, this register bit is not applicable.

On AMD platform designs:
1. BIOS programs the BUS_CLEAR_FEATURE_CTRL and enables the detection
of SCL/SDA stuck low.
2. Whenever the stuck low is detected, the SMU FW shall do the bus
recovery procedure.

Currently, the way in which the "master_cfg" is built in the driver, it
overrides the BUS_CLEAR_FEATURE_CTRL advertised by BIOS and the SMU FW
cannot initiate the bus recovery if the stuck low is detected.

Hence add a check in i2c_dw_probe_master() that if the BIOS
advertises the bus clear feature, let driver not ignore it and
adapt accordingly.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2023-01-28 20:05:32 +01:00
Hanna Hawa
f2e1fa9955 i2c: designware: fix i2c_dw_clk_rate() return size to be u32
Make i2c_dw_clk_rate() to return u32 instead of unsigned long, as the
function return the value of get_clk_rate_khz() which returns u32.

Fixes: b33af11de236 ("i2c: designware: Do not require clock when SSCN and FFCN are provided")
Signed-off-by: Hanna Hawa <hhhawa@amazon.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2023-01-09 13:03:46 +01:00
Jarkko Nikula
4bae6da1cb i2c: designware: Add comment to custom register value constants
DW_IC_COMP_VERSION register contains the ASCII representation of the
Synopsys component version. Here 0x3131312A == "111*" means version
1.11* required for DW_IC_SDA_HOLD register availability where '*' means
any letter starting from 'a'.

DW_IC_COMP_TYPE is constant and is derived from two ASCII letters "DW"
followed by a 16-bit unsigned number.

Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-11-12 07:38:16 +01:00
Jarkko Nikula
966b7d3c73 i2c: designware: Align defines in i2c-designware-core.h
Align all defines to the same column.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-11-12 07:38:13 +01:00
Jarkko Nikula
fee61247b7 i2c: designware: Remove common i2c_dw_disable_int()
Commit 90312351fd1e ("i2c: designware: MASTER mode as separated driver")
introduced disable_int pointer but there is no real use for it. Both
i2c-designware-master.c and i2c-designware-slave.c set it to the same
i2c_dw_disable_int() and scope is inside the same kernel module.

Since i2c_dw_disable_int() is just masking interrupts and the direct
DW_IC_INTR_MASK register write looks more clear in the code use that and
remove it from common code.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-11-12 07:38:11 +01:00
Jarkko Nikula
4d827824b7 i2c: designware: Define software status flags with BIT()
Define software status flags with a BIT() macro. While at it remove
STATUS_IDLE and replace its use with zero initialization and status
flags clearing with a mask.

Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-11-12 07:37:30 +01:00
Jarkko Nikula
dcf1bf648f i2c: designware: Empty receive FIFO in slave interrupt handler
Writes from I2C bus often fail when testing the i2c-designware-slave.c
with the slave-eeprom backend. The same writes work correctly when
testing with a real 24c02 EEPROM chip.

In the tests below an i2c-designware-slave.c instance with the
slave-eeprom backend is configured to act as a simulated 24c02 at
address 0x65 on an I2C host bus 6.

1. i2cset -y 6 0x65 0x00 0x55

Single byte 0x55 write into address 0x00. No data goes into simulated
EEPROM. Debug prints from the i2c_dw_irq_handler_slave():

0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x714 : INTR_STAT=0x204
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4

2. i2ctransfer -y 6 w9@0x65 0x00 0xff-

Write 8 bytes with decrementing value starting from 0xff at address 0x00
and forward. Only some of the data goes into arbitrary addresses.
Content is something like below but varies:

00000000  f9 f8 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000050  00 00 00 00 00 00 ff fe  00 00 00 00 00 00 00 00  |................|
000000f0  00 00 00 00 00 00 00 00  00 00 00 00 00 fc fb fa  |................|

In this case debug prints were:

0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4
0x1 STATUS SLAVE_ACTIVITY=0x1 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x714 : INTR_STAT=0x204
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x514 : INTR_STAT=0x4
0x1 STATUS SLAVE_ACTIVITY=0x0 : RAW_INTR_STAT=0x510 : INTR_STAT=0x0

Both cases show there is more data coming from the receive FIFO still
after detecting the STOP condition. This can be seen from interrupt
status bits DW_IC_INTR_STOP_DET (0x200) and DW_IC_INTR_RX_FULL (0x4).

Perhaps due interrupt latencies the receive FIFO is not read fast
enough, STOP detection happens synchronously when it occurs on the I2C
bus and the DW_IC_INTR_RX_FULL keeps coming as long as there are more
bytes in the receive FIFO.

Fix this by reading the receive FIFO completely empty whenever
DW_IC_INTR_RX_FULL occurs. Use RFNE, Receive FIFO Not Empty bit in the
DW_IC_STATUS register to loop through bytes in the FIFO.

While at it do not test the return code from i2c_slave_event() for the
I2C_SLAVE_WRITE_RECEIVED since to my understanding this hardware cannot
generate NACK to incoming bytes and debug print itself does not have
much value.

Reported-by: Tian Ye <tianye@sugon.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-11-12 07:37:22 +01:00
Jarkko Nikula
c42edde5de i2c: designware: Fix slave state machine for sequential reads
Some read types from I2C bus don't work correctly when testing the
i2c-designware-slave.c with the slave-eeprom backend. The same reads
work correctly when testing with a real 24c02 EEPROM chip.

In the following tests an i2c-designware-slave.c instance with the
slave-eeprom backend is configured to act as a simulated 24c02 at
address 0x65 on an I2C host bus 6:

1. i2cdump -y 6 0x65 b (OK)
   Random read. Each byte are read using a byte address write with a
   current address read in a same message.
2. i2cdump -y 6 0x65 c (OK, was NOK before commit 3b5f7f10ff6e when it
                        was repeating the 1st byte)
   Repeated current address read. One byte address write message
   followed by repeated current address read messages.
3. i2cdump -y 6 0x65 i (NOK, each 32 byte block repeats the 1st byte of
                        block)
   Sequential read using SMBus Block Read. For each 32 byte block a byte
   address write followed by 32 sequental reads in a same message.

These findings are explained because the implementation has had a
mismatch between hardware interrupts and what I2C slave events should be
sent after those interrupts. Despite that the case 1 happened to have
always the I2C slave events sent to a right order with a right data
between backend and the I2C bus.

Hardware generates the DW_IC_INTR_RD_REQ interrupt when another host is
attempting to read and for sequential reads after. DW_IC_INTR_RX_DONE
occurs when host does not acknowledge a transmitted byte which is an
indication the end of transmission.

Those interrupts do not match directly with I2C_SLAVE_READ_REQUESTED and
I2C_SLAVE_READ_PROCESSED events which is how the code was and is
practically using them. The slave-eeprom backend increases the buffer
index with the I2C_SLAVE_READ_PROCESSED event and returns the data from
current index when receiving only the I2C_SLAVE_READ_REQUESTED event.

That explains the repeated bytes in case 3 and also case 2 before
commit 3b5f7f10ff6e ("i2c: designware: slave should do WRITE_REQUESTED
before WRITE_RECEIVED").

Patch fixes the case 3 while keep cases 1 and 2 working with following
changes:

- First DW_IC_INTR_RD_REQ interrupt will change the state machine to
  read in progress state, send I2C_SLAVE_READ_REQUESTED event and
  transmit the first byte from backend
- Subsequent DW_IC_INTR_RD_REQ interrupts will send
  I2C_SLAVE_READ_PROCESSED events and transmit next bytes from backend
- STOP won't change the state machine. Otherwise case 2 won't work since
  we cannot distinguish current address read from sequentiel read
- DW_IC_INTR_RX_DONE interrupt is needless since there is no mechanism
  to inform it to a backend. It cannot be used to change state machine
  at the end of read either due the same reason than above
- Next host write to us will change the state machine from read to write
  in progress state
- STATUS_WRITE_IN_PROGRESS and STATUS_READ_IN_PROGRESS are considered
  now to be status flags not the state of the driver. This is how we
  treat them in i2c-designware-master.c

While at it do not test the return code from i2c_slave_event() for
I2C_SLAVE_READ_REQUESTED and I2C_SLAVE_READ_PROCESSED since it returns
always 0.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-11-12 07:37:17 +01:00
Jarkko Nikula
301c8f5c32 i2c: designware: Fix handling of real but unexpected device interrupts
Commit c7b79a752871 ("mfd: intel-lpss: Add Intel Alder Lake PCH-S PCI
IDs") caused a regression on certain Gigabyte motherboards for Intel
Alder Lake-S where system crashes to NULL pointer dereference in
i2c_dw_xfer_msg() when system resumes from S3 sleep state ("deep").

I was able to debug the issue on Gigabyte Z690 AORUS ELITE and made
following notes:

- Issue happens when resuming from S3 but not when resuming from
  "s2idle"
- PCI device 00:15.0 == i2c_designware.0 is already in D0 state when
  system enters into pci_pm_resume_noirq() while all other i2c_designware
  PCI devices are in D3. Devices were runtime suspended and in D3 prior
  entering into suspend
- Interrupt comes after pci_pm_resume_noirq() when device interrupts are
  re-enabled
- According to register dump the interrupt really comes from the
  i2c_designware.0. Controller is enabled, I2C target address register
  points to a one detectable I2C device address 0x60 and the
  DW_IC_RAW_INTR_STAT register START_DET, STOP_DET, ACTIVITY and
  TX_EMPTY bits are set indicating completed I2C transaction.

My guess is that the firmware uses this controller to communicate with
an on-board I2C device during resume but does not disable the controller
before giving control to an operating system.

I was told the UEFI update fixes this but never the less it revealed the
driver is not ready to handle TX_EMPTY (or RX_FULL) interrupt when device
is supposed to be idle and state variables are not set (especially the
dev->msgs pointer which may point to NULL or stale old data).

Introduce a new software status flag STATUS_ACTIVE indicating when the
controller is active in driver point of view. Now treat all interrupts
that occur when is not set as unexpected and mask all interrupts from
the controller.

Fixes: c7b79a752871 ("mfd: intel-lpss: Add Intel Alder Lake PCH-S PCI IDs")
Reported-by: Samuel Clark <slc2015@gmail.com>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215907
Cc: stable@vger.kernel.org # v5.12+
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-10-05 21:00:12 +02:00
Hans de Goede
80704a84a9 i2c: designware: Use the i2c_mark_adapter_suspended/resumed() helpers
Use the i2c_mark_adapter_suspended/resumed() i2c-core helpers and rely
on the i2c-core's suspended checking instead of using DIY code.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-03-01 16:31:39 +01:00
Jan Dabros
78d5e9e299 i2c: designware: Add AMD PSP I2C bus support
Implement an I2C controller sharing mechanism between the host (kernel)
and PSP co-processor on some platforms equipped with AMD Cezanne SoC.

On these platforms we need to implement "software" i2c arbitration.
Default arbitration owner is PSP and kernel asks for acquire as well
as inform about release of the i2c bus via mailbox mechanism.

            +---------+
 <- ACQUIRE |         |
  +---------|   CPU   |\
  |         |         | \      +----------+  SDA
  |         +---------+  \     |          |-------
MAILBOX                   +--> |  I2C-DW  |  SCL
  |         +---------+        |          |-------
  |         |         |        +----------+
  +---------|   PSP   |
   <- ACK   |         |
            +---------+

            +---------+
 <- RELEASE |         |
  +---------|   CPU   |
  |         |         |        +----------+  SDA
  |         +---------+        |          |-------
MAILBOX                   +--> |  I2C-DW  |  SCL
  |         +---------+  /     |          |-------
  |         |         | /      +----------+
  +---------|   PSP   |/
   <- ACK   |         |
            +---------+

The solution is similar to i2c-designware-baytrail.c implementation, where
we are using a generic i2c-designware-* driver with a small "wrapper".

In contrary to baytrail semaphore implementation, beside internal
acquire_lock() and release_lock() methods we are also applying quirks to
lock_bus() and unlock_bus() global adapter methods. With this in place
all i2c clients drivers may lock i2c bus for a desired number of i2c
transactions (e.g. write-wait-read) without being aware of that such bus
is shared with another entity.

Modify i2c_dw_probe_lock_support() to select correct semaphore
implementation at runtime, since now we have more than one available.

Configure new matching ACPI ID "AMDI0019" and register
ARBITRATION_SEMAPHORE flag in order to distinguish setup with PSP
arbitration.

Add myself as a reviewer for I2C DesignWare in order to help with reviewing
and testing possible changes touching new i2c-designware-amdpsp.c module.

Signed-off-by: Jan Dabros <jsd@semihalf.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
[wsa: removed unneeded blank line and curly braces]
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2022-02-11 15:38:23 +01:00
Andy Shevchenko
1ead7e992a i2c: designware: Fix the kernel doc description for struct dw_i2c_dev
$ scripts/kernel-doc -none drivers/i2c/busses/i2c-designware-core.h
warning: Function parameter or member 'rst' not described in 'dw_i2c_dev'
warning: Function parameter or member 'get_clk_rate_khz' not described in 'dw_i2c_dev'
warning: Function parameter or member 'flags' not described in 'dw_i2c_dev'
warning: Function parameter or member 'functionality' not described in 'dw_i2c_dev'
warning: Function parameter or member 'master_cfg' not described in 'dw_i2c_dev'
warning: Function parameter or member 'set_sda_hold_time' not described in 'dw_i2c_dev'
warning: Function parameter or member 'rinfo' not described in 'dw_i2c_dev'

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Randy Dunlap <rdunla@infradead.org>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2021-11-29 10:41:48 +01:00
Andy Shevchenko
85888376a8 i2c: designware: Fix indentation in the header
In couple of places the indentation makes harder to read the code.
Fix it to be sane.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2021-08-11 16:43:32 +02:00
Sanket Goswami
17631e8ca2 i2c: designware: Add driver support for AMD NAVI GPU
The Latest AMD NAVI GPU card has an integrated Type-C controller and
Designware I2C with PCI Interface. The PD controller for USB Type-C can
be accessed over I2C. The client driver is part of the USB Type-C UCSI
driver.

Also, there exists a couple of notable IP limitations that are dealt as
workarounds:
- I2C transaction work on a polling mode as IP does not generate
interrupt.
- I2C read command sent twice to address the IP issues.
- AMD NAVI GPU based products are already in the commercial market,
  hence some of the I2C parameters are statically programmed as they
  can not be part of the ACPI table.

Reviewed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Co-developed-by: Nehal Bakulchandra Shah <Nehal-Bakulchandra.shah@amd.com>
Signed-off-by: Nehal Bakulchandra Shah <Nehal-Bakulchandra.shah@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2021-04-05 23:00:46 +02:00
Liguang Zhang
f53f15ba5a i2c: designware: Get right data length
IC_DATA_CMD[11] indicates the first data byte received after the address
phase for receive transfer in Master receiver or Slave receiver mode,
this bit was set in some transfer flow. IC_DATA_CMD[7:0] contains the
data to be transmitted or received on the I2C bus, so we should use the
lower 8 bits to get the real data length.

Signed-off-by: Liguang Zhang <zhangliguang@linux.alibaba.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2021-02-26 11:26:09 +01:00
Andy Shevchenko
8f95c13228 i2c: designware: Make register offsets all of the same width
For the sake of consistency add leading 0 to first register offsets
to make them all of the same width.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-12-09 21:53:29 +01:00
Andy Shevchenko
a5df4c14b9 i2c: designware: Switch header to use BIT() and GENMASK()
Currently header file uses partially BIT() and GENMASK() macros.
Switch it to use those macros in all cases where it's applicable
for the sake of consistency.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-12-09 21:53:14 +01:00
Andy Shevchenko
852f71942c i2c: designware: Adjust bus speed independently of ACPI
John Stultz reported that commit f9288fcc5c615 ("i2c: designware: Move
ACPI parts into common module") caused a regression on the HiKey board
where adv7511 HDMI bridge driver wasn't probing anymore due the I2C bus
failed to start.

It seems the change caused the bus speed being zero when CONFIG_ACPI
not set and neither speed based on "clock-frequency" device property
or default fast mode is set.

Fix this by splitting i2c_dw_acpi_adjust_bus_speed() to
i2c_dw_acpi_round_bus_speed() and i2c_dw_adjust_bus_speed(), where
the latter one has the code that runs independently of ACPI.

Fixes: f9288fcc5c615 ("i2c: designware: Move ACPI parts into common module")
Reported-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Tested-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-06-23 21:24:33 +02:00
Serge Semin
fcb82a939d i2c: designware: Add Baikal-T1 System I2C support
Baikal-T1 System Controller is equipped with a dedicated I2C Controller
which functionality is based on the DW APB I2C IP-core, the only
difference in a way it' registers are accessed. There are three access
register provided in the System Controller registers map, which indirectly
address the normal DW APB I2C registers space. So in order to have the
Baikal-T1 System I2C Controller supported by the common DW APB I2C driver
we created a dedicated Dw I2C controller model quirk, which retrieves the
syscon regmap from the parental dt node and creates a new regmap based on
it.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-30 23:03:06 +02:00
Serge Semin
0daede80f8 i2c: designware: Convert driver to using regmap API
Seeing the DW I2C driver is using flags-based accessors with two
conditional clauses it would be better to replace them with the regmap
API IO methods and to initialize the regmap object with read/write
callbacks specific to the controller registers map implementation. This
will be also handy for the drivers with non-standard registers mapping
(like an embedded into the Baikal-T1 System Controller DW I2C block, which
glue-driver is a part of this series).

As before the driver tries to detect the mapping setup at probe stage and
creates a regmap object accordingly, which will be used by the rest of the
code to correctly access the controller registers. In two places it was
appropriate to convert the hand-written read-modify-write and
read-poll-loop design patterns to the corresponding regmap API
ready-to-use methods.

Note the regmap IO methods return value is checked only at the probe
stage. The rest of the code won't do this because basically we have
MMIO-based regmap so non of the read/write methods can fail (this also
won't be needed for the Baikal-T1-specific I2C controller).

Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[wsa: fix type of 'rx_valid' and remove outdated kdoc var description]
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-30 23:02:22 +02:00
Serge Semin
c615f5c65f i2c: designware: Discard Cherry Trail model flag
A PM workaround activated by the flag MODEL_CHERRYTRAIL has been removed
since commit 9cbeeca05049 ("i2c: designware: Remove Cherry Trail PMIC I2C
bus pm_disabled workaround"), but the flag most likely by mistake has been
left in the Dw I2C drivers. Let's remove it. Since MODEL_MSCC_OCELOT is
the only model-flag left, redefine it to be 0x100 so setting a very first
bit in the MODEL_MASK bits range.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-30 11:33:54 +02:00
Andy Shevchenko
f9288fcc5c i2c: designware: Move ACPI parts into common module
For possible code reuse in the future, move ACPI parts into common module.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-22 16:50:37 +02:00
Andy Shevchenko
20ee1d9020 i2c: designware: Move i2c_dw_validate_speed() helper to a common code
In order to export array supported speed for wider use, move it
to a header along with i2c_dw_validate_speed() helper moved to
a common code.

No functional changes intended.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-22 16:50:27 +02:00
Andy Shevchenko
a19f133f69 i2c: designware: Include proper headers in i2c-desingware-core.h
This header is a user of some generic ones, include them respectively.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-22 16:50:19 +02:00
Andy Shevchenko
ab0ef8bac1 i2c: designware: Get rid of PCI driver specifics in common code
Do not spread PCI specifics over common code. It seems to be a layering
violation which can be easily avoided. Refactor PCI driver and drop
PCI specifics from common code.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-22 16:50:17 +02:00
Andy Shevchenko
bed20c8402 i2c: designware: Rename i2c_dw_probe() to i2c_dw_probe_master()
As a preparatory patch to support slave mode for PCI enumerated devices rename
i2c_dw_probe() to i2c_dw_probe_master() and split common i2c_dw_probe() as
inline helper.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-13 12:36:22 +02:00
Andy Shevchenko
3ebe40ed1c i2c: designware: Move configuration routines to respective modules
Move configuration routines to respective modules, i.e. master and slave.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
2020-05-13 12:36:22 +02:00
Serge Semin
d816f216c3 i2c: designware: Discard i2c_dw_read_comp_param() function
There is no code left in the kernel which would be using the function.
So just remove it.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2020-03-21 19:32:24 +01:00
Serge Semin
1f1a714658 i2c: designware: Detect the FIFO size in the common code
The problem with detecting the FIFO depth in the platform driver
is that in order to implement this we have to access the controller
IC_COMP_PARAM_1 register. Currently it's done before the
i2c_dw_set_reg_access() method execution, which is errors prone since
the method determines the registers endianness and access mode and we
can't use dw_readl/dw_writel accessors before this information is
retrieved. We also can't move the i2c_dw_set_reg_access() function
invocation to after the master/slave probe functions call (when endianness
and access mode are determined), since the FIFO depth information is used
by them for initializations. So in order to fix the problem we have no
choice but to move the FIFO size detection methods to the common code and
call it at the probe stage.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2020-03-21 19:32:15 +01:00
Phil Edworthy
c62ebb3d5f i2c: designware: Add support for an interface clock
The Synopsys I2C Controller has an interface clock, but most SoCs hide
this away. However, on some SoCs you need to explicitly enable the
interface clock in order to access the registers. Therefore, add
support for an optional interface clock.

Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
Signed-off-by: Gareth Williams <gareth.williams.jx@renesas.com>
Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2019-03-20 17:57:18 +01:00
Hans de Goede
2751541555 i2c: designware: Do not allow i2c_dw_xfer() calls while suspended
On most Intel Bay- and Cherry-Trail systems the PMIC is connected over I2C
and the PMIC is accessed through various means by the _PS0 and _PS3 ACPI
methods (power on / off methods) of various devices.

This leads to suspend/resume ordering problems where a device may be
resumed and get its _PS0 method executed before the I2C controller is
resumed. On Cherry Trail this leads to errors like these:

     i2c_designware 808622C1:06: controller timed out
     ACPI Error: AE_ERROR, Returned by Handler for [UserDefinedRegion]
     ACPI Error: Method parse/execution failed \_SB.P18W._ON, AE_ERROR
     video LNXVIDEO:00: Failed to change power state to D0

But on Bay Trail this caused I2C reads to seem to succeed, but they end
up returning wrong data, which ends up getting written back by the typical
read-modify-write cycle done to turn on various power-resources.

Debugging the problems caused by this silent data corruption is quite
nasty. This commit adds a check which disallows i2c_dw_xfer() calls to
happen until the controller's resume method has completed.

Which turns the silent data corruption into getting these errors in
dmesg instead:

    i2c_designware 80860F41:04: Error i2c_dw_xfer call while suspended
    ACPI Error: AE_ERROR, Returned by Handler for [UserDefinedRegion]
    ACPI Error: Method parse/execution failed \_SB.PCI0.GFX0._PS0, AE_ERROR

Which is much better.

Note the above errors are an example of issues which this patch will
help to debug, the actual fix requires fixing the suspend order and
this has been fixed by a different commit.

Note the setting / clearing of the suspended flag in the suspend / resume
methods is NOT protected by i2c_lock_bus(). This is intentional as these
methods get called from i2c_dw_xfer() (through pm_runtime_get/put) a nd
i2c_dw_xfer() is called with the i2c_bus_lock held, so otherwise we would
deadlock. This means that there is a theoretical race between a non runtime
suspend and the suspended check in i2c_dw_xfer(), this is not a problem
since normally we should not hit the race and this check is primarily a
debugging tool so hitting the check if there are suspend/resume ordering
problems does not need to be 100% reliable.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2019-02-23 11:08:48 +01:00
Linus Torvalds
c2101d0182 More ACPI updates for 4.20-rc1
Rework the handling of the P-unit semaphore on Intel Baytrail and
 Cherrytrail systems to avoid race conditions and excessive overhead
 related to it (Hans de Goede).
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJb2BIsAAoJEILEb/54YlRx/3IP/jhBujlb884Yz1Kzix2cEat0
 56fqh1TJTn9ZyOQjTW2rIbRnOdSNHzerLWWoUZdKO9ndO1gRvLgNBILug2zC/9TZ
 gZ+AODC7JVcAvSk8vVCN7wtHbDFH23dEP5kdye8Ax4MqMFY0ctKMVIvicPD7HXFS
 nFaB/JZQ9SlWKmaIPQKpyTQ5dCTZM5qnziYiRt56HpEFoCPYdzaaUx7zlVWJff8J
 N521n3bEgxglOBqJyGkR5LvOZJ7S92KwOL94FNCY0/yEDbY53YWTxXkpFJVbBzlK
 gELAehxUBD9cnwi+g1OSrTCeOVdsCWwmiztTbpHlcLhCITsHFdg1B6SPlX3Sw4Wv
 DRszpnazSJfJj87JNRaYBXdgQnDs3wDW5yji3aTbu8MOa8kWMrpDzmR/qs4vYZGT
 EB37hKk0ZO15dNeIhHmKoo4d3pzDYzSAeJ1d1c2cOG5QMF3qsIfZyHyDQAUaIYMx
 EkLhZki2PyOFicgTlchr+9mBsXT37KrJXxYIFb4w2BjzZ4u74IEER4QDgRHSFuTL
 sJgxrqY/+n1142UqFRhgu59yeRKl+seyNHB/RptM1DsVs4BRkHcEj4pfBPq49Kxv
 2H0ByTAvy09olcFvFqSVCFzPEquNsLJrvhrTiwbduOsBcVHwXIWNywaBwjeYllPX
 iNIWx7Nr/TzlV4hPO8pH
 =4oYh
 -----END PGP SIGNATURE-----

Merge tag 'acpi-4.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more ACPI updates from Rafael Wysocki:
 "Rework the handling of the P-unit semaphore on Intel Baytrail and
  Cherrytrail systems to avoid race conditions and excessive overhead
  related to it (Hans de Goede)"

* tag 'acpi-4.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / PMIC: xpower: Add depends on IOSF_MBI to Kconfig entry
  i2c: designware: Cleanup bus lock handling
  ACPI / PMIC: xpower: Block P-Unit I2C access during read-modify-write
  x86: baytrail/cherrytrail: Rework and move P-Unit PMIC bus semaphore code
2018-10-30 09:15:31 -07:00
Hans de Goede
8afb46804d i2c: designware: Cleanup bus lock handling
Now that most of the special Bay- / Cherry-Trail bus lock handling has
been moved to the iosf_mbi code we can simplify the remaining code a bit.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2018-10-25 17:00:05 +02:00
Hans de Goede
b30f2f6556 i2c: designware: Set IRQF_NO_SUSPEND flag for all BYT and CHT controllers
On some Cherry Trail systems the GPU ACPI fwnode has power-resources which
point to the PMIC, which is connected over a LPSS I2C controller. The GPU
is a PCI device and PCI devices are powered-on at the resume_noirq resume
phase.

Since the GPU power-resources need the I2C controller, recent acpi_lpss.c
changes now also power-up the LPSS I2C controllers on BYT and CHT devices
in the resume_noirq resume phase. But during this phase the IRQ of the
controller is disabled leading to these errors:

 i2c_designware 808622C1:06: controller timed out
 ACPI Error: AE_ERROR, Returned by Handler for [UserDefinedRegion]
 ACPI Error: Method parse/execution failed \_SB.P18W._ON, AE_ERROR
 video LNXVIDEO:00: Failed to change power state to D0

This commit makes the i2c-designware controller set the IRQF_NO_SUSPEND
flag when requesting the interrupt on BYT and CHT devices, so that the IRQ
is left enabled during the noirq phase, fixing this.

Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-10-11 23:05:09 +02:00
Hans de Goede
9cbeeca050 i2c: designware: Remove Cherry Trail PMIC I2C bus pm_disabled workaround
Commit a3d411fb38c0 ("i2c: designware: Disable pm for PMIC i2c-bus even if
there is no _SEM method"), always set the pm_disabled flag on the I2C7
controller, even if its bus was not shared with the PUNIT.

This was a workaround for various suspend/resume issues, after the
following 2 commits this workaround is no longer necessary:

Commit 541527728341 ("PM: i2c-designware-platdrv: Suspend/resume at the
                     late/early stages")
Commit e6ce0ce34f65 ("ACPI / LPSS: Add device link for CHT SD card
                     dependency on I2C")

Therefor this commit removes this workaround.

After this commit the pm_disabled flag is only used to indicate that the
bus is shared with the PUNIT and after other recent changes we no longer
call dev_pm_syscore_device(dev, true), so we are no longer actually
disabling (non-runtime) pm, so this commit also renames the flag to
shared_with_punit to better reflect what it is for.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-09-06 20:29:10 +02:00
Alexandre Belloni
1bb3995962 i2c: designware: add MSCC Ocelot support
The Microsemi Ocelot I2C controller is a designware IP. It also has a
second set of registers to allow tweaking SDA hold time and spike
filtering.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
[wsa: made one function static]
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-09-02 23:51:15 +02:00
Alexandre Belloni
c7fa7aeff8 i2c: designware: allow IP specific sda_hold_time
Because some old designware IPs were not supporting setting an SDA hold
time, vendors developed their own solution. Add a way for the final driver
to provide its own SDA hold time handling.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-09-02 23:51:15 +02:00
Andy Shevchenko
15c566fcff i2c: designware: Add SPDX license tag
Replace short statement in comment with proper SPDX license tag.

Note, for i2c-desingware-slave.c the identifier is chosen
in accordance with MODULE_LICENSE() macro since it is visible to user.
Another point to this choice is that the header seems to be copy'n'paste
from the other file of this very driver.

Acked-by: Luis Oliveira <Luis.Oliveira@synopsys.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-08-20 10:45:45 +02:00
Andy Shevchenko
e3ea52b578 i2c: designware: Convert to use struct i2c_timings
Instead of using custom variables and parser, convert the driver to use
the ones provided by I2C core.

No functional change intended.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Tested-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-08-08 22:28:52 +02:00
Jarkko Nikula
1080ee7e28 i2c: designware: Move SDA hold time configuration to common code
SDA hold time configuration is common to both master and slave code. It
is also something that can be done once during probe and do only
register write when HW needs to be reinitialized.

Remove duplication and move SDA hold time configuration to common code.
It will be called from slave probe and for master code from a new
i2c_dw_set_timings_master() to where we will populate more probe time
timing parameter setting.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-07-03 23:05:55 +02:00
Jarkko Nikula
3aca0bd6f4 i2c: designware: Move register access detection to common code
Move register access detection out from master and slave HW
initialization code to common code. Motivation for this is to have
register access configured before HW initialization and remove
duplicated code.

This allows to do further separation between probe time initialization
and runtime reinitialization code.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-07-03 23:05:20 +02:00
Alexander Monakov
9f4659ba38 i2c: designware: refactor low-level enable/disable
Low-level controller enable function __i2c_dw_enable is overloaded to
also handle disabling. What's worse, even though the documentation
requires polling the IC_ENABLE_STATUS register when disabling, this
is not done: polling needs to be requested specifically by calling
__i2c_dw_enable_and_wait, which can also poll on enabling, but that
doesn't work if the IC_ENABLE_STATUS register is not implemented.
This is quite confusing if not in fact backwards.

Especially since the documentation says that disabling should be
followed by polling, the driver should be using a separate function
where it does one-shot disables to make the optimization stand out.

This refactors the two functions so that requested status is given
in the name rather than in a boolean argument. Specifically:

 - __i2c_dw_enable: enable without polling (in accordance with docs)
 - __i2c_dw_disable: disable and do poll (also as suggested by docs)
 - __i2c_dw_disable_nowait: disable without polling (Linux-specific)

No functional change.

Signed-off-by: Alexander Monakov <amonakov@ispras.ru>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
[wsa: fixed blank lines in header file]
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2018-05-15 10:42:19 +02:00
Linus Torvalds
4141cf676b Merge branch 'i2c/for-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
 "I2C has the following changes for you:

   - new flag to mark DMA safe buffers in i2c_msg. Also, some
     infrastructure around it. And docs.

   - huge refactoring of the at24 driver led by the new maintainer
     Bartosz

   - update I2C bus recovery to send STOP after recovery

   - conversion from gpio to gpiod for I2C bus recovery

   - adding a fault-injector to the i2c-gpio driver

   - lots of small driver improvements, and bigger ones to
     i2c-sh_mobile"

* 'i2c/for-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (99 commits)
  i2c: mv64xxx: Add myself as maintainer for this driver
  i2c: mv64xxx: Fix clock resource by adding an optional bus clock
  i2c: mv64xxx: Remove useless test before clk_disable_unprepare
  i2c: mxs: use true and false for boolean values
  i2c: meson: update doc description to fix build warnings
  i2c: meson: add configurable divider factors
  dt-bindings: i2c: update documentation for the Meson-AXG
  i2c: imx-lpi2c: add runtime pm support
  i2c: rcar: fix some trivial typos in comments
  i2c: davinci: fix the cpufreq transition
  i2c: rk3x: add proper kerneldoc header
  i2c: rk3x: account for const type of of_device_id.data
  i2c: acorn: remove outdated path from file header
  i2c: acorn: add MODULE_LICENSE tag
  i2c: rcar: implement bus recovery
  i2c: send STOP after successful bus recovery
  i2c: ensure SDA is released in recovery if SDA is controllable
  i2c: add 'set_sda' to bus_recovery_info
  i2c: add identifier in declarations for i2c_bus_recovery
  i2c: make kerneldoc about bus recovery more precise
  ...
2018-02-04 10:57:43 -08:00
Rafael J. Wysocki
02e45646d5 PM: i2c-designware-platdrv: Optimize power management
Optimize the power management in i2c-designware-platdrv by making it
set the DPM_FLAG_SMART_SUSPEND and DPM_FLAG_LEAVE_SUSPENDED which
allows some code to be dropped from its PM callbacks.

First, setting DPM_FLAG_SMART_SUSPEND causes the intel-lpss driver
to avoid resuming i2c-designware-platdrv devices in its ->prepare
callback, so they can stay in runtime suspend after that point even
if the direct-complete feature is not used for them.

It also causes the ACPI PM domain and the PM core to avoid invoking
"late" and "noirq" suspend callbacks for these devices if they are
in runtime suspend at the beginning of the "late" phase of device
suspend during system suspend.  That guarantees dw_i2c_plat_suspend()
to be called for a device only if it is not in runtime suspend.

Moreover, it causes the device's runtime PM status to be set to
"active" after calling dw_i2c_plat_resume() for it, so the
driver doesn't need internal flags to avoid invoking either
dw_i2c_plat_suspend() or dw_i2c_plat_resume() twice in a row.

Second, setting DPM_FLAG_LEAVE_SUSPENDED enables the optimization
allowing the device to stay suspended after system resume under
suitable conditions, so again the driver doesn't need to take
care of that by itself.

Accordingly, the internal "suspended" and "skip_resume" flags
used by the driver are not necessary any more, so drop them and
simplify the driver's PM callbacks.

Additionally, notice that dw_i2c_plat_complete() only needs to
schedule runtime PM resume for the device if platform firmware
has been involved in resuming the system, so make it call
pm_resume_via_firmware() to check that.  Also make it check the
runtime PM status of the device instead of its direct_complete
flag which also works if the device remained suspended due to
the DPM_FLAG_LEAVE_SUSPENDED driver flag.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Wolfram Sang <wsa@the-dreams.de>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
2018-01-10 00:48:25 +01:00