Skip to content

Commit efb2ad8

Browse files
author
Wolfram Sang
committed
Merge tag 'i2c-host-6.17-pt2' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux into i2c/for-mergewindow
i2c-host for v6.17, part 2 - apple: add support for Apple A7–A11, T2 chips - qcom-geni: fix controller frequency mapping - stm32f7: add DMA-safe transfer support - tegra: use controller reset if device reset is missing - tegra: remove unnecessary dma_sync*() calls
2 parents 186f3ed + 85c3453 commit efb2ad8

File tree

4 files changed

+73
-34
lines changed

4 files changed

+73
-34
lines changed

Documentation/devicetree/bindings/i2c/apple,i2c.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ properties:
2222
compatible:
2323
items:
2424
- enum:
25+
- apple,s5l8960x-i2c
26+
- apple,t7000-i2c
27+
- apple,s8000-i2c
28+
- apple,t8010-i2c
29+
- apple,t8015-i2c
2530
- apple,t8103-i2c
2631
- apple,t8112-i2c
2732
- apple,t6000-i2c

drivers/i2c/busses/i2c-qcom-geni.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@ static const struct geni_i2c_clk_fld geni_i2c_clk_map_19p2mhz[] = {
155155

156156
/* source_clock = 32 MHz */
157157
static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz[] = {
158-
{ I2C_MAX_STANDARD_MODE_FREQ, 8, 14, 18, 40 },
159-
{ I2C_MAX_FAST_MODE_FREQ, 4, 3, 11, 20 },
160-
{ I2C_MAX_FAST_MODE_PLUS_FREQ, 2, 3, 6, 15 },
158+
{ I2C_MAX_STANDARD_MODE_FREQ, 8, 14, 18, 38 },
159+
{ I2C_MAX_FAST_MODE_FREQ, 4, 3, 9, 19 },
160+
{ I2C_MAX_FAST_MODE_PLUS_FREQ, 2, 3, 5, 15 },
161161
{}
162162
};
163163

drivers/i2c/busses/i2c-stm32f7.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -742,11 +742,14 @@ static void stm32f7_i2c_dma_callback(void *arg)
742742
{
743743
struct stm32f7_i2c_dev *i2c_dev = arg;
744744
struct stm32_i2c_dma *dma = i2c_dev->dma;
745+
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
745746

746747
stm32f7_i2c_disable_dma_req(i2c_dev);
747748
dmaengine_terminate_async(dma->chan_using);
748749
dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len,
749750
dma->dma_data_dir);
751+
if (!f7_msg->smbus)
752+
i2c_put_dma_safe_msg_buf(f7_msg->buf, i2c_dev->msg, true);
750753
complete(&dma->dma_complete);
751754
}
752755

@@ -882,6 +885,7 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
882885
{
883886
struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
884887
void __iomem *base = i2c_dev->base;
888+
u8 *dma_buf;
885889
u32 cr1, cr2;
886890
int ret;
887891

@@ -931,17 +935,23 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
931935

932936
/* Configure DMA or enable RX/TX interrupt */
933937
i2c_dev->use_dma = false;
934-
if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN
935-
&& !i2c_dev->atomic) {
936-
ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
937-
msg->flags & I2C_M_RD,
938-
f7_msg->count, f7_msg->buf,
939-
stm32f7_i2c_dma_callback,
940-
i2c_dev);
941-
if (!ret)
942-
i2c_dev->use_dma = true;
943-
else
944-
dev_warn(i2c_dev->dev, "can't use DMA\n");
938+
if (i2c_dev->dma && !i2c_dev->atomic) {
939+
dma_buf = i2c_get_dma_safe_msg_buf(msg, STM32F7_I2C_DMA_LEN_MIN);
940+
if (dma_buf) {
941+
f7_msg->buf = dma_buf;
942+
ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
943+
msg->flags & I2C_M_RD,
944+
f7_msg->count, f7_msg->buf,
945+
stm32f7_i2c_dma_callback,
946+
i2c_dev);
947+
if (ret) {
948+
dev_warn(i2c_dev->dev, "can't use DMA\n");
949+
i2c_put_dma_safe_msg_buf(f7_msg->buf, msg, false);
950+
f7_msg->buf = msg->buf;
951+
} else {
952+
i2c_dev->use_dma = true;
953+
}
954+
}
945955
}
946956

947957
if (!i2c_dev->use_dma) {

drivers/i2c/busses/i2c-tegra.c

Lines changed: 44 additions & 20 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;
@@ -605,12 +611,42 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
605611
return 0;
606612
}
607613

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

640+
/*
641+
* Reset the controller before initializing it.
642+
* In case if device_reset() returns -ENOENT, i.e. when the reset is
643+
* not available, the internal software reset will be used if it is
644+
* supported by the controller.
645+
*/
646+
err = device_reset(i2c_dev->dev);
647+
if (err == -ENOENT)
648+
err = tegra_i2c_master_reset(i2c_dev);
649+
614650
/*
615651
* The reset shouldn't ever fail in practice. The failure will be a
616652
* sign of a severe problem that needs to be resolved. Still we don't
@@ -619,7 +655,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
619655
* emit a noisy warning on error, which won't stay unnoticed and
620656
* won't hose machine entirely.
621657
*/
622-
err = device_reset(i2c_dev->dev);
623658
WARN_ON_ONCE(err);
624659

625660
if (IS_DVC(i2c_dev))
@@ -1266,17 +1301,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
12661301

12671302
if (i2c_dev->dma_mode) {
12681303
if (i2c_dev->msg_read) {
1269-
dma_sync_single_for_device(i2c_dev->dma_dev,
1270-
i2c_dev->dma_phys,
1271-
xfer_size, DMA_FROM_DEVICE);
1272-
12731304
err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
12741305
if (err)
12751306
return err;
1276-
} else {
1277-
dma_sync_single_for_cpu(i2c_dev->dma_dev,
1278-
i2c_dev->dma_phys,
1279-
xfer_size, DMA_TO_DEVICE);
12801307
}
12811308
}
12821309

@@ -1286,11 +1313,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
12861313
if (i2c_dev->dma_mode) {
12871314
memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
12881315
msg->buf, i2c_dev->msg_len);
1289-
1290-
dma_sync_single_for_device(i2c_dev->dma_dev,
1291-
i2c_dev->dma_phys,
1292-
xfer_size, DMA_TO_DEVICE);
1293-
12941316
err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
12951317
if (err)
12961318
return err;
@@ -1331,13 +1353,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
13311353
return -ETIMEDOUT;
13321354
}
13331355

1334-
if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) {
1335-
dma_sync_single_for_cpu(i2c_dev->dma_dev,
1336-
i2c_dev->dma_phys,
1337-
xfer_size, DMA_FROM_DEVICE);
1338-
1356+
if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE)
13391357
memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
1340-
}
13411358
}
13421359

13431360
time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete,
@@ -1468,6 +1485,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
14681485
.has_multi_master_mode = false,
14691486
.has_slcg_override_reg = false,
14701487
.has_mst_fifo = false,
1488+
.has_mst_reset = false,
14711489
.quirks = &tegra_i2c_quirks,
14721490
.supports_bus_clear = false,
14731491
.has_apb_dma = true,
@@ -1492,6 +1510,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
14921510
.has_multi_master_mode = false,
14931511
.has_slcg_override_reg = false,
14941512
.has_mst_fifo = false,
1513+
.has_mst_reset = false,
14951514
.quirks = &tegra_i2c_quirks,
14961515
.supports_bus_clear = false,
14971516
.has_apb_dma = true,
@@ -1516,6 +1535,7 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
15161535
.has_multi_master_mode = false,
15171536
.has_slcg_override_reg = false,
15181537
.has_mst_fifo = false,
1538+
.has_mst_reset = false,
15191539
.quirks = &tegra_i2c_quirks,
15201540
.supports_bus_clear = true,
15211541
.has_apb_dma = true,
@@ -1540,6 +1560,7 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
15401560
.has_multi_master_mode = false,
15411561
.has_slcg_override_reg = true,
15421562
.has_mst_fifo = false,
1563+
.has_mst_reset = false,
15431564
.quirks = &tegra_i2c_quirks,
15441565
.supports_bus_clear = true,
15451566
.has_apb_dma = true,
@@ -1564,6 +1585,7 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
15641585
.has_multi_master_mode = false,
15651586
.has_slcg_override_reg = true,
15661587
.has_mst_fifo = false,
1588+
.has_mst_reset = false,
15671589
.quirks = &tegra_i2c_quirks,
15681590
.supports_bus_clear = true,
15691591
.has_apb_dma = true,
@@ -1588,6 +1610,7 @@ static const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
15881610
.has_multi_master_mode = false,
15891611
.has_slcg_override_reg = true,
15901612
.has_mst_fifo = false,
1613+
.has_mst_reset = false,
15911614
.quirks = &tegra_i2c_quirks,
15921615
.supports_bus_clear = true,
15931616
.has_apb_dma = false,
@@ -1612,6 +1635,7 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
16121635
.has_multi_master_mode = true,
16131636
.has_slcg_override_reg = true,
16141637
.has_mst_fifo = true,
1638+
.has_mst_reset = true,
16151639
.quirks = &tegra194_i2c_quirks,
16161640
.supports_bus_clear = true,
16171641
.has_apb_dma = false,

0 commit comments

Comments
 (0)