* [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements
@ 2024-02-10 15:25 Heiner Kallweit
2024-02-10 15:27 ` [PATCH 1/3] i2c: i801: Cosmetic improvements Heiner Kallweit
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Heiner Kallweit @ 2024-02-10 15:25 UTC (permalink / raw)
To: Jean Delvare, Andi Shyti; +Cc: linux-i2c@vger.kernel.org
This series avoids a potential issue in i801_check_post () and
includes smaller, more cosmetic improvements.
Heiner Kallweit (3):
i2c: i801: Cosmetic improvements
i2c: i801: Move i801_wait_intr and i801_wait_byte_done in the code
i2c: i801: Improve too small kill wait time in i801_check_post
drivers/i2c/busses/i2c-i801.c | 125 ++++++++++++++++------------------
1 file changed, 57 insertions(+), 68 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] i2c: i801: Cosmetic improvements
2024-02-10 15:25 [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements Heiner Kallweit
@ 2024-02-10 15:27 ` Heiner Kallweit
2024-02-10 15:28 ` [PATCH 2/3] i2c: i801: Move i801_wait_intr and i801_wait_byte_done in the code Heiner Kallweit
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Heiner Kallweit @ 2024-02-10 15:27 UTC (permalink / raw)
To: Jean Delvare, Andi Shyti; +Cc: linux-i2c@vger.kernel.org
- Use pci_err et al instead of dev_err to simplify the code
- Combine an error and subsequent debug message in i801_check_post()
- use format %pr to print resource
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/i2c/busses/i2c-i801.c | 54 ++++++++++++++---------------------
1 file changed, 22 insertions(+), 32 deletions(-)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 918c794c7..4951d7d90 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -398,25 +398,22 @@ static int i801_check_post(struct i801_priv *priv, int status)
* If the SMBus is still busy, we give up
*/
if (unlikely(status < 0)) {
- dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
+ pci_err(priv->pci_dev, "Timeout, terminating transaction\n");
/* try to stop the current command */
- dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv));
usleep_range(1000, 2000);
outb_p(0, SMBHSTCNT(priv));
/* Check if it worked */
status = inb_p(SMBHSTSTS(priv));
- if ((status & SMBHSTSTS_HOST_BUSY) ||
- !(status & SMBHSTSTS_FAILED))
- dev_err(&priv->pci_dev->dev,
- "Failed terminating the transaction\n");
+ if ((status & SMBHSTSTS_HOST_BUSY) || !(status & SMBHSTSTS_FAILED))
+ pci_err(priv->pci_dev, "Failed terminating the transaction\n");
return -ETIMEDOUT;
}
if (status & SMBHSTSTS_FAILED) {
result = -EIO;
- dev_err(&priv->pci_dev->dev, "Transaction failed\n");
+ pci_err(priv->pci_dev, "Transaction failed\n");
}
if (status & SMBHSTSTS_DEV_ERR) {
/*
@@ -444,7 +441,7 @@ static int i801_check_post(struct i801_priv *priv, int status)
}
if (status & SMBHSTSTS_BUS_ERR) {
result = -EAGAIN;
- dev_dbg(&priv->pci_dev->dev, "Lost arbitration\n");
+ pci_dbg(priv->pci_dev, "Lost arbitration\n");
}
return result;
@@ -572,8 +569,7 @@ static void i801_isr_byte_done(struct i801_priv *priv)
if (priv->count < priv->len)
priv->data[priv->count++] = inb(SMBBLKDAT(priv));
else
- dev_dbg(&priv->pci_dev->dev,
- "Discarding extra byte on block read\n");
+ pci_dbg(priv->pci_dev, "Discarding extra byte on block read\n");
/* Set LAST_BYTE for last byte of read transaction */
if (priv->count == priv->len - 1)
@@ -1262,7 +1258,7 @@ static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv)
}
if (i == ARRAY_SIZE(dell_lis3lv02d_devices)) {
- dev_warn(&priv->pci_dev->dev,
+ pci_warn(priv->pci_dev,
"Accelerometer lis3lv02d is present on SMBus but its"
" address is unknown, skipping registration\n");
return;
@@ -1533,7 +1529,7 @@ static void i801_add_tco(struct i801_priv *priv)
priv->tco_pdev = i801_add_tco_spt(pci_dev, tco_res);
if (IS_ERR(priv->tco_pdev))
- dev_warn(&pci_dev->dev, "failed to create iTCO device\n");
+ pci_warn(pci_dev, "failed to create iTCO device\n");
}
#ifdef CONFIG_ACPI
@@ -1562,8 +1558,8 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) {
priv->acpi_reserved = true;
- dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");
- dev_warn(&pdev->dev, "Driver SMBus register access inhibited\n");
+ pci_warn(pdev, "BIOS is accessing SMBus registers\n");
+ pci_warn(pdev, "Driver SMBus register access inhibited\n");
/*
* BIOS is accessing the host controller so prevent it from
@@ -1644,8 +1640,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* Disable features on user request */
for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) {
if (priv->features & disable_features & (1 << i))
- dev_notice(&dev->dev, "%s disabled by user\n",
- i801_feature_names[i]);
+ pci_notice(dev, "%s disabled by user\n", i801_feature_names[i]);
}
priv->features &= ~disable_features;
@@ -1655,8 +1650,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
err = pcim_enable_device(dev);
if (err) {
- dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
- err);
+ pci_err(dev, "Failed to enable SMBus PCI device (%d)\n", err);
return err;
}
pcim_pin_device(dev);
@@ -1664,8 +1658,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* Determine the address of the SMBus area */
priv->smba = pci_resource_start(dev, SMBBAR);
if (!priv->smba) {
- dev_err(&dev->dev,
- "SMBus base address uninitialized, upgrade BIOS\n");
+ pci_err(dev, "SMBus base address uninitialized, upgrade BIOS\n");
return -ENODEV;
}
@@ -1674,26 +1667,24 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
err = pcim_iomap_regions(dev, 1 << SMBBAR, DRV_NAME);
if (err) {
- dev_err(&dev->dev,
- "Failed to request SMBus region 0x%lx-0x%Lx\n",
- priv->smba,
- (unsigned long long)pci_resource_end(dev, SMBBAR));
+ pci_err(dev, "Failed to request SMBus region %pr\n",
+ pci_resource_n(dev, SMBBAR));
i801_acpi_remove(priv);
return err;
}
- pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg);
+ pci_read_config_byte(dev, SMBHSTCFG, &priv->original_hstcfg);
i801_setup_hstcfg(priv);
if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN))
- dev_info(&dev->dev, "Enabling SMBus device\n");
+ pci_info(dev, "Enabling SMBus device\n");
if (priv->original_hstcfg & SMBHSTCFG_SMB_SMI_EN) {
- dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
+ pci_dbg(dev, "SMBus using interrupt SMI#\n");
/* Disable SMBus interrupt feature if SMBus using SMI# */
priv->features &= ~FEATURE_IRQ;
}
if (priv->original_hstcfg & SMBHSTCFG_SPD_WD)
- dev_info(&dev->dev, "SPD Write Disable is set\n");
+ pci_info(dev, "SPD Write Disable is set\n");
/* Clear special mode bits */
if (priv->features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
@@ -1712,7 +1703,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* Complain if an interrupt is already pending */
pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists);
if (pcists & PCI_STATUS_INTERRUPT)
- dev_warn(&dev->dev, "An interrupt is pending!\n");
+ pci_warn(dev, "An interrupt is pending!\n");
}
if (priv->features & FEATURE_IRQ) {
@@ -1721,12 +1712,11 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
err = devm_request_irq(&dev->dev, dev->irq, i801_isr,
IRQF_SHARED, DRV_NAME, priv);
if (err) {
- dev_err(&dev->dev, "Failed to allocate irq %d: %d\n",
- dev->irq, err);
+ pci_err(dev, "Failed to allocate irq %d: %d\n", dev->irq, err);
priv->features &= ~FEATURE_IRQ;
}
}
- dev_info(&dev->dev, "SMBus using %s\n",
+ pci_info(dev, "SMBus using %s\n",
priv->features & FEATURE_IRQ ? "PCI interrupt" : "polling");
/* Host notification uses an interrupt */
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] i2c: i801: Move i801_wait_intr and i801_wait_byte_done in the code
2024-02-10 15:25 [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements Heiner Kallweit
2024-02-10 15:27 ` [PATCH 1/3] i2c: i801: Cosmetic improvements Heiner Kallweit
@ 2024-02-10 15:28 ` Heiner Kallweit
2024-02-10 15:31 ` [PATCH 3/3] i2c: i801: Improve too small kill wait time in i801_check_post Heiner Kallweit
2025-02-12 18:53 ` [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements Andi Shyti
3 siblings, 0 replies; 5+ messages in thread
From: Heiner Kallweit @ 2024-02-10 15:28 UTC (permalink / raw)
To: Jean Delvare, Andi Shyti; +Cc: linux-i2c@vger.kernel.org
Move both functions to avoid forward declarations in a subsequent patch.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/i2c/busses/i2c-i801.c | 68 +++++++++++++++++------------------
1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 4951d7d90..751b7c6d2 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -330,6 +330,40 @@ MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n"
"\t\t 0x10 don't use interrupts\n"
"\t\t 0x20 disable SMBus Host Notify ");
+/* Wait for BUSY being cleared and either INTR or an error flag being set */
+static int i801_wait_intr(struct i801_priv *priv)
+{
+ unsigned long timeout = jiffies + priv->adapter.timeout;
+ int status, busy;
+
+ do {
+ usleep_range(250, 500);
+ status = inb_p(SMBHSTSTS(priv));
+ busy = status & SMBHSTSTS_HOST_BUSY;
+ status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR;
+ if (!busy && status)
+ return status & STATUS_ERROR_FLAGS;
+ } while (time_is_after_eq_jiffies(timeout));
+
+ return -ETIMEDOUT;
+}
+
+/* Wait for either BYTE_DONE or an error flag being set */
+static int i801_wait_byte_done(struct i801_priv *priv)
+{
+ unsigned long timeout = jiffies + priv->adapter.timeout;
+ int status;
+
+ do {
+ usleep_range(250, 500);
+ status = inb_p(SMBHSTSTS(priv));
+ if (status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE))
+ return status & STATUS_ERROR_FLAGS;
+ } while (time_is_after_eq_jiffies(timeout));
+
+ return -ETIMEDOUT;
+}
+
static int i801_get_block_len(struct i801_priv *priv)
{
u8 len = inb_p(SMBHSTDAT0(priv));
@@ -447,40 +481,6 @@ static int i801_check_post(struct i801_priv *priv, int status)
return result;
}
-/* Wait for BUSY being cleared and either INTR or an error flag being set */
-static int i801_wait_intr(struct i801_priv *priv)
-{
- unsigned long timeout = jiffies + priv->adapter.timeout;
- int status, busy;
-
- do {
- usleep_range(250, 500);
- status = inb_p(SMBHSTSTS(priv));
- busy = status & SMBHSTSTS_HOST_BUSY;
- status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR;
- if (!busy && status)
- return status & STATUS_ERROR_FLAGS;
- } while (time_is_after_eq_jiffies(timeout));
-
- return -ETIMEDOUT;
-}
-
-/* Wait for either BYTE_DONE or an error flag being set */
-static int i801_wait_byte_done(struct i801_priv *priv)
-{
- unsigned long timeout = jiffies + priv->adapter.timeout;
- int status;
-
- do {
- usleep_range(250, 500);
- status = inb_p(SMBHSTSTS(priv));
- if (status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE))
- return status & STATUS_ERROR_FLAGS;
- } while (time_is_after_eq_jiffies(timeout));
-
- return -ETIMEDOUT;
-}
-
static int i801_transaction(struct i801_priv *priv, int xact)
{
unsigned long result;
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] i2c: i801: Improve too small kill wait time in i801_check_post
2024-02-10 15:25 [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements Heiner Kallweit
2024-02-10 15:27 ` [PATCH 1/3] i2c: i801: Cosmetic improvements Heiner Kallweit
2024-02-10 15:28 ` [PATCH 2/3] i2c: i801: Move i801_wait_intr and i801_wait_byte_done in the code Heiner Kallweit
@ 2024-02-10 15:31 ` Heiner Kallweit
2025-02-12 18:53 ` [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements Andi Shyti
3 siblings, 0 replies; 5+ messages in thread
From: Heiner Kallweit @ 2024-02-10 15:31 UTC (permalink / raw)
To: Jean Delvare, Andi Shyti; +Cc: linux-i2c@vger.kernel.org
In my tests terminating a transaction took about 25ms, what is
in line with the chip-internal timeout as described in 5.21.3.2
"Bus Time Out" in [0]. Therefore the 2ms delay is too low.
Instead of a fixed delay let's use i801_wait_intr() here,
this also facilitates the status handling.
This potential issue seems to have been existing forever, but as no
related problem is known, treat it as an improvement.
[0] Intel document #326776-003, 7 Series PCH datasheet
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
drivers/i2c/busses/i2c-i801.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 751b7c6d2..5a84eb1a6 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -435,12 +435,11 @@ static int i801_check_post(struct i801_priv *priv, int status)
pci_err(priv->pci_dev, "Timeout, terminating transaction\n");
/* try to stop the current command */
outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv));
- usleep_range(1000, 2000);
+ status = i801_wait_intr(priv);
outb_p(0, SMBHSTCNT(priv));
/* Check if it worked */
- status = inb_p(SMBHSTSTS(priv));
- if ((status & SMBHSTSTS_HOST_BUSY) || !(status & SMBHSTSTS_FAILED))
+ if (status < 0 || !(status & SMBHSTSTS_FAILED))
pci_err(priv->pci_dev, "Failed terminating the transaction\n");
return -ETIMEDOUT;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements
2024-02-10 15:25 [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements Heiner Kallweit
` (2 preceding siblings ...)
2024-02-10 15:31 ` [PATCH 3/3] i2c: i801: Improve too small kill wait time in i801_check_post Heiner Kallweit
@ 2025-02-12 18:53 ` Andi Shyti
3 siblings, 0 replies; 5+ messages in thread
From: Andi Shyti @ 2025-02-12 18:53 UTC (permalink / raw)
To: Heiner Kallweit; +Cc: Jean Delvare, linux-i2c@vger.kernel.org
Hi Heiner,
On Sat, Feb 10, 2024 at 04:25:30PM +0100, Heiner Kallweit wrote:
> This series avoids a potential issue in i801_check_post () and
> includes smaller, more cosmetic improvements.
>
> Heiner Kallweit (3):
> i2c: i801: Cosmetic improvements
> i2c: i801: Move i801_wait_intr and i801_wait_byte_done in the code
> i2c: i801: Improve too small kill wait time in i801_check_post
this series went forgotten. As I'm browing through the forgotten
patches, I want to know if this is still necessary (it looks OK
to me to bring it forward).
If so, may I ask you to please rebase it on top of the latest
i2c/host as it currently doesn't apply?
Thanks,
Andi
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-02-12 18:53 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-10 15:25 [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements Heiner Kallweit
2024-02-10 15:27 ` [PATCH 1/3] i2c: i801: Cosmetic improvements Heiner Kallweit
2024-02-10 15:28 ` [PATCH 2/3] i2c: i801: Move i801_wait_intr and i801_wait_byte_done in the code Heiner Kallweit
2024-02-10 15:31 ` [PATCH 3/3] i2c: i801: Improve too small kill wait time in i801_check_post Heiner Kallweit
2025-02-12 18:53 ` [PATCH 0/3] i2c: i801: Avoid potential issue in i801_check_post and cosmetic improvements Andi Shyti
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).