mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
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 commit0676bfebf5
("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>
This commit is contained in:
parent
9bc7501b0b
commit
be90ae1ba1
@ -631,6 +631,7 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id)
|
||||
static int i3c_hci_init(struct i3c_hci *hci)
|
||||
{
|
||||
u32 regval, offset;
|
||||
bool size_in_dwords;
|
||||
int ret;
|
||||
|
||||
/* Validate HCI hardware version */
|
||||
@ -654,11 +655,16 @@ static int i3c_hci_init(struct i3c_hci *hci)
|
||||
hci->caps = reg_read(HC_CAPABILITIES);
|
||||
DBG("caps = %#x", hci->caps);
|
||||
|
||||
size_in_dwords = hci->version_major < 1 ||
|
||||
(hci->version_major == 1 && hci->version_minor < 1);
|
||||
|
||||
regval = reg_read(DAT_SECTION);
|
||||
offset = FIELD_GET(DAT_TABLE_OFFSET, regval);
|
||||
hci->DAT_regs = offset ? hci->base_regs + offset : NULL;
|
||||
hci->DAT_entries = FIELD_GET(DAT_TABLE_SIZE, regval);
|
||||
hci->DAT_entry_size = FIELD_GET(DAT_ENTRY_SIZE, regval) ? 0 : 8;
|
||||
if (size_in_dwords)
|
||||
hci->DAT_entries = 4 * hci->DAT_entries / hci->DAT_entry_size;
|
||||
dev_info(&hci->master.dev, "DAT: %u %u-bytes entries at offset %#x\n",
|
||||
hci->DAT_entries, hci->DAT_entry_size, offset);
|
||||
|
||||
@ -667,6 +673,8 @@ static int i3c_hci_init(struct i3c_hci *hci)
|
||||
hci->DCT_regs = offset ? hci->base_regs + offset : NULL;
|
||||
hci->DCT_entries = FIELD_GET(DCT_TABLE_SIZE, regval);
|
||||
hci->DCT_entry_size = FIELD_GET(DCT_ENTRY_SIZE, regval) ? 0 : 16;
|
||||
if (size_in_dwords)
|
||||
hci->DCT_entries = 4 * hci->DCT_entries / hci->DCT_entry_size;
|
||||
dev_info(&hci->master.dev, "DCT: %u %u-bytes entries at offset %#x\n",
|
||||
hci->DCT_entries, hci->DCT_entry_size, offset);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user