Skip to content

Commit a095e26

Browse files
author
CKI KWF Bot
committed
Merge: i2c-tegra: fix error reset
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7382 JIRA: https://issues.redhat.com/browse/RHEL-113177 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 7cfcf74 + a52365f commit a095e26

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))
@@ -1474,6 +1504,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
14741504
.has_multi_master_mode = false,
14751505
.has_slcg_override_reg = false,
14761506
.has_mst_fifo = false,
1507+
.has_mst_reset = false,
14771508
.quirks = &tegra_i2c_quirks,
14781509
.supports_bus_clear = false,
14791510
.has_apb_dma = true,
@@ -1498,6 +1529,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
14981529
.has_multi_master_mode = false,
14991530
.has_slcg_override_reg = false,
15001531
.has_mst_fifo = false,
1532+
.has_mst_reset = false,
15011533
.quirks = &tegra_i2c_quirks,
15021534
.supports_bus_clear = false,
15031535
.has_apb_dma = true,
@@ -1522,6 +1554,7 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
15221554
.has_multi_master_mode = false,
15231555
.has_slcg_override_reg = false,
15241556
.has_mst_fifo = false,
1557+
.has_mst_reset = false,
15251558
.quirks = &tegra_i2c_quirks,
15261559
.supports_bus_clear = true,
15271560
.has_apb_dma = true,
@@ -1546,6 +1579,7 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
15461579
.has_multi_master_mode = false,
15471580
.has_slcg_override_reg = true,
15481581
.has_mst_fifo = false,
1582+
.has_mst_reset = false,
15491583
.quirks = &tegra_i2c_quirks,
15501584
.supports_bus_clear = true,
15511585
.has_apb_dma = true,
@@ -1570,6 +1604,7 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
15701604
.has_multi_master_mode = false,
15711605
.has_slcg_override_reg = true,
15721606
.has_mst_fifo = false,
1607+
.has_mst_reset = false,
15731608
.quirks = &tegra_i2c_quirks,
15741609
.supports_bus_clear = true,
15751610
.has_apb_dma = true,
@@ -1594,6 +1629,7 @@ static const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
15941629
.has_multi_master_mode = false,
15951630
.has_slcg_override_reg = true,
15961631
.has_mst_fifo = false,
1632+
.has_mst_reset = false,
15971633
.quirks = &tegra_i2c_quirks,
15981634
.supports_bus_clear = true,
15991635
.has_apb_dma = false,
@@ -1618,6 +1654,7 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
16181654
.has_multi_master_mode = true,
16191655
.has_slcg_override_reg = true,
16201656
.has_mst_fifo = true,
1657+
.has_mst_reset = true,
16211658
.quirks = &tegra194_i2c_quirks,
16221659
.supports_bus_clear = true,
16231660
.has_apb_dma = false,
@@ -1668,19 +1705,6 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
16681705
i2c_dev->is_vi = true;
16691706
}
16701707

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

17911815
tegra_i2c_parse_dt(i2c_dev);
17921816

1793-
err = tegra_i2c_init_reset(i2c_dev);
1794-
if (err)
1795-
return err;
1796-
17971817
err = tegra_i2c_init_clocks(i2c_dev);
17981818
if (err)
17991819
return err;

0 commit comments

Comments
 (0)