Skip to content

Commit 49b162a

Browse files
author
CKI KWF Bot
committed
Merge: i2c-tegra: fix error reset
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1479 JIRA: https://issues.redhat.com/browse/RHEL-113178 resolves issues encountered while loading `ipmi-ssif` on NVIDIA Grace systems Signed-off-by: Charles Mirabile <cmirabil@redhat.com> Approved-by: Tony Camuso <tcamuso@redhat.com> Approved-by: Daniel Horak <dhorak@redhat.com> Approved-by: John W. Linville <linville@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents b198b46 + 668b30c commit 49b162a

File tree

1 file changed

+43
-23
lines changed

1 file changed

+43
-23
lines changed

drivers/i2c/busses/i2c-tegra.c

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@
134134
#define I2C_MST_FIFO_STATUS_TX GENMASK(23, 16)
135135
#define I2C_MST_FIFO_STATUS_RX GENMASK(7, 0)
136136

137+
#define I2C_MASTER_RESET_CNTRL 0x0a8
138+
137139
/* configuration load timeout in microseconds */
138140
#define I2C_CONFIG_LOAD_TIMEOUT 1000000
139141

@@ -184,6 +186,9 @@ enum msg_end_type {
184186
* @has_mst_fifo: The I2C controller contains the new MST FIFO interface that
185187
* provides additional features and allows for longer messages to
186188
* be transferred in one go.
189+
* @has_mst_reset: The I2C controller contains MASTER_RESET_CTRL register which
190+
* provides an alternative to controller reset when configured as
191+
* I2C master
187192
* @quirks: I2C adapter quirks for limiting write/read transfer size and not
188193
* allowing 0 length transfers.
189194
* @supports_bus_clear: Bus Clear support to recover from bus hang during
@@ -213,6 +218,7 @@ struct tegra_i2c_hw_feature {
213218
bool has_multi_master_mode;
214219
bool has_slcg_override_reg;
215220
bool has_mst_fifo;
221+
bool has_mst_reset;
216222
const struct i2c_adapter_quirks *quirks;
217223
bool supports_bus_clear;
218224
bool has_apb_dma;
@@ -604,13 +610,42 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
604610
return 0;
605611
}
606612

613+
static int tegra_i2c_master_reset(struct tegra_i2c_dev *i2c_dev)
614+
{
615+
if (!i2c_dev->hw->has_mst_reset)
616+
return -EOPNOTSUPP;
617+
618+
/*
619+
* Writing 1 to I2C_MASTER_RESET_CNTRL will reset all internal state of
620+
* Master logic including FIFOs. Clear this bit to 0 for normal operation.
621+
* SW needs to wait for 2us after assertion and de-assertion of this soft
622+
* reset.
623+
*/
624+
i2c_writel(i2c_dev, 0x1, I2C_MASTER_RESET_CNTRL);
625+
fsleep(2);
626+
627+
i2c_writel(i2c_dev, 0x0, I2C_MASTER_RESET_CNTRL);
628+
fsleep(2);
629+
630+
return 0;
631+
}
632+
607633
static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
608634
{
609635
u32 val, clk_divisor, clk_multiplier, tsu_thd, tlow, thigh, non_hs_mode;
610-
acpi_handle handle = ACPI_HANDLE(i2c_dev->dev);
611636
struct i2c_timings *t = &i2c_dev->timings;
612637
int err;
613638

639+
/*
640+
* Reset the controller before initializing it.
641+
* In case if device_reset() returns -ENOENT, i.e. when the reset is
642+
* not available, the internal software reset will be used if it is
643+
* supported by the controller.
644+
*/
645+
err = device_reset(i2c_dev->dev);
646+
if (err == -ENOENT)
647+
err = tegra_i2c_master_reset(i2c_dev);
648+
614649
/*
615650
* The reset shouldn't ever fail in practice. The failure will be a
616651
* sign of a severe problem that needs to be resolved. Still we don't
@@ -619,11 +654,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
619654
* emit a noisy warning on error, which won't stay unnoticed and
620655
* won't hose machine entirely.
621656
*/
622-
if (handle)
623-
err = acpi_evaluate_object(handle, "_RST", NULL, NULL);
624-
else
625-
err = reset_control_reset(i2c_dev->rst);
626-
627657
WARN_ON_ONCE(err);
628658

629659
if (IS_DVC(i2c_dev))
@@ -1472,6 +1502,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
14721502
.has_multi_master_mode = false,
14731503
.has_slcg_override_reg = false,
14741504
.has_mst_fifo = false,
1505+
.has_mst_reset = false,
14751506
.quirks = &tegra_i2c_quirks,
14761507
.supports_bus_clear = false,
14771508
.has_apb_dma = true,
@@ -1496,6 +1527,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
14961527
.has_multi_master_mode = false,
14971528
.has_slcg_override_reg = false,
14981529
.has_mst_fifo = false,
1530+
.has_mst_reset = false,
14991531
.quirks = &tegra_i2c_quirks,
15001532
.supports_bus_clear = false,
15011533
.has_apb_dma = true,
@@ -1520,6 +1552,7 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
15201552
.has_multi_master_mode = false,
15211553
.has_slcg_override_reg = false,
15221554
.has_mst_fifo = false,
1555+
.has_mst_reset = false,
15231556
.quirks = &tegra_i2c_quirks,
15241557
.supports_bus_clear = true,
15251558
.has_apb_dma = true,
@@ -1544,6 +1577,7 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
15441577
.has_multi_master_mode = false,
15451578
.has_slcg_override_reg = true,
15461579
.has_mst_fifo = false,
1580+
.has_mst_reset = false,
15471581
.quirks = &tegra_i2c_quirks,
15481582
.supports_bus_clear = true,
15491583
.has_apb_dma = true,
@@ -1568,6 +1602,7 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
15681602
.has_multi_master_mode = false,
15691603
.has_slcg_override_reg = true,
15701604
.has_mst_fifo = false,
1605+
.has_mst_reset = false,
15711606
.quirks = &tegra_i2c_quirks,
15721607
.supports_bus_clear = true,
15731608
.has_apb_dma = true,
@@ -1592,6 +1627,7 @@ static const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
15921627
.has_multi_master_mode = false,
15931628
.has_slcg_override_reg = true,
15941629
.has_mst_fifo = false,
1630+
.has_mst_reset = false,
15951631
.quirks = &tegra_i2c_quirks,
15961632
.supports_bus_clear = true,
15971633
.has_apb_dma = false,
@@ -1616,6 +1652,7 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
16161652
.has_multi_master_mode = true,
16171653
.has_slcg_override_reg = true,
16181654
.has_mst_fifo = true,
1655+
.has_mst_reset = true,
16191656
.quirks = &tegra194_i2c_quirks,
16201657
.supports_bus_clear = true,
16211658
.has_apb_dma = false,
@@ -1666,19 +1703,6 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
16661703
i2c_dev->is_vi = true;
16671704
}
16681705

1669-
static int tegra_i2c_init_reset(struct tegra_i2c_dev *i2c_dev)
1670-
{
1671-
if (ACPI_HANDLE(i2c_dev->dev))
1672-
return 0;
1673-
1674-
i2c_dev->rst = devm_reset_control_get_exclusive(i2c_dev->dev, "i2c");
1675-
if (IS_ERR(i2c_dev->rst))
1676-
return dev_err_probe(i2c_dev->dev, PTR_ERR(i2c_dev->rst),
1677-
"failed to get reset control\n");
1678-
1679-
return 0;
1680-
}
1681-
16821706
static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev)
16831707
{
16841708
int err;
@@ -1788,10 +1812,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
17881812

17891813
tegra_i2c_parse_dt(i2c_dev);
17901814

1791-
err = tegra_i2c_init_reset(i2c_dev);
1792-
if (err)
1793-
return err;
1794-
17951815
err = tegra_i2c_init_clocks(i2c_dev);
17961816
if (err)
17971817
return err;

0 commit comments

Comments
 (0)