| From afd97867f8dea1cd89320fc136fb3a09b4649732 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 31 Aug 2023 20:16:56 +0200 |
| Subject: clk: si521xx: Fix regmap write accessor |
| |
| From: Marek Vasut <marex@denx.de> |
| |
| [ Upstream commit 83df5bf010eb5ccc11ce95f2d076515ec216c99c ] |
| |
| Rework the write operation such that the Byte Count register is written with |
| a single raw i2c write outside of regmap using transfer which does specify |
| the number of bytes to be transfered, one in this case, and which makes the |
| expected subsequent write transfer look like address+register+data, and then |
| make use of this method. Without this change, the Byte Count register write |
| in probe() would succeed as it would provide the byte count as part of its |
| write payload, but any subsequent writes would fail due to this Byte Count |
| register programming. Such failing writes happens e.g. during resume, when |
| restoring the regmap content. |
| |
| Fixes: edc12763a3a2 ("clk: si521xx: Clock driver for Skyworks Si521xx I2C PCIe clock generators") |
| Signed-off-by: Marek Vasut <marex@denx.de> |
| Link: https://lore.kernel.org/r/20230831181656.154750-2-marex@denx.de |
| Signed-off-by: Stephen Boyd <sboyd@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/clk/clk-si521xx.c | 7 ++++--- |
| 1 file changed, 4 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/clk/clk-si521xx.c b/drivers/clk/clk-si521xx.c |
| index 0b9e2edbbe67c..ef4ba467e747b 100644 |
| --- a/drivers/clk/clk-si521xx.c |
| +++ b/drivers/clk/clk-si521xx.c |
| @@ -96,7 +96,7 @@ static int si521xx_regmap_i2c_write(void *context, unsigned int reg, |
| unsigned int val) |
| { |
| struct i2c_client *i2c = context; |
| - const u8 data[3] = { reg, 1, val }; |
| + const u8 data[2] = { reg, val }; |
| const int count = ARRAY_SIZE(data); |
| int ret; |
| |
| @@ -281,9 +281,10 @@ static int si521xx_probe(struct i2c_client *client) |
| { |
| const u16 chip_info = (u16)(uintptr_t)device_get_match_data(&client->dev); |
| const struct clk_parent_data clk_parent_data = { .index = 0 }; |
| - struct si521xx *si; |
| + const u8 data[3] = { SI521XX_REG_BC, 1, 1 }; |
| unsigned char name[6] = "DIFF0"; |
| struct clk_init_data init = {}; |
| + struct si521xx *si; |
| int i, ret; |
| |
| if (!chip_info) |
| @@ -308,7 +309,7 @@ static int si521xx_probe(struct i2c_client *client) |
| "Failed to allocate register map\n"); |
| |
| /* Always read back 1 Byte via I2C */ |
| - ret = regmap_write(si->regmap, SI521XX_REG_BC, 1); |
| + ret = i2c_master_send(client, data, ARRAY_SIZE(data)); |
| if (ret < 0) |
| return ret; |
| |
| -- |
| 2.40.1 |
| |