1
Commit Graph

148 Commits

Author SHA1 Message Date
Kaixin Wang
6185072577 i3c: master: svc: Fix use after free vulnerability in svc_i3c_master Driver Due to Race Condition
In the svc_i3c_master_probe function, &master->hj_work is bound with
svc_i3c_master_hj_work, &master->ibi_work is bound with
svc_i3c_master_ibi_work. And svc_i3c_master_ibi_work  can start the
hj_work, svc_i3c_master_irq_handler can start the ibi_work.

If we remove the module which will call svc_i3c_master_remove to
make cleanup, it will free master->base through i3c_master_unregister
while the work mentioned above will be used. The sequence of operations
that may lead to a UAF bug is as follows:

CPU0                                         CPU1

                                    | svc_i3c_master_hj_work
svc_i3c_master_remove               |
i3c_master_unregister(&master->base)|
device_unregister(&master->dev)     |
device_release                      |
//free master->base                 |
                                    | i3c_master_do_daa(&master->base)
                                    | //use master->base

Fix it by ensuring that the work is canceled before proceeding with the
cleanup in svc_i3c_master_remove.

Fixes: 0f74f8b667 ("i3c: Make i3c_master_unregister() return void")
Cc: stable@vger.kernel.org
Signed-off-by: Kaixin Wang <kxwang23@m.fudan.edu.cn>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/stable/20240914154030.180-1-kxwang23%40m.fudan.edu.cn
Link: https://lore.kernel.org/r/20240914163932.253-1-kxwang23@m.fudan.edu.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-17 16:51:45 +02:00
Kaixin Wang
609366e7a0 i3c: master: cdns: Fix use after free vulnerability in cdns_i3c_master Driver Due to Race Condition
In the cdns_i3c_master_probe function, &master->hj_work is bound with
cdns_i3c_master_hj. And cdns_i3c_master_interrupt can call
cnds_i3c_master_demux_ibis function to start the work.

If we remove the module which will call cdns_i3c_master_remove to
make cleanup, it will free master->base through i3c_master_unregister
while the work mentioned above will be used. The sequence of operations
that may lead to a UAF bug is as follows:

CPU0                                      CPU1

                                     | cdns_i3c_master_hj
cdns_i3c_master_remove               |
i3c_master_unregister(&master->base) |
device_unregister(&master->dev)      |
device_release                       |
//free master->base                  |
                                     | i3c_master_do_daa(&master->base)
                                     | //use master->base

Fix it by ensuring that the work is canceled before proceeding with
the cleanup in cdns_i3c_master_remove.

Signed-off-by: Kaixin Wang <kxwang23@m.fudan.edu.cn>
Link: https://lore.kernel.org/r/20240911153544.848398-1-kxwang23@m.fudan.edu.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-17 16:50:18 +02:00
Carlos Song
96267f358c i3c: master: svc: adjust SDR according to i3c spec
According to I3C Specification(Version 1.1) 5.1.2.4 "Use of Clock
Speed to Prevent Legacy I2C Devices From Seeing I3C traffic", when
slow i2c devices(FM/FM+ rate i2c frequency without 50ns filter)
works on i3c bus, i3c SDR should work at FM/FM+ rate.

Adjust timing for difference mode.

Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
Signed-off-by: Carlos Song <carlos.song@nxp.com>
Signed-off-by: Frank Li <frank.li@nxp.com>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20240719080233.842771-1-carlos.song@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-17 16:48:40 +02:00
Carlos Song
20ade67bb1 i3c: master: svc: use slow speed for first broadcast address
I3C controller should support adjusting open drain timing for the first
broadcast address to make I3C device working as a i2c device can see slow
broadcast address to close its Spike Filter to change working at i3c mode.

Signed-off-by: Carlos Song <carlos.song@nxp.com>
Reviewed-by: Frank Li <frank.li@nxp.com>
Link: https://lore.kernel.org/r/20240910051626.4052552-2-carlos.song@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-17 16:46:22 +02:00
Billy Tsai
061dd21ca7 i3c/master: cmd_v1: Fix the rule for getting i3c mode
Based on the I3C TCRI specification, the rules for determining the I3C
mode are as follows:
I3C SCL rate > 8MHz: use SDR0, as SDR1 has a maximum data rate of 8MHz
I3C SCL rate > 6MHz: use SDR1, as SDR2 has a maximum data rate of 6MHz
I3C SCL rate > 4MHz: use SDR2, as SDR3 has a maximum data rate of 4MHz
I3C SCL rate > 2MHz: use SDR3, as SDR4 has a maximum data rate of 2MHz
Otherwise, use SDR4

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
Link: https://lore.kernel.org/r/20240826033821.175591-1-billy_tsai@aspeedtech.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-06 17:36:02 +02:00
Liao Chen
133f67bea5 i3c: master: cdns: fix module autoloading
Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded
based on the alias from of_device_id table.

Signed-off-by: Liao Chen <liaochen4@huawei.com>
Link: https://lore.kernel.org/r/20240826123957.379212-1-liaochen4@huawei.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-05 18:46:19 +02:00
Shyam Sundar S K
ced86959d2 i3c: mipi-i3c-hci: Add a quirk to set Response buffer threshold
The current driver sets the response buffer threshold value to 1
(N+1, 2 DWORDS) in the QUEUE THRESHOLD register. However, the AMD
I3C controller only generates interrupts when the response buffer
threshold value is set to 0 (1 DWORD).

Therefore, a quirk is added to set the response buffer threshold value
to 0.

Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Co-developed-by: Krishnamoorthi M <krishnamoorthi.m@amd.com>
Signed-off-by: Krishnamoorthi M <krishnamoorthi.m@amd.com>
Co-developed-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com>
Signed-off-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://lore.kernel.org/r/20240829091713.736217-7-Shyam-sundar.S-k@amd.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-05 18:34:09 +02:00
Shyam Sundar S K
46d4daa517 i3c: mipi-i3c-hci: Add a quirk to set timing parameters
The AMD HCI controller is currently unstable at 12.5 MHz. To address this,
a quirk is added to configure the clock rate to 9 MHz as a workaround,
with proportional adjustments to the Open-Drain (OD) and Push-Pull (PP)
values.

Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Co-developed-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com>
Signed-off-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://lore.kernel.org/r/20240829091713.736217-6-Shyam-sundar.S-k@amd.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-05 18:34:09 +02:00
Shyam Sundar S K
216201b3d7 i3c: mipi-i3c-hci: Relocate helper macros to HCI header file
The reg_* helper macros are currently limited to core.c. Moving them to
hci.h will allow their functionality to be utilized in other files outside
of core.c.

Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Co-developed-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com>
Signed-off-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://lore.kernel.org/r/20240829091713.736217-5-Shyam-sundar.S-k@amd.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-05 18:34:09 +02:00
Shyam Sundar S K
0140893299 i3c: mipi-i3c-hci: Add a quirk to set PIO mode
The AMD HCI controller currently only supports PIO mode but exposes DMA
rings to the OS, which leads to the controller being configured in DMA
mode. To address this, add a quirk to avoid configuring the controller in
DMA mode and default to PIO mode.

Additionally, introduce a generic quirk infrastructure to the mipi-i3c-hci
driver to facilitate seamless future quirk additions.

Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Co-developed-by: Krishnamoorthi M <krishnamoorthi.m@amd.com>
Signed-off-by: Krishnamoorthi M <krishnamoorthi.m@amd.com>
Co-developed-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com>
Signed-off-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://lore.kernel.org/r/20240829091713.736217-4-Shyam-sundar.S-k@amd.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-05 18:34:08 +02:00
Shyam Sundar S K
039b23609f i3c: mipi-i3c-hci: Read HC_CONTROL_PIO_MODE only after i3c hci v1.1
The HC_CONTROL_PIO_MODE bit was introduced in the HC_CONTROL register
starting from version 1.1. Therefore, checking the HC_CONTROL_PIO_MODE bit
on hardware that adheres to older specification revisions (i.e., versions
earlier than 1.1) is incorrect. To address this, add an additional check
to read the HCI version before attempting to read the HC_CONTROL_PIO_MODE
status.

Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20240829091713.736217-3-Shyam-sundar.S-k@amd.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-05 18:34:08 +02:00
Shyam Sundar S K
8d2e56ef83 i3c: mipi-i3c-hci: Add AMDI5017 ACPI ID to the I3C Support List
The current driver code lacks the necessary plumbing for ACPI IDs,
preventing the mipi-i3c-hci driver from being loaded on x86
platforms that advertise I3C ACPI support.

Add the AMDI5017 ACPI ID to the list of supported IDs.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20240829091713.736217-2-Shyam-sundar.S-k@amd.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-09-05 18:34:08 +02:00
Dan Carpenter
b73c983491 i3c: master: svc: Fix error code in svc_i3c_master_do_daa_locked()
This code has a typo so it returns positive EIO instead of negative -EIO.  Fix
it!

Fixes: a7809cb368b9 ("i3c: master: svc: Improve DAA STOP handle code logic")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/e017edfc-da64-496b-8516-958bec27cd9a@stanley.mountain
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:30 +02:00
Aniket
62fe9d06f5 i3c: dw: Add power management support
Add support for runtime and system power management.
Handle clocks, resets, pads as part of suspend and resume.
Restore controller registers that could be lost due to suspend.
Finally add get and put calls appropriately in functions which
access controller : bus_init, do_daa, send_ccc_cmd, priv_xfers,
i2c_xfers, ibi and hot-join.

Signed-off-by: Aniket <aniketmaurya@google.com>
Link: https://lore.kernel.org/r/20240708062103.3296587-4-aniketmaurya@google.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:30 +02:00
Aniket
effd21743c i3c: dw: Add some functions for reusability
Separate logic for setting intr/thld registers in a func.
Also modify enable function to take care of setting all fields in DEVICE_CTRL.
These functions can be reused later for power management.

Signed-off-by: Aniket <aniketmaurya@google.com>
Link: https://lore.kernel.org/r/20240708062103.3296587-3-aniketmaurya@google.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:30 +02:00
Aniket
4e89bc48e6 i3c: dw: Save timing registers and other values
Add variables to store timing registers and other values.
These variables would be later used to restore registers
during resume without recomputation.

Signed-off-by: Aniket <aniketmaurya@google.com>
Link: https://lore.kernel.org/r/20240708062103.3296587-2-aniketmaurya@google.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Frank Li
915d0741e0 i3c: master: svc: Improve DAA STOP handle code logic
The REQUEST_PROC_DAA command behaves differently from other commands.
Sometimes the hardware can auto emit STOP, but in other conditions, it
cannot.

Improves the code logic to better handle these situations.

Hardware can auto emit STOP only when the following conditions are met:
- The previous I3C device correctly returns a PID and ACKs an I3C address.
- A NACK is received when emitting 7E to try to get the next I3C device's
PID.

In all other cases, a manual STOP emission is needed.

The code is changed to emit STOP when break the while loop and 'return 0'
only when the hardware can auto emit STOP.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20240702223107.403057-1-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Aniket
a0d48ebf39 i3c: dw: Add optional apb clock
Besides the core clock, IP also has an apb interface clock.
Add an optional hook for the same.

Signed-off-by: Aniket <aniketmaurya@google.com>
Link: https://lore.kernel.org/r/20240628154618.327151-1-aniketmaurya@google.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Aniket
54f5079e0d i3c: dw: Use new *_enabled clk API
Move to "enabled" variant of clk_get API. It takes care
of enable and disable calls during the probe and remove.

Signed-off-by: Aniket <aniketmaurya@google.com>
Link: https://lore.kernel.org/r/20240628154603.326075-1-aniketmaurya@google.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Chen Ni
48a6dcdafd i3c: master: svc: Convert comma to semicolon
Replace a comma between expression statements by a semicolon.

Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
Link: https://lore.kernel.org/r/20240702024758.1411569-1-nichen@iscas.ac.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Jarkko Nikula
4642f7eddb i3c: mipi-i3c-hci: Round IBI data chunk size to HW supported value
The dma.c: hci_dma_init() sets the CHUNK_SIZE field in the IBI_SETUP
register incorrectly if the calculated ibi_chunk_sz is not exactly
2^(n+2) bytes, where n is 0..6.

Fix this by rounding the chunk size up to nearest 2^(n+2) bytes.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20240628131559.502822-4-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Jarkko Nikula
8a2be2f1db i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup
Definitely condition dma_get_cache_alignment * defined value > 256
during driver initialization is not reason to BUG_ON(). Turn that to
graceful error out with -EINVAL.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20240628131559.502822-3-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Jarkko Nikula
2df1de813a i3c: mipi-i3c-hci: Set IBI Status and Data Ring base addresses
IBI Status and Data Ring base address registers are not set so HW
obviously cannot update those rings after In-Band Interrupt.

Set them to already allocated and mapped ring addresses.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20240628131559.502822-2-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Jarkko Nikula
74e931f090 i3c: mipi-i3c-hci: Switch to lower_32_bits()/upper_32_bits() helpers
Rather than having own lo32()/hi32() helpers for dealing with 32-bit and
64-bit build targets switch to generic lower_32_bits()/upper_32_bits()
helpers.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20240628131559.502822-1-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Aniket
d9deb28f70 i3c: dw: Remove ibi_capable property
Since DW I3C IP master role always supports IBI, we don't need
to keep two variants of master ops and select one using this
property. Hence remove the code.

Signed-off-by: Aniket <aniketmaurya@google.com>
Link: https://lore.kernel.org/r/20240627034119.3938050-1-aniketmaurya@google.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Aniket
64bf145908 i3c: dw: Fix IBI intr programming
IBI_SIR_REQ_REJECT register is not present if the IP has
IC_HAS_IBI_DATA = 1 set. So don't rely on doing read-
modify-write op on this register.
Instead maintain a variable to store the sir reject mask
and use it to set IBI_SIR_REQ_REJECT.

Signed-off-by: Aniket <aniketmaurya@google.com>
Reviewed-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Aniket
8f2cb03279 i3c: dw: Fix clearing queue thld
QUEUE_THLD_CTRL_IBI_STAT_MASK is repeated twice.
Replace with QUEUE_THLD_CTRL_IBI_DATA_MASK.

Signed-off-by: Aniket <aniketmaurya@google.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Jarkko Nikula
be90ae1ba1 i3c: mipi-i3c-hci: Fix number of DAT/DCT entries for HCI versions < 1.1
I was wrong about the TABLE_SIZE field description in the
commit 0676bfebf5 ("i3c: mipi-i3c-hci: Fix DAT/DCT entry sizes").

For the MIPI I3C HCI versions 1.0 and earlier the TABLE_SIZE field in
the registers DAT_SECTION_OFFSET and DCT_SECTION_OFFSET is indeed defined
in DWORDs and not number of entries like it is defined in later versions.

Where above fix allowed driver initialization to continue the wrongly
interpreted TABLE_SIZE field leads variables DAT_entries being twice and
DCT_entries four times as big as they really are.

That in turn leads clearing the DAT table over the boundary in the
dat_v1.c: hci_dat_v1_init().

So interprete the TABLE_SIZE field in DWORDs for HCI versions < 1.1 and
fix number of DAT/DCT entries accordingly.

Fixes: 0676bfebf5 ("i3c: mipi-i3c-hci: Fix DAT/DCT entry sizes")
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Frank Li
9bc7501b0b i3c: master: svc: resend target address when get NACK
According to I3C Spec 1.1.1, 11-Jun-2021, section: 5.1.2.2.3:

If the Controller chooses to start an I3C Message with an I3C Dynamic
Address, then special provisions shall be made because that same I3C Target
may be initiating an IBI or a Controller Role Request. So, one of three
things may happen: (skip 1, 2)

3. The Addresses match and the RnW bits also match, and so neither
Controller nor Target will ACK since both are expecting the other side to
provide ACK. As a result, each side might think it had "won" arbitration,
but neither side would continue, as each would subsequently see that the
other did not provide ACK.
...
For either value of RnW: Due to the NACK, the Controller shall defer the
Private Write or Private Read, and should typically transmit the Target
						    ^^^^^^^^^^^^^^^^^^^
Address again after a Repeated START (i.e., the next one or any one prior
^^^^^^^^^^^^^
to a STOP in the Frame). Since the Address Header following a Repeated
START is not arbitrated, the Controller will always win (see Section
5.1.2.2.4).

Resend target address again if address is not 7E and controller get NACK.

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-07-26 14:21:29 +02:00
Billy Tsai
1d08326020 i3c: dw: Add hot-join support.
Add hot-join support for dw i3c master controller.
By default, the hot-join acknowledgment is disabled, and the hardware will
automatically send the DISEC CCC when it receives the hot-join request.
Users can use the sys entry to enable it.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
Link: https://lore.kernel.org/r/20240429073624.256830-1-billy_tsai@aspeedtech.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-05-23 00:29:19 +02:00
Frank Li
38baed9b86 i3c: master: svc: fix invalidate IBI type and miss call client IBI handler
In an In-Band Interrupt (IBI) handle, the code logic is as follows:

1: writel(SVC_I3C_MCTRL_REQUEST_AUTO_IBI | SVC_I3C_MCTRL_IBIRESP_AUTO,
	  master->regs + SVC_I3C_MCTRL);

2: ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val,
                                    SVC_I3C_MSTATUS_IBIWON(val), 0, 1000);
	...
3: ibitype = SVC_I3C_MSTATUS_IBITYPE(status);
   ibiaddr = SVC_I3C_MSTATUS_IBIADDR(status);

SVC_I3C_MSTATUS_IBIWON may be set before step 1. Thus, step 2 will return
immediately, and the I3C controller has not sent out the 9th SCL yet.
Consequently, ibitype and ibiaddr are 0, resulting in an unknown IBI type
occurrence and missing call I3C client driver's IBI handler.

A typical case is that SVC_I3C_MSTATUS_IBIWON is set when an IBI occurs
during the controller send start frame in svc_i3c_master_xfer().

Clear SVC_I3C_MSTATUS_IBIWON before issue SVC_I3C_MCTRL_REQUEST_AUTO_IBI
to fix this issue.

Cc: stable@vger.kernel.org
Fixes: 5e5e3c92e7 ("i3c: master: svc: fix wrong data return when IBI happen during start frame")
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20240506164009.21375-3-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-05-23 00:29:19 +02:00
Frank Li
7f3d633b46 i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame
svc_i3c_master_xfer() returns error ENXIO if an In-Band Interrupt (IBI)
occurs when the host starts the frame.

Change error code to EAGAIN to inform the client driver that this
situation has occurred and to try again sometime later.

Fixes: 5e5e3c92e7 ("i3c: master: svc: fix wrong data return when IBI happen during start frame")
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20240506164009.21375-2-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-05-23 00:29:19 +02:00
Dylan Hung
10201396ef i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling
Disable IBI IRQ signal and status only when hot-join and SIR enabling of
all target devices attached to the bus are disabled.

Fixes: e389b1d72a ("i3c: dw: Add support for in-band interrupts")

Signed-off-by: Dylan Hung <dylan_hung@aspeedtech.com>
Link: https://lore.kernel.org/r/20240119054547.983693-1-dylan_hung@aspeedtech.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-02-19 00:32:34 +01:00
Harshit Shah
374c13f908 i3c: master: cdns: Update maximum prescaler value for i2c clock
As per the Cadence IP document fixed the I2C clock divider value limit from
16 bits instead of 10 bits. Without this change setting up the I2C clock to
low frequencies will not work as the prescaler value might be greater than
10 bit number.

I3C clock divider value is 10 bits only. Updating the macro names for both.

Signed-off-by: Harshit Shah <harshitshah.opendev@gmail.com>
Link: https://lore.kernel.org/r/1703927483-28682-1-git-send-email-harshitshah.opendev@gmail.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-01-08 00:51:36 +01:00
Frank Li
6d1a19d34e i3c: master: svc: return actual transfer data len
I3C allow devices early terminate data transfer. So set "actual_len" to
indicate how much data get by i3c_priv_xfer.

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231201222532.2431484-6-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-01-08 00:49:21 +01:00
Frank Li
6fb61734a7 i3c: master: svc: rename read_len as actual_len
I3C transfer (SDR), target can early terminate read transfer.
I3C transfer (HDR), target can end write transfer.
I2C transfer, target can NACK write transfer.

'actual_len' is better name than 'read_len'.

Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231201222532.2431484-5-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-01-08 00:49:21 +01:00
Frank Li
05b26c31a4 i3c: master: svc: add hot join support
Add hot join support for svc master controller. Disable hot join by
default.
User can use sysfs entry to enable hot join.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231201222532.2431484-3-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2024-01-08 00:48:10 +01:00
Jarkko Nikula
4afd728769 i3c: mipi-i3c-hci: Add DMA bounce buffer for private transfers
Implement a local bounce buffer for private I3C SDR and I2C transfers
when using DMA and the buffer attached to the transfer is not DMA safe.

Otherwise the DMA transfer will fail and with following warning:

[   11.411059] i3c mipi-i3c-hci.0: rejecting DMA map of vmalloc memory
[   11.417313] WARNING: CPU: 3 PID: 357 at include/linux/dma-mapping.h:332 hci_dma_queue_xfer+0x2e2/0x300 [mipi_i3c_hci]

Strictly speaking private I3C SDR transfers are expected to pass a
DMA-able buffer. However I fear this requirement may easily be slipped
or go unnoticed when I3C interface support is added into a existing
device driver that use regmap API to read/write stack variables.

For example this is the case with the commit 2660b0080b ("iio: imu:
st_lsm6dsx: add i3c basic support for LSM6DSO and LSM6DSR").

Buffer of an I2C message is not required to be DMA safe and the I2C core
provides i2c_(get|put)_dma_safe_msg_buf() helpers for the host
controllers that do DMA and that is also recommendation for the
i2c_xfers() callback from the I3C core.

However due to above I3C private transfers reason I decided to implement
a bounce buffer for them and reuse the same code for the I2C transfers
too. Since this driver is currently the only I3C host controller driver
that can do DMA the implementation is done here and not in I3C core.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20231109133708.653950-5-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-16 23:36:44 +01:00
Jarkko Nikula
f83f86e506 i3c: mipi-i3c-hci: Handle I3C address header error in hci_cmd_v1_daa()
Handle also I3C address header error response status as the end of DAA
process in hci_cmd_v1_daa().

According to MIPI I3C HCI Specification v1.1 the NACK error during DAA
process comes when the device does not accept the dynamic address.
Currently code uses it for successful exit from the process and fails
with any other error response.

I'm unsure is this MIPI I3C HCI version specific difference or
specification misunderstanding but on an early MIPI I3C HCI version
compatible controller responds always with I3C address header error and
not with NACK error when there is no device on the bus or no more devices
participating to DAA process.

Handle now both response statuses as the end of DAA.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20231109133708.653950-4-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-16 23:36:44 +01:00
Jarkko Nikula
0be1a06c66 i3c: mipi-i3c-hci: Do not overallocate transfers in hci_cmd_v1_daa()
Function hci_cmd_v1_daa() uses only single transfer at a time so no need
to allocate two transfers and access can be simplified.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20231109133708.653950-3-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-16 23:36:44 +01:00
Jarkko Nikula
9e0e9e85e7 i3c: mipi-i3c-hci: Report NACK response from CCC command to core
Currently probe of mipi-i3c-hci will fail if bus doesn't have any I3C
devices connected. This happens when CCC commands that are sent during
i3c_master_bus_init() are not ACKed by any device and controller responds
with an error status set.

The controller can detect NACK both during I3C address header
transmission (broadcast address 0x7e is not ACKed) and when target
device address or dynamic address assignment is NACKed. Former as error
status 0x4: Address Header Error and latter as 0x5: NACK.

Difference between those two NACK statuses were not described explicitly
until MIPI I3C HCI Specification v1.1. Earlier versions share the same
error status code though.

Report both of those as I3C_ERROR_M2 to I3C core code.

Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Link: https://lore.kernel.org/r/20231109133708.653950-2-jarkko.nikula@linux.intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-16 23:36:44 +01:00
Billy Tsai
b53e9758a3 i3c: master: mipi-i3c-hci: Fix a kernel panic for accessing DAT_data.
The `i3c_master_bus_init` function may attach the I2C devices before the
I3C bus initialization. In this flow, the DAT `alloc_entry`` will be used
before the DAT `init`. Additionally, if the `i3c_master_bus_init` fails,
the DAT `cleanup` will execute before the device is detached, which will
execue DAT `free_entry` function. The above scenario can cause the driver
to use DAT_data when it is NULL.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
Link: https://lore.kernel.org/r/20231023080237.560936-1-billy_tsai@aspeedtech.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-04 00:39:52 +01:00
Frank Li
8911eae9c8 i3c: master: svc: fix compatibility string mismatch with binding doc
In the binding documentation, the compatible string is specified as
'silvaco,i3c-master-v1', but in the driver, it is defined as
'silvaco,i3c-master'.

Rename 'silvaco,i3c-master' to 'silvaco,i3c-master-v1' to ensure
compatibility with the documentation.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231017194657.3199749-1-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-03 20:02:45 +01:00
Frank Li
9aaeef113c i3c: master: svc: fix random hot join failure since timeout error
master side report:
  silvaco-i3c-master 44330000.i3c-master: Error condition: MSTATUS 0x020090c7, MERRWARN 0x00100000

BIT 20: TIMEOUT error
  The module has stalled too long in a frame. This happens when:
  - The TX FIFO or RX FIFO is not handled and the bus is stuck in the
middle of a message,
  - No STOP was issued and between messages,
  - IBI manual is used and no decision was made.
  The maximum stall period is 100 μs.

This can be considered as being just a warning as the system IRQ latency
can easily be greater than 100us.

Fixes: dd3c52846d ("i3c: master: svc: Add Silvaco I3C master driver")
Cc:  <stable@vger.kernel.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231023161658.3890811-7-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-03 19:48:17 +01:00
Frank Li
dfd7cd6aaf i3c: master: svc: fix SDA keep low when polling IBIWON timeout happen
Upon IBIWON timeout, the SDA line will always be kept low if we don't emit
a stop. Calling svc_i3c_master_emit_stop() there will let the bus return to
idle state.

Fixes: dd3c52846d ("i3c: master: svc: Add Silvaco I3C master driver")
Cc:  <stable@vger.kernel.org>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231023161658.3890811-6-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-03 19:48:17 +01:00
Frank Li
225d5ef048 i3c: master: svc: fix check wrong status register in irq handler
svc_i3c_master_irq_handler() wrongly checks register SVC_I3C_MINTMASKED. It
should be SVC_I3C_MSTATUS.

Fixes: dd3c52846d ("i3c: master: svc: Add Silvaco I3C master driver")
Cc:  <stable@vger.kernel.org>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231023161658.3890811-5-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-03 19:48:17 +01:00
Frank Li
c85e209b79 i3c: master: svc: fix ibi may not return mandatory data byte
MSTATUS[RXPEND] is only updated after the data transfer cycle started. This
creates an issue when the I3C clock is slow, and the CPU is running fast
enough that MSTATUS[RXPEND] may not be updated when the code reaches
checking point. As a result, mandatory data can be missed.

Add a wait for MSTATUS[COMPLETE] to ensure that all mandatory data is
already in FIFO. It also works without mandatory data.

Fixes: dd3c52846d ("i3c: master: svc: Add Silvaco I3C master driver")
Cc:  <stable@vger.kernel.org>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231023161658.3890811-4-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-03 19:48:17 +01:00
Frank Li
5e5e3c92e7 i3c: master: svc: fix wrong data return when IBI happen during start frame
┌─────┐     ┏──┐  ┏──┐  ┏──┐  ┏──┐  ┏──┐  ┏──┐  ┏──┐  ┏──┐  ┌─────
SCL: ┘     └─────┛  └──┛  └──┛  └──┛  └──┛  └──┛  └──┛  └──┛  └──┘
     ───┐                       ┌─────┐     ┌─────┐     ┌───────────┐
SDA:    └───────────────────────┘     └─────┘     └─────┘           └─────
     xxx╱    ╲╱                                        ╲╱    ╲╱    ╲╱    ╲
   : xxx╲IBI ╱╲               Addr(0x0a)               ╱╲ RW ╱╲NACK╱╲ S  ╱

If an In-Band Interrupt (IBI) occurs and IBI work thread is not immediately
scheduled, when svc_i3c_master_priv_xfers() initiates the I3C transfer and
attempts to send address 0x7e, the target interprets it as an
IBI handler and returns the target address 0x0a.

However, svc_i3c_master_priv_xfers() does not handle this case and proceeds
with other transfers, resulting in incorrect data being returned.

Add IBIWON check in svc_i3c_master_xfer(). In case this situation occurs,
return a failure to the driver.

Fixes: dd3c52846d ("i3c: master: svc: Add Silvaco I3C master driver")
Cc:  <stable@vger.kernel.org>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231023161658.3890811-3-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-03 19:48:17 +01:00
Frank Li
6bf3fc2681 i3c: master: svc: fix race condition in ibi work thread
The ibi work thread operates asynchronously with other transfers, such as
svc_i3c_master_priv_xfers(). Introduce mutex protection to ensure the
completion of the entire i3c/i2c transaction.

Fixes: dd3c52846d ("i3c: master: svc: Add Silvaco I3C master driver")
Cc:  <stable@vger.kernel.org>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20231023161658.3890811-2-Frank.Li@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-11-03 19:48:17 +01:00
Matt Johnston
57ec42b9a1 i3c: Fix typo "Provisional ID" to "Provisioned ID"
The MIPI I3C spec refers to a Provisioned ID, since it is (sometimes)
provisioned at device manufacturing.

Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
Acked-by: Rob Herring <robh@kernel.org>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231003075339.197099-1-matt@codeconstruct.com.au
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
2023-10-10 12:11:13 +02:00