From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev,
Conor Dooley <conor.dooley@microchip.com>,
Andi Shyti <andi.shyti@kernel.org>
Subject: [PATCH 6.1 52/60] i2c: microchip-core: actually use repeated sends
Date: Mon, 30 Dec 2024 16:43:02 +0100 [thread overview]
Message-ID: <20241230154209.248926718@linuxfoundation.org> (raw)
In-Reply-To: <20241230154207.276570972@linuxfoundation.org>
6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Conor Dooley <conor.dooley@microchip.com>
commit 9a8f9320d67b27ddd7f1ee88d91820197a0e908f upstream.
At present, where repeated sends are intended to be used, the
i2c-microchip-core driver sends a stop followed by a start. Lots of i2c
devices must not malfunction in the face of this behaviour, because the
driver has operated like this for years! Try to keep track of whether or
not a repeated send is required, and suppress sending a stop in these
cases.
CC: stable@vger.kernel.org
Fixes: 64a6f1c4987e ("i2c: add support for microchip fpga i2c controllers")
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20241218-football-composure-e56df2461461@spud
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/i2c/busses/i2c-microchip-corei2c.c | 120 ++++++++++++++++++++++-------
1 file changed, 94 insertions(+), 26 deletions(-)
--- a/drivers/i2c/busses/i2c-microchip-corei2c.c
+++ b/drivers/i2c/busses/i2c-microchip-corei2c.c
@@ -93,27 +93,35 @@
* @base: pointer to register struct
* @dev: device reference
* @i2c_clk: clock reference for i2c input clock
+ * @msg_queue: pointer to the messages requiring sending
* @buf: pointer to msg buffer for easier use
* @msg_complete: xfer completion object
* @adapter: core i2c abstraction
* @msg_err: error code for completed message
* @bus_clk_rate: current i2c bus clock rate
* @isr_status: cached copy of local ISR status
+ * @total_num: total number of messages to be sent/received
+ * @current_num: index of the current message being sent/received
* @msg_len: number of bytes transferred in msg
* @addr: address of the current slave
+ * @restart_needed: whether or not a repeated start is required after current message
*/
struct mchp_corei2c_dev {
void __iomem *base;
struct device *dev;
struct clk *i2c_clk;
+ struct i2c_msg *msg_queue;
u8 *buf;
struct completion msg_complete;
struct i2c_adapter adapter;
int msg_err;
+ int total_num;
+ int current_num;
u32 bus_clk_rate;
u32 isr_status;
u16 msg_len;
u8 addr;
+ bool restart_needed;
};
static void mchp_corei2c_core_disable(struct mchp_corei2c_dev *idev)
@@ -222,6 +230,47 @@ static int mchp_corei2c_fill_tx(struct m
return 0;
}
+static void mchp_corei2c_next_msg(struct mchp_corei2c_dev *idev)
+{
+ struct i2c_msg *this_msg;
+ u8 ctrl;
+
+ if (idev->current_num >= idev->total_num) {
+ complete(&idev->msg_complete);
+ return;
+ }
+
+ /*
+ * If there's been an error, the isr needs to return control
+ * to the "main" part of the driver, so as not to keep sending
+ * messages once it completes and clears the SI bit.
+ */
+ if (idev->msg_err) {
+ complete(&idev->msg_complete);
+ return;
+ }
+
+ this_msg = idev->msg_queue++;
+
+ if (idev->current_num < (idev->total_num - 1)) {
+ struct i2c_msg *next_msg = idev->msg_queue;
+
+ idev->restart_needed = next_msg->flags & I2C_M_RD;
+ } else {
+ idev->restart_needed = false;
+ }
+
+ idev->addr = i2c_8bit_addr_from_msg(this_msg);
+ idev->msg_len = this_msg->len;
+ idev->buf = this_msg->buf;
+
+ ctrl = readb(idev->base + CORE_I2C_CTRL);
+ ctrl |= CTRL_STA;
+ writeb(ctrl, idev->base + CORE_I2C_CTRL);
+
+ idev->current_num++;
+}
+
static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
{
u32 status = idev->isr_status;
@@ -247,10 +296,14 @@ static irqreturn_t mchp_corei2c_handle_i
break;
case STATUS_M_SLAW_ACK:
case STATUS_M_TX_DATA_ACK:
- if (idev->msg_len > 0)
+ if (idev->msg_len > 0) {
mchp_corei2c_fill_tx(idev);
- else
- last_byte = true;
+ } else {
+ if (idev->restart_needed)
+ finished = true;
+ else
+ last_byte = true;
+ }
break;
case STATUS_M_TX_DATA_NACK:
case STATUS_M_SLAR_NACK:
@@ -287,7 +340,7 @@ static irqreturn_t mchp_corei2c_handle_i
mchp_corei2c_stop(idev);
if (last_byte || finished)
- complete(&idev->msg_complete);
+ mchp_corei2c_next_msg(idev);
return IRQ_HANDLED;
}
@@ -311,21 +364,48 @@ static irqreturn_t mchp_corei2c_isr(int
return ret;
}
-static int mchp_corei2c_xfer_msg(struct mchp_corei2c_dev *idev,
- struct i2c_msg *msg)
+static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
{
- u8 ctrl;
+ struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap);
+ struct i2c_msg *this_msg = msgs;
unsigned long time_left;
+ u8 ctrl;
- idev->addr = i2c_8bit_addr_from_msg(msg);
- idev->msg_len = msg->len;
- idev->buf = msg->buf;
+ mchp_corei2c_core_enable(idev);
+
+ /*
+ * The isr controls the flow of a transfer, this info needs to be saved
+ * to a location that it can access the queue information from.
+ */
+ idev->restart_needed = false;
+ idev->msg_queue = msgs;
+ idev->total_num = num;
+ idev->current_num = 0;
+
+ /*
+ * But the first entry to the isr is triggered by the start in this
+ * function, so the first message needs to be "dequeued".
+ */
+ idev->addr = i2c_8bit_addr_from_msg(this_msg);
+ idev->msg_len = this_msg->len;
+ idev->buf = this_msg->buf;
idev->msg_err = 0;
- reinit_completion(&idev->msg_complete);
+ if (idev->total_num > 1) {
+ struct i2c_msg *next_msg = msgs + 1;
- mchp_corei2c_core_enable(idev);
+ idev->restart_needed = next_msg->flags & I2C_M_RD;
+ }
+ idev->current_num++;
+ idev->msg_queue++;
+
+ reinit_completion(&idev->msg_complete);
+
+ /*
+ * Send the first start to pass control to the isr
+ */
ctrl = readb(idev->base + CORE_I2C_CTRL);
ctrl |= CTRL_STA;
writeb(ctrl, idev->base + CORE_I2C_CTRL);
@@ -335,20 +415,8 @@ static int mchp_corei2c_xfer_msg(struct
if (!time_left)
return -ETIMEDOUT;
- return idev->msg_err;
-}
-
-static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
- int num)
-{
- struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap);
- int i, ret;
-
- for (i = 0; i < num; i++) {
- ret = mchp_corei2c_xfer_msg(idev, msgs++);
- if (ret)
- return ret;
- }
+ if (idev->msg_err)
+ return idev->msg_err;
return num;
}
next prev parent reply other threads:[~2024-12-30 15:47 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-30 15:42 [PATCH 6.1 00/60] 6.1.123-rc1 review Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 01/60] media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 02/60] mm/vmstat: fix a W=1 clang compiler warning Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 03/60] tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress() Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 04/60] tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 05/60] bpf: Check negative offsets in __bpf_skb_min_len() Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 06/60] nfsd: restore callback functionality for NFSv4.0 Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 07/60] mtd: diskonchip: Cast an operand to prevent potential overflow Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 08/60] mtd: rawnand: arasan: Fix double assertion of chip-select Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 09/60] mtd: rawnand: arasan: Fix missing de-registration of NAND Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 10/60] phy: qcom-qmp: Fix register name in RX Lane config of SC8280XP Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 11/60] phy: core: Fix an OF node refcount leakage in _of_phy_get() Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 12/60] phy: core: Fix an OF node refcount leakage in of_phy_provider_lookup() Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 13/60] phy: core: Fix that API devm_phy_put() fails to release the phy Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 14/60] phy: core: Fix that API devm_of_phy_provider_unregister() fails to unregister the phy provider Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 15/60] phy: core: Fix that API devm_phy_destroy() fails to destroy the phy Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 16/60] phy: usb: Toggle the PHY power during init Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 17/60] phy: rockchip: naneng-combphy: fix phy reset Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 18/60] dmaengine: mv_xor: fix child node refcount handling in early exit Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 19/60] dmaengine: dw: Select only supported masters for ACPI devices Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 20/60] dmaengine: tegra: Return correct DMA status when paused Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 21/60] dmaengine: apple-admac: Avoid accessing registers in probe Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 22/60] dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 23/60] mtd: rawnand: fix double free in atmel_pmecc_create_user() Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 24/60] powerpc/pseries/vas: Add close() callback in vas_vm_ops struct Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 25/60] stddef: make __struct_group() UAPI C++-friendly Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 26/60] tracing/kprobe: Make trace_kprobes module callback called after jump_label update Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 27/60] watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04 Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 28/60] scsi: qla1280: Fix hw revision numbering for ISP1020/1040 Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 29/60] scsi: megaraid_sas: Fix for a potential deadlock Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 30/60] ALSA: hda/conexant: fix Z60MR100 startup pop issue Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 31/60] smb: server: Fix building with GCC 15 Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 32/60] regmap: Use correct format specifier for logging range errors Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 33/60] platform/x86: asus-nb-wmi: Ignore unknown event 0xCF Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 34/60] scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load time Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 35/60] scsi: storvsc: Do not flag MAINTENANCE_IN return of SRB_STATUS_DATA_OVERRUN as an error Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 36/60] drm/dp_mst: Ensure mst_primary pointer is valid in drm_dp_mst_handle_up_req() Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 37/60] virtio-blk: dont keep queue frozen during system suspend Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 38/60] blk-mq: register cpuhp callback after hctx is added to xarray table Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 39/60] vmalloc: fix accounting with i915 Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 40/60] MIPS: Probe toolchain support of -msym32 Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 41/60] MIPS: mipsregs: Set proper ISA level for virt extensions Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 42/60] net/mlx5e: Dont call cleanup on profile rollback failure Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 43/60] bpf: Check validity of link->type in bpf_link_show_fdinfo() Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 44/60] ALSA: hda/realtek: fix mute/micmute LEDs dont work for EliteBook X G1i Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 45/60] ALSA: hda/realtek: fix micmute LEDs dont work on HP Laptops Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 46/60] pmdomain: core: Add missing put_device() Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 47/60] sched/core: Report correct state for TASK_IDLE | TASK_FREEZABLE Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 48/60] freezer, sched: Report frozen tasks as D instead of R Greg Kroah-Hartman
2024-12-30 15:42 ` [PATCH 6.1 49/60] tracing: Constify string literal data member in struct trace_event_call Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 50/60] tracing: Prevent bad count for tracing_cpumask_write Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 51/60] io_uring/sqpoll: fix sqpoll error handling races Greg Kroah-Hartman
2024-12-30 15:43 ` Greg Kroah-Hartman [this message]
2024-12-30 15:43 ` [PATCH 6.1 53/60] i2c: imx: add imx7d compatible string for applying erratum ERR007805 Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 54/60] i2c: microchip-core: fix "ghost" detections Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 55/60] power: supply: gpio-charger: Fix set charge current limits Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 56/60] btrfs: avoid monopolizing a core when activating a swap file Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 57/60] btrfs: sysfs: fix direct super block member reads Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 58/60] nfsd: cancel nfsd_shrinker_work using sync mode in nfs4_state_shutdown_net Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 59/60] Revert "rcu-tasks: Fix access non-existent percpu rtpcp variable in rcu_tasks_need_gpcb()" Greg Kroah-Hartman
2024-12-30 15:43 ` [PATCH 6.1 60/60] ALSA: hda/realtek: Fix spelling mistake "Firelfy" -> "Firefly" Greg Kroah-Hartman
2024-12-30 17:39 ` [PATCH 6.1 00/60] 6.1.123-rc1 review Florian Fainelli
2024-12-30 19:28 ` Pavel Machek
2024-12-30 20:59 ` Shuah Khan
2024-12-31 8:23 ` Muhammad Usama Anjum
2024-12-31 9:44 ` Naresh Kamboju
2024-12-31 22:38 ` [PATCH 6.1] " Hardik Garg
2024-12-31 23:00 ` [PATCH 6.1 00/60] " Ron Economos
2025-01-02 10:42 ` Pavel Machek
[not found] ` <2025010357-laziness-shield-0ad0@gregkh>
2025-01-04 17:54 ` Buggy patch -- " Pavel Machek
2025-01-06 10:04 ` Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241230154209.248926718@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=andi.shyti@kernel.org \
--cc=conor.dooley@microchip.com \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox