From 469668a58b68933ca48f616325be09685407adcb Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Thu, 29 Apr 2021 16:11:42 +0800 Subject: dt-bindings: i2c: i2c-rk3x: add description for rk3568 add "rockchip,rk3568-i2c", "rockchip,rk3399-i2c" for i2c nodes on a rk3568 platform to i2c-rk3x.yaml. Signed-off-by: Liang Chen Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml b/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml index 7f254d79558c..5339dd4fc370 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-rk3x.yaml @@ -36,6 +36,7 @@ properties: - rockchip,px30-i2c - rockchip,rk3308-i2c - rockchip,rk3328-i2c + - rockchip,rk3568-i2c - const: rockchip,rk3399-i2c reg: -- cgit From e653312b5b77d758796f90bb602068068ca1afa2 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Thu, 13 May 2021 13:55:17 -0400 Subject: i2c: qcom-cci: add sm8250 compatible SM8250 CCI is the same as SDM845, add an equivalent compatible for SM8250. Signed-off-by: Jonathan Marek Reviewed-by: Loic Poulain Reviewed-by: Vinod Koul Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt | 5 +++-- drivers/i2c/busses/i2c-qcom-cci.c | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt b/Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt index c6668b7c66e6..7b9fc0c22eaf 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt @@ -9,6 +9,7 @@ PROPERTIES: "qcom,msm8916-cci" "qcom,msm8996-cci" "qcom,sdm845-cci" + "qcom,sm8250-cci" - reg Usage: required @@ -41,8 +42,8 @@ PROPERTIES: SUBNODES: -The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996 and -sdm845), described as subdevices named "i2c-bus@0" and "i2c-bus@1". +The CCI provides I2C masters for one (msm8916) or two i2c busses (msm8996, +sdm845 and sm8250), described as subdevices named "i2c-bus@0" and "i2c-bus@1". PROPERTIES: diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index c63d5545fc2a..c1de8eb66169 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -769,6 +769,7 @@ static const struct of_device_id cci_dt_match[] = { { .compatible = "qcom,msm8916-cci", .data = &cci_v1_data}, { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data}, { .compatible = "qcom,sdm845-cci", .data = &cci_v2_data}, + { .compatible = "qcom,sm8250-cci", .data = &cci_v2_data}, {} }; MODULE_DEVICE_TABLE(of, cci_dt_match); -- cgit From 168290fb26757d3f9732a466c59a5c45a01974f9 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Wed, 5 May 2021 15:14:38 +0200 Subject: i2c: add binding to mark a bus as supporting SMBus-Alert Since SMBus-Alert is an optional feature of SMBUS which requires an additional pin, the smbus binding cannot be used to indicate its support. Add an additional smbus-alert binding specific for it and update the description text of smbus to avoid mentioning SMBus-Alert Signed-off-by: Alain Volmat Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt index df41f72afc87..b864916e087f 100644 --- a/Documentation/devicetree/bindings/i2c/i2c.txt +++ b/Documentation/devicetree/bindings/i2c/i2c.txt @@ -89,8 +89,11 @@ wants to support one of the below features, it should adapt these bindings. - smbus states that additional SMBus restrictions and features apply to this bus. - Examples of features are SMBusHostNotify and SMBusAlert. Examples of - restrictions are more reserved addresses and timeout definitions. + An example of feature is SMBusHostNotify. Examples of restrictions are + more reserved addresses and timeout definitions. + +- smbus-alert + states that the optional SMBus-Alert feature apply to this bus. Required properties (per child device) -------------------------------------- -- cgit From c8062d11e20c218b310145bc918e116423fb1e83 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Wed, 5 May 2021 15:14:39 +0200 Subject: i2c: stm32f7: add SMBus-Alert support Add support for the SMBus-Alert protocol to the STM32F7 that has dedicated control and status logic. If SMBus-Alert is used, the SMBALERT# pin must be configured as alternate function for I2C Alert. Signed-off-by: Alain Volmat Reviewed-by: Pierre-Yves MORDRET Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-stm32f7.c | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 0138317ea600..b9b19a2a2ffa 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -51,6 +51,7 @@ /* STM32F7 I2C control 1 */ #define STM32F7_I2C_CR1_PECEN BIT(23) +#define STM32F7_I2C_CR1_ALERTEN BIT(22) #define STM32F7_I2C_CR1_SMBHEN BIT(20) #define STM32F7_I2C_CR1_WUPEN BIT(18) #define STM32F7_I2C_CR1_SBC BIT(16) @@ -125,6 +126,7 @@ (((n) & STM32F7_I2C_ISR_ADDCODE_MASK) >> 17) #define STM32F7_I2C_ISR_DIR BIT(16) #define STM32F7_I2C_ISR_BUSY BIT(15) +#define STM32F7_I2C_ISR_ALERT BIT(13) #define STM32F7_I2C_ISR_PECERR BIT(11) #define STM32F7_I2C_ISR_ARLO BIT(9) #define STM32F7_I2C_ISR_BERR BIT(8) @@ -138,6 +140,7 @@ #define STM32F7_I2C_ISR_TXE BIT(0) /* STM32F7 I2C Interrupt Clear */ +#define STM32F7_I2C_ICR_ALERTCF BIT(13) #define STM32F7_I2C_ICR_PECCF BIT(11) #define STM32F7_I2C_ICR_ARLOCF BIT(9) #define STM32F7_I2C_ICR_BERRCF BIT(8) @@ -278,6 +281,17 @@ struct stm32f7_i2c_msg { u8 smbus_buf[I2C_SMBUS_BLOCK_MAX + 3] __aligned(4); }; +/** + * struct stm32f7_i2c_alert - SMBus alert specific data + * @setup: platform data for the smbus_alert i2c client + * @ara: I2C slave device used to respond to the SMBus Alert with Alert + * Response Address + */ +struct stm32f7_i2c_alert { + struct i2c_smbus_alert_setup setup; + struct i2c_client *ara; +}; + /** * struct stm32f7_i2c_dev - private data of the controller * @adap: I2C adapter for this controller @@ -310,6 +324,7 @@ struct stm32f7_i2c_msg { * @analog_filter: boolean to indicate enabling of the analog filter * @dnf_dt: value of digital filter requested via dt * @dnf: value of digital filter to apply + * @alert: SMBus alert specific data */ struct stm32f7_i2c_dev { struct i2c_adapter adap; @@ -341,6 +356,7 @@ struct stm32f7_i2c_dev { bool analog_filter; u32 dnf_dt; u32 dnf; + struct stm32f7_i2c_alert *alert; }; /* @@ -1624,6 +1640,13 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) f7_msg->result = -EINVAL; } + if (status & STM32F7_I2C_ISR_ALERT) { + dev_dbg(dev, "<%s>: SMBus alert received\n", __func__); + writel_relaxed(STM32F7_I2C_ICR_ALERTCF, base + STM32F7_I2C_ICR); + i2c_handle_smbus_alert(i2c_dev->alert->ara); + return IRQ_HANDLED; + } + if (!i2c_dev->slave_running) { u32 mask; /* Disable interrupts */ @@ -1990,6 +2013,42 @@ static void stm32f7_i2c_disable_smbus_host(struct stm32f7_i2c_dev *i2c_dev) } } +static int stm32f7_i2c_enable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev) +{ + struct stm32f7_i2c_alert *alert; + struct i2c_adapter *adap = &i2c_dev->adap; + struct device *dev = i2c_dev->dev; + void __iomem *base = i2c_dev->base; + + alert = devm_kzalloc(dev, sizeof(*alert), GFP_KERNEL); + if (!alert) + return -ENOMEM; + + alert->ara = i2c_new_smbus_alert_device(adap, &alert->setup); + if (IS_ERR(alert->ara)) + return PTR_ERR(alert->ara); + + i2c_dev->alert = alert; + + /* Enable SMBus Alert */ + stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_ALERTEN); + + return 0; +} + +static void stm32f7_i2c_disable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev) +{ + struct stm32f7_i2c_alert *alert = i2c_dev->alert; + void __iomem *base = i2c_dev->base; + + if (alert) { + /* Disable SMBus Alert */ + stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1, + STM32F7_I2C_CR1_ALERTEN); + i2c_unregister_device(alert->ara); + } +} + static u32 stm32f7_i2c_func(struct i2c_adapter *adap) { struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adap); @@ -2173,6 +2232,16 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) } } + if (of_property_read_bool(pdev->dev.of_node, "smbus-alert")) { + ret = stm32f7_i2c_enable_smbus_alert(i2c_dev); + if (ret) { + dev_err(i2c_dev->dev, + "failed to enable SMBus alert protocol (%d)\n", + ret); + goto i2c_disable_smbus_host; + } + } + dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr); pm_runtime_mark_last_busy(i2c_dev->dev); @@ -2180,6 +2249,9 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) return 0; +i2c_disable_smbus_host: + stm32f7_i2c_disable_smbus_host(i2c_dev); + i2c_adapter_remove: i2c_del_adapter(adap); @@ -2214,6 +2286,7 @@ static int stm32f7_i2c_remove(struct platform_device *pdev) { struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev); + stm32f7_i2c_disable_smbus_alert(i2c_dev); stm32f7_i2c_disable_smbus_host(i2c_dev); i2c_del_adapter(&i2c_dev->adap); -- cgit From 3fb2e2aeafb2d28e49d9c069ac392dabe595b1ae Mon Sep 17 00:00:00 2001 From: Zev Weiss Date: Thu, 6 May 2021 15:54:19 -0500 Subject: i2c: aspeed: disable additional device addresses on ast2[56]xx The ast25xx and ast26xx have, respectively, two and three configurable slave device addresses to the ast24xx's one. We only support using one at a time, but the others may come up in an indeterminate state depending on hardware/bootloader behavior, so we need to make sure we disable them so as to avoid ending up with phantom devices on the bus. Signed-off-by: Zev Weiss Reviewed-by: Brendan Higgins Reviewed-by: Joel Stanley Tested-by: Joel Stanley Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-aspeed.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index 724bf30600d6..67e8b97c0c95 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -727,10 +727,14 @@ static void __aspeed_i2c_reg_slave(struct aspeed_i2c_bus *bus, u16 slave_addr) { u32 addr_reg_val, func_ctrl_reg_val; - /* Set slave addr. */ - addr_reg_val = readl(bus->base + ASPEED_I2C_DEV_ADDR_REG); - addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR_MASK; - addr_reg_val |= slave_addr & ASPEED_I2CD_DEV_ADDR_MASK; + /* + * Set slave addr. Reserved bits can all safely be written with zeros + * on all of ast2[456]00, so zero everything else to ensure we only + * enable a single slave address (ast2500 has two, ast2600 has three, + * the enable bits for which are also in this register) so that we don't + * end up with additional phantom devices responding on the bus. + */ + addr_reg_val = slave_addr & ASPEED_I2CD_DEV_ADDR_MASK; writel(addr_reg_val, bus->base + ASPEED_I2C_DEV_ADDR_REG); /* Turn on slave mode. */ -- cgit From 78f420acc4231f7db99291d846bc73d5f8a8df72 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 22 May 2021 00:00:28 +0200 Subject: i2c: i801: Remove unneeded warning after wait_event_timeout timeout When passing -ETIMEDOUT to i801_check_post() it will emit a timeout error message. I don't see much benefit in an additional warning stating more or less the same. Signed-off-by: Heiner Kallweit Reviewed-by: Jean Delvare Tested-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 99d446763530..bfea94d02775 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -509,11 +509,9 @@ static int i801_transaction(struct i801_priv *priv, int xact) result = wait_event_timeout(priv->waitq, (status = priv->status), adap->timeout); - if (!result) { + if (!result) status = -ETIMEDOUT; - dev_warn(&priv->pci_dev->dev, - "Timeout waiting for interrupt!\n"); - } + priv->status = 0; return i801_check_post(priv, status); } @@ -732,11 +730,9 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, result = wait_event_timeout(priv->waitq, (status = priv->status), adap->timeout); - if (!result) { + if (!result) status = -ETIMEDOUT; - dev_warn(&priv->pci_dev->dev, - "Timeout waiting for interrupt!\n"); - } + priv->status = 0; return i801_check_post(priv, status); } -- cgit From 1de93d5d521717cbb77cc9796a4df141d800d608 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 22 May 2021 00:02:43 +0200 Subject: i2c: i801: Replace waitqueue with completion API Using the completion API is more intuitive and it allows to simplify the code. Note that we don't have to set priv->status = 0 any longer with the completion API. Signed-off-by: Heiner Kallweit Reviewed-by: Jean Delvare Tested-by: Jean Delvare Reviewed-by: Daniel Kurtz Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 48 +++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index bfea94d02775..738204d7726d 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -103,7 +103,7 @@ #include #include #include -#include +#include #include #include #include @@ -270,7 +270,7 @@ struct i801_priv { unsigned int features; /* isr processing */ - wait_queue_head_t waitq; + struct completion done; u8 status; /* Command state used by isr for byte-by-byte block transactions */ @@ -496,24 +496,19 @@ static int i801_wait_byte_done(struct i801_priv *priv) static int i801_transaction(struct i801_priv *priv, int xact) { int status; - int result; + unsigned long result; const struct i2c_adapter *adap = &priv->adapter; - result = i801_check_pre(priv); - if (result < 0) - return result; + status = i801_check_pre(priv); + if (status < 0) + return status; if (priv->features & FEATURE_IRQ) { + reinit_completion(&priv->done); outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START, SMBHSTCNT(priv)); - result = wait_event_timeout(priv->waitq, - (status = priv->status), - adap->timeout); - if (!result) - status = -ETIMEDOUT; - - priv->status = 0; - return i801_check_post(priv, status); + result = wait_for_completion_timeout(&priv->done, adap->timeout); + return i801_check_post(priv, result ? priv->status : -ETIMEDOUT); } /* the current contents of SMBHSTCNT can be overwritten, since PEC, @@ -638,7 +633,7 @@ static irqreturn_t i801_host_notify_isr(struct i801_priv *priv) * DEV_ERR - Invalid command, NAK or communication timeout * BUS_ERR - SMI# transaction collision * FAILED - transaction was canceled due to a KILL request - * When any of these occur, update ->status and wake up the waitq. + * When any of these occur, update ->status and signal completion. * ->status must be cleared before kicking off the next transaction. * * 2) For byte-by-byte (I2C read/write) transactions, one BYTE_DONE interrupt @@ -675,7 +670,7 @@ static irqreturn_t i801_isr(int irq, void *dev_id) if (status) { outb_p(status, SMBHSTSTS(priv)); priv->status = status; - wake_up(&priv->waitq); + complete(&priv->done); } return IRQ_HANDLED; @@ -694,15 +689,15 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, int i, len; int smbcmd; int status; - int result; + unsigned long result; const struct i2c_adapter *adap = &priv->adapter; if (command == I2C_SMBUS_BLOCK_PROC_CALL) return -EOPNOTSUPP; - result = i801_check_pre(priv); - if (result < 0) - return result; + status = i801_check_pre(priv); + if (status < 0) + return status; len = data->block[0]; @@ -726,15 +721,10 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, priv->count = 0; priv->data = &data->block[1]; + reinit_completion(&priv->done); outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv)); - result = wait_event_timeout(priv->waitq, - (status = priv->status), - adap->timeout); - if (!result) - status = -ETIMEDOUT; - - priv->status = 0; - return i801_check_post(priv, status); + result = wait_for_completion_timeout(&priv->done, adap->timeout); + return i801_check_post(priv, result ? priv->status : -ETIMEDOUT); } for (i = 1; i <= len; i++) { @@ -1889,7 +1879,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) } if (priv->features & FEATURE_IRQ) { - init_waitqueue_head(&priv->waitq); + init_completion(&priv->done); err = devm_request_irq(&dev->dev, dev->irq, i801_isr, IRQF_SHARED, -- cgit From 0d3f1e4524bb70f528b7002803fc0737c83ddd5e Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 22 May 2021 23:46:20 +0200 Subject: i2c: i801: Use standard PCI constants instead of own ones Layout of these registers is part of the PCI standard. Therefore use the constants defined by the PCI subsystem. Signed-off-by: Heiner Kallweit Reviewed-by: Jean Delvare Tested-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 738204d7726d..f6d7866f11c3 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -131,8 +131,6 @@ /* PCI Address Constants */ #define SMBBAR 4 -#define SMBPCICTL 0x004 -#define SMBPCISTS 0x006 #define SMBHSTCFG 0x040 #define TCOBASE 0x050 #define TCOCTL 0x054 @@ -141,12 +139,6 @@ #define SBREG_SMBCTRL 0xc6000c #define SBREG_SMBCTRL_DNV 0xcf000c -/* Host status bits for SMBPCISTS */ -#define SMBPCISTS_INTS BIT(3) - -/* Control bits for SMBPCICTL */ -#define SMBPCICTL_INTDIS BIT(10) - /* Host configuration bits for SMBHSTCFG */ #define SMBHSTCFG_HST_EN BIT(0) #define SMBHSTCFG_SMB_SMI_EN BIT(1) @@ -648,8 +640,8 @@ static irqreturn_t i801_isr(int irq, void *dev_id) u8 status; /* Confirm this is our interrupt */ - pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); - if (!(pcists & SMBPCISTS_INTS)) + pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists); + if (!(pcists & PCI_STATUS_INTERRUPT)) return IRQ_NONE; if (priv->features & FEATURE_HOST_NOTIFY) { @@ -1866,13 +1858,13 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) u16 pcictl, pcists; /* Complain if an interrupt is already pending */ - pci_read_config_word(priv->pci_dev, SMBPCISTS, &pcists); - if (pcists & SMBPCISTS_INTS) + pci_read_config_word(priv->pci_dev, PCI_STATUS, &pcists); + if (pcists & PCI_STATUS_INTERRUPT) dev_warn(&dev->dev, "An interrupt is pending!\n"); /* Check if interrupts have been disabled */ - pci_read_config_word(priv->pci_dev, SMBPCICTL, &pcictl); - if (pcictl & SMBPCICTL_INTDIS) { + pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pcictl); + if (pcictl & PCI_COMMAND_INTX_DISABLE) { dev_info(&dev->dev, "Interrupts are disabled\n"); priv->features &= ~FEATURE_IRQ; } -- cgit From 7fb9dc8109bf9713ffcda65617249099a1942f0f Mon Sep 17 00:00:00 2001 From: Qii Wang Date: Thu, 27 May 2021 19:31:50 +0800 Subject: i2c: mediatek: Rename i2c irq name Rename i2c irq name with dev_name() which can provide unique naming in /proc/interrupts for each instance of the I2C IP core. Signed-off-by: Qii Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 5ddfa4e56ee2..ea337ba46938 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1281,7 +1281,7 @@ static int mtk_i2c_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, - I2C_DRV_NAME, i2c); + dev_name(&pdev->dev), i2c); if (ret < 0) { dev_err(&pdev->dev, "Request I2C IRQ %d fail\n", irq); -- cgit From 7475d2fbca9c0daf15fcd7d2fd440782af56dad7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 4 May 2021 16:35:53 +0200 Subject: i2c: rcar: Drop "renesas,i2c-rcar" The compatible value "renesas,i2c-rcar" was deprecated in commit ad4a8dc3fec6485b ("i2c: rcar: Add per-Generation fallback bindings"), and never had any users in upstream Linux. Drop its match entry from the driver. Signed-off-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 327c092a4130..bff9913c37b8 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -1013,7 +1013,6 @@ static const struct of_device_id rcar_i2c_dt_ids[] = { { .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 }, { .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 }, { .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 }, - { .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 }, /* Deprecated */ { .compatible = "renesas,rcar-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 }, { .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 }, { .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 }, -- cgit From cd90e95820d569c7215abb9b7830a83212ed1273 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 4 May 2021 16:35:54 +0200 Subject: dt-bindings: i2c: renesas,i2c: Drop "renesas,i2c-rcar" The compatible value "renesas,i2c-rcar" was deprecated in commit ad4a8dc3fec6485b ("i2c: rcar: Add per-Generation fallback bindings"), and never had any users in upstream Linux. Drop its description from the DT bindings. Signed-off-by: Geert Uytterhoeven Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/renesas,i2c.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/i2c/renesas,i2c.txt b/Documentation/devicetree/bindings/i2c/renesas,i2c.txt index 5762d2d1ab9c..f4240fcf28bb 100644 --- a/Documentation/devicetree/bindings/i2c/renesas,i2c.txt +++ b/Documentation/devicetree/bindings/i2c/renesas,i2c.txt @@ -32,7 +32,6 @@ Required properties: device. "renesas,rcar-gen3-i2c" for a generic R-Car Gen3 or RZ/G2 compatible device. - "renesas,i2c-rcar" (deprecated) When compatible with the generic version, nodes must list the SoC-specific version corresponding to the platform first followed -- cgit From 524f6fdfa6375b75fb910ac80a9aa4a7c6091d9e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 4 May 2021 16:35:55 +0200 Subject: dt-bindings: i2c: renesas,i2c: Convert to json-schema Convert the Renesas R-Car I2C Controller Device Tree binding documentation to json-schema. Document missing properties. Make the clocks property required. DMA is supported on R-Car Gen3 and RZ/G2 only. Update the example to match reality. Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/renesas,i2c.txt | 66 --------- .../devicetree/bindings/i2c/renesas,rcar-i2c.yaml | 158 +++++++++++++++++++++ MAINTAINERS | 2 +- 3 files changed, 159 insertions(+), 67 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/renesas,i2c.txt create mode 100644 Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml diff --git a/Documentation/devicetree/bindings/i2c/renesas,i2c.txt b/Documentation/devicetree/bindings/i2c/renesas,i2c.txt deleted file mode 100644 index f4240fcf28bb..000000000000 --- a/Documentation/devicetree/bindings/i2c/renesas,i2c.txt +++ /dev/null @@ -1,66 +0,0 @@ -I2C for R-Car platforms - -Required properties: -- compatible: - "renesas,i2c-r8a7742" if the device is a part of a R8A7742 SoC. - "renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC. - "renesas,i2c-r8a7744" if the device is a part of a R8A7744 SoC. - "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC. - "renesas,i2c-r8a77470" if the device is a part of a R8A77470 SoC. - "renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC. - "renesas,i2c-r8a774b1" if the device is a part of a R8A774B1 SoC. - "renesas,i2c-r8a774c0" if the device is a part of a R8A774C0 SoC. - "renesas,i2c-r8a774e1" if the device is a part of a R8A774E1 SoC. - "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC. - "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC. - "renesas,i2c-r8a7790" if the device is a part of a R8A7790 SoC. - "renesas,i2c-r8a7791" if the device is a part of a R8A7791 SoC. - "renesas,i2c-r8a7792" if the device is a part of a R8A7792 SoC. - "renesas,i2c-r8a7793" if the device is a part of a R8A7793 SoC. - "renesas,i2c-r8a7794" if the device is a part of a R8A7794 SoC. - "renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC. - "renesas,i2c-r8a7796" if the device is a part of a R8A77960 SoC. - "renesas,i2c-r8a77961" if the device is a part of a R8A77961 SoC. - "renesas,i2c-r8a77965" if the device is a part of a R8A77965 SoC. - "renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC. - "renesas,i2c-r8a77980" if the device is a part of a R8A77980 SoC. - "renesas,i2c-r8a77990" if the device is a part of a R8A77990 SoC. - "renesas,i2c-r8a77995" if the device is a part of a R8A77995 SoC. - "renesas,i2c-r8a779a0" if the device is a part of a R8A779A0 SoC. - "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device. - "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible - device. - "renesas,rcar-gen3-i2c" for a generic R-Car Gen3 or RZ/G2 compatible - device. - - When compatible with the generic version, nodes must list the - SoC-specific version corresponding to the platform first followed - by the generic version. - -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: interrupt specifier. - -Optional properties: -- clock-frequency: desired I2C bus clock frequency in Hz. The absence of this - property indicates the default frequency 100 kHz. -- clocks: clock specifier. -- dmas: Must contain a list of two references to DMA specifiers, one for - transmission, and one for reception. -- dma-names: Must contain a list of two DMA names, "tx" and "rx". - -- i2c-scl-falling-time-ns: see i2c.txt -- i2c-scl-internal-delay-ns: see i2c.txt -- i2c-scl-rising-time-ns: see i2c.txt - -Examples : - -i2c0: i2c@e6508000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c"; - reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp9_clks R8A7791_CLK_I2C0>; - clock-frequency = <400000>; -}; diff --git a/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml b/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml new file mode 100644 index 000000000000..052aad44e781 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml @@ -0,0 +1,158 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/renesas,rcar-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas R-Car I2C Controller + +maintainers: + - Wolfram Sang + +properties: + compatible: + oneOf: + - items: + - enum: + - renesas,i2c-r8a7778 # R-Car M1A + - renesas,i2c-r8a7779 # R-Car H1 + - const: renesas,rcar-gen1-i2c # R-Car Gen1 + + - items: + - enum: + - renesas,i2c-r8a7742 # RZ/G1H + - renesas,i2c-r8a7743 # RZ/G1M + - renesas,i2c-r8a7744 # RZ/G1N + - renesas,i2c-r8a7745 # RZ/G1E + - renesas,i2c-r8a77470 # RZ/G1C + - renesas,i2c-r8a7790 # R-Car H2 + - renesas,i2c-r8a7791 # R-Car M2-W + - renesas,i2c-r8a7792 # R-Car V2H + - renesas,i2c-r8a7793 # R-Car M2-N + - renesas,i2c-r8a7794 # R-Car E2 + - const: renesas,rcar-gen2-i2c # R-Car Gen2 and RZ/G1 + + - items: + - enum: + - renesas,i2c-r8a774a1 # RZ/G2M + - renesas,i2c-r8a774b1 # RZ/G2N + - renesas,i2c-r8a774c0 # RZ/G2E + - renesas,i2c-r8a774e1 # RZ/G2H + - renesas,i2c-r8a7795 # R-Car H3 + - renesas,i2c-r8a7796 # R-Car M3-W + - renesas,i2c-r8a77961 # R-Car M3-W+ + - renesas,i2c-r8a77965 # R-Car M3-N + - renesas,i2c-r8a77970 # R-Car V3M + - renesas,i2c-r8a77980 # R-Car V3H + - renesas,i2c-r8a77990 # R-Car E3 + - renesas,i2c-r8a77995 # R-Car D3 + - renesas,i2c-r8a779a0 # R-Car V3U + - const: renesas,rcar-gen3-i2c # R-Car Gen3 and RZ/G2 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clock-frequency: + description: + Desired I2C bus clock frequency in Hz. The absence of this property + indicates the default frequency 100 kHz. + + clocks: + maxItems: 1 + + power-domains: + maxItems: 1 + + resets: + maxItems: 1 + + dmas: + minItems: 2 + maxItems: 4 + description: + Must contain a list of pairs of references to DMA specifiers, one for + transmission, and one for reception. + + dma-names: + minItems: 2 + maxItems: 4 + items: + enum: + - tx + - rx + + i2c-scl-falling-time-ns: + default: 35 + description: + Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C + specification. + + i2c-scl-internal-delay-ns: + default: 50 + description: + Number of nanoseconds the IP core additionally needs to setup SCL. + + i2c-scl-rising-time-ns: + default: 200 + description: + Number of nanoseconds the SCL signal takes to rise; t(r) in the I2C + specification. + +required: + - compatible + - reg + - interrupts + - clocks + - power-domains + - '#address-cells' + - '#size-cells' + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + + - if: + properties: + compatible: + contains: + enum: + - renesas,rcar-gen1-i2c + - renesas,rcar-gen2-i2c + then: + properties: + dmas: false + dma-names: false + + - if: + properties: + compatible: + contains: + enum: + - renesas,rcar-gen2-i2c + - renesas,rcar-gen3-i2c + then: + required: + - resets + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + i2c0: i2c@e6508000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7791", "renesas,rcar-gen2-i2c"; + reg = <0xe6508000 0x40>; + interrupts = ; + clock-frequency = <400000>; + clocks = <&cpg CPG_MOD 931>; + power-domains = <&sysc R8A7791_PD_ALWAYS_ON>; + resets = <&cpg 931>; + i2c-scl-internal-delay-ns = <6>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 81e1edeceae4..654f07ca2cd0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15596,7 +15596,7 @@ F: drivers/iio/adc/rcar-gyroadc.c RENESAS R-CAR I2C DRIVERS M: Wolfram Sang S: Supported -F: Documentation/devicetree/bindings/i2c/renesas,i2c.txt +F: Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml F: Documentation/devicetree/bindings/i2c/renesas,iic.txt F: drivers/i2c/busses/i2c-rcar.c F: drivers/i2c/busses/i2c-sh_mobile.c -- cgit From 6221a93475f35fe7aade9d66211661bb82755da5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 4 May 2021 16:35:58 +0200 Subject: dt-bindings: i2c: renesas,iic-emev2: Convert to json-schema Convert the Renesas EMMA Mobile EV2 IIC Interface (IIC) Device Tree binding documentation to json-schema. Document missing properties. Update the example to match reality. Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/renesas,iic-emev2.txt | 22 --------- .../devicetree/bindings/i2c/renesas,iic-emev2.yaml | 54 ++++++++++++++++++++++ MAINTAINERS | 2 +- 3 files changed, 55 insertions(+), 23 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt create mode 100644 Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml diff --git a/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt b/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt deleted file mode 100644 index 5ed1ea1c7e14..000000000000 --- a/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt +++ /dev/null @@ -1,22 +0,0 @@ -Device tree configuration for Renesas EMEV2 IIC controller - -Required properties: -- compatible : "renesas,iic-emev2" -- reg : address start and address range size of device -- interrupts : specifier for the IIC controller interrupt -- clocks : phandle to the IP core SCLK -- clock-names : must be "sclk" -- #address-cells : should be <1> -- #size-cells : should be <0> - -Example: - - iic0: i2c@e0070000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "renesas,iic-emev2"; - reg = <0xe0070000 0x28>; - interrupts = <0 32 IRQ_TYPE_EDGE_RISING>; - clocks = <&iic0_sclk>; - clock-names = "sclk"; - }; diff --git a/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml b/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml new file mode 100644 index 000000000000..17c1102562be --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/renesas,iic-emev2.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas EMMA Mobile EV2 IIC Interface + +maintainers: + - Wolfram Sang + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + +properties: + compatible: + const: renesas,iic-emev2 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: sclk + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - '#address-cells' + - '#size-cells' + +unevaluatedProperties: false + +examples: + - | + #include + + iic0: i2c@e0070000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-emev2"; + reg = <0xe0070000 0x28>; + interrupts = ; + clocks = <&iic0_sclk>; + clock-names = "sclk"; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 654f07ca2cd0..e07a56601b36 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15575,7 +15575,7 @@ F: drivers/clk/renesas/ RENESAS EMEV2 I2C DRIVER M: Wolfram Sang S: Supported -F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt +F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml F: drivers/i2c/busses/i2c-emev2.c RENESAS ETHERNET DRIVERS -- cgit From 92b7716f4c54cb61b30e4680ea436a9e0cc6f4de Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 May 2021 11:19:48 +0200 Subject: dt-bindings: i2c: renesas,riic: Convert to json-schema Convert the Renesas RZ/A I2C Bus Interface (RIIC) Device Tree binding documentation to json-schema. Document missing properties. Update the example to match reality. Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/renesas,riic.txt | 32 --------- .../devicetree/bindings/i2c/renesas,riic.yaml | 82 ++++++++++++++++++++++ MAINTAINERS | 2 +- 3 files changed, 83 insertions(+), 33 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/renesas,riic.txt create mode 100644 Documentation/devicetree/bindings/i2c/renesas,riic.yaml diff --git a/Documentation/devicetree/bindings/i2c/renesas,riic.txt b/Documentation/devicetree/bindings/i2c/renesas,riic.txt deleted file mode 100644 index e26fe3ad86a9..000000000000 --- a/Documentation/devicetree/bindings/i2c/renesas,riic.txt +++ /dev/null @@ -1,32 +0,0 @@ -Device tree configuration for Renesas RIIC driver - -Required properties: -- compatible : - "renesas,riic-r7s72100" if the device is a part of a R7S72100 SoC. - "renesas,riic-r7s9210" if the device is a part of a R7S9210 SoC. - "renesas,riic-rz" for a generic RZ/A compatible device. -- reg : address start and address range size of device -- interrupts : 8 interrupts (TEI, RI, TI, SPI, STI, NAKI, ALI, TMOI) -- clock-frequency : frequency of bus clock in Hz -- #address-cells : should be <1> -- #size-cells : should be <0> - -Pinctrl properties might be needed, too. See there. - -Example: - - i2c0: i2c@fcfee000 { - compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; - reg = <0xfcfee000 0x44>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>, - <0 158 IRQ_TYPE_EDGE_RISING>, - <0 159 IRQ_TYPE_EDGE_RISING>, - <0 160 IRQ_TYPE_LEVEL_HIGH>, - <0 161 IRQ_TYPE_LEVEL_HIGH>, - <0 162 IRQ_TYPE_LEVEL_HIGH>, - <0 163 IRQ_TYPE_LEVEL_HIGH>, - <0 164 IRQ_TYPE_LEVEL_HIGH>; - clock-frequency = <100000>; - #address-cells = <1>; - #size-cells = <0>; - }; diff --git a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml new file mode 100644 index 000000000000..2d6378164958 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/renesas,riic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/A I2C Bus Interface (RIIC) + +maintainers: + - Chris Brandt + - Wolfram Sang + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + +properties: + compatible: + items: + - enum: + - renesas,riic-r7s72100 # RZ/A1H + - renesas,riic-r7s9210 # RZ/A2M + - const: renesas,riic-rz # RZ/A + + reg: + maxItems: 1 + + interrupts: + items: + - description: Transmit End Interrupt (TEI) + - description: Receive Data Full Interrupt (RI) + - description: Transmit Data Empty Interrupt (TI) + - description: Stop Condition Detection Interrupt (SPI) + - description: Start Condition Detection Interrupt (STI) + - description: NACK Reception Interrupt (NAKI) + - description: Arbitration-Lost Interrupt (ALI) + - description: Timeout Interrupt (TMOI) + + clock-frequency: + description: + Desired I2C bus clock frequency in Hz. The absence of this property + indicates the default frequency 100 kHz. + + clocks: + maxItems: 1 + + power-domains: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-frequency + - power-domains + - '#address-cells' + - '#size-cells' + +unevaluatedProperties: false + +examples: + - | + #include + #include + + i2c0: i2c@fcfee000 { + compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; + reg = <0xfcfee000 0x44>; + interrupts = , + , + , + , + , + , + , + ; + clocks = <&mstp9_clks R7S72100_CLK_I2C0>; + clock-frequency = <100000>; + power-domains = <&cpg_clocks>; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index e07a56601b36..ab5fc6af8800 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15613,7 +15613,7 @@ F: drivers/thermal/rcar_thermal.c RENESAS RIIC DRIVER M: Chris Brandt S: Supported -F: Documentation/devicetree/bindings/i2c/renesas,riic.txt +F: Documentation/devicetree/bindings/i2c/renesas,riic.yaml F: drivers/i2c/busses/i2c-riic.c RENESAS USB PHY DRIVER -- cgit From cb3c66af9585c0301a772332e195ead1fe3b29cf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 28 May 2021 12:13:50 +0300 Subject: i2c: core: Make debug message even more debuggish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One may notice that dev_printk(KERN_DEBUG ...) is *not* an equivalent to dev_dbg(). It will be printed whenever loglevel is high enough. And currently it will be the only message in the I²C core in some configurations that got printed under above conditions. Moving to dev_dbg() will hide it in the configurations where Dynamic Debug is enabled and hence align with all other debug messages in the I²C core.. Signed-off-by: Andy Shevchenko Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 5a97e4a02fa2..ae1b1b610aca 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -399,7 +399,8 @@ static int i2c_gpio_init_recovery(struct i2c_adapter *adap) static int i2c_init_recovery(struct i2c_adapter *adap) { struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; - char *err_str, *err_level = KERN_ERR; + bool is_error_level = true; + char *err_str; if (!bri) return 0; @@ -409,7 +410,7 @@ static int i2c_init_recovery(struct i2c_adapter *adap) if (!bri->recover_bus) { err_str = "no suitable method provided"; - err_level = KERN_DEBUG; + is_error_level = false; goto err; } @@ -436,7 +437,10 @@ static int i2c_init_recovery(struct i2c_adapter *adap) return 0; err: - dev_printk(err_level, &adap->dev, "Not using recovery: %s\n", err_str); + if (is_error_level) + dev_err(&adap->dev, "Not using recovery: %s\n", err_str); + else + dev_dbg(&adap->dev, "Not using recovery: %s\n", err_str); adap->bus_recovery_info = NULL; return -EINVAL; -- cgit From 5a7b95fb993ec399c8a685552aa6a8fc995c40bd Mon Sep 17 00:00:00 2001 From: Bibby Hsieh Date: Thu, 27 May 2021 15:55:53 +0800 Subject: i2c: core: support bus regulator controlling in adapter Although in the most platforms, the bus power of i2c are alway on, some platforms disable the i2c bus power in order to meet low power request. We can control bulk regulator if it is provided in i2c adapter device. Signed-off-by: Bibby Hsieh Signed-off-by: Marek Szyprowski Signed-off-by: Hsin-Yi Wang Reviewed-by: Matthias Brugger Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 95 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c.h | 2 + 2 files changed, 97 insertions(+) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index ae1b1b610aca..2a222e495c70 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -465,12 +465,14 @@ static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client) static int i2c_device_probe(struct device *dev) { struct i2c_client *client = i2c_verify_client(dev); + struct i2c_adapter *adap; struct i2c_driver *driver; int status; if (!client) return 0; + adap = client->adapter; client->irq = client->init_irq; if (!client->irq) { @@ -536,6 +538,14 @@ static int i2c_device_probe(struct device *dev) dev_dbg(dev, "probe\n"); + if (adap->bus_regulator) { + status = regulator_enable(adap->bus_regulator); + if (status < 0) { + dev_err(&adap->dev, "Failed to enable bus regulator\n"); + goto err_clear_wakeup_irq; + } + } + status = of_clk_set_defaults(dev->of_node, false); if (status < 0) goto err_clear_wakeup_irq; @@ -593,8 +603,10 @@ put_sync_adapter: static int i2c_device_remove(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); + struct i2c_adapter *adap; struct i2c_driver *driver; + adap = client->adapter; driver = to_i2c_driver(dev->driver); if (driver->remove) { int status; @@ -609,6 +621,8 @@ static int i2c_device_remove(struct device *dev) devres_release_group(&client->dev, client->devres_group_id); dev_pm_domain_detach(&client->dev, true); + if (!pm_runtime_status_suspended(&client->dev) && adap->bus_regulator) + regulator_disable(adap->bus_regulator); dev_pm_clear_wake_irq(&client->dev); device_init_wakeup(&client->dev, false); @@ -621,6 +635,86 @@ static int i2c_device_remove(struct device *dev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int i2c_resume_early(struct device *dev) +{ + struct i2c_client *client = i2c_verify_client(dev); + int err; + + if (!client) + return 0; + + if (pm_runtime_status_suspended(&client->dev) && + client->adapter->bus_regulator) { + err = regulator_enable(client->adapter->bus_regulator); + if (err) + return err; + } + + return pm_generic_resume_early(&client->dev); +} + +static int i2c_suspend_late(struct device *dev) +{ + struct i2c_client *client = i2c_verify_client(dev); + int err; + + if (!client) + return 0; + + err = pm_generic_suspend_late(&client->dev); + if (err) + return err; + + if (!pm_runtime_status_suspended(&client->dev) && + client->adapter->bus_regulator) + return regulator_disable(client->adapter->bus_regulator); + + return 0; +} +#endif + +#ifdef CONFIG_PM +static int i2c_runtime_resume(struct device *dev) +{ + struct i2c_client *client = i2c_verify_client(dev); + int err; + + if (!client) + return 0; + + if (client->adapter->bus_regulator) { + err = regulator_enable(client->adapter->bus_regulator); + if (err) + return err; + } + + return pm_generic_runtime_resume(&client->dev); +} + +static int i2c_runtime_suspend(struct device *dev) +{ + struct i2c_client *client = i2c_verify_client(dev); + int err; + + if (!client) + return 0; + + err = pm_generic_runtime_suspend(&client->dev); + if (err) + return err; + + if (client->adapter->bus_regulator) + return regulator_disable(client->adapter->bus_regulator); + return 0; +} +#endif + +static const struct dev_pm_ops i2c_device_pm = { + SET_LATE_SYSTEM_SLEEP_PM_OPS(i2c_suspend_late, i2c_resume_early) + SET_RUNTIME_PM_OPS(i2c_runtime_suspend, i2c_runtime_resume, NULL) +}; + static void i2c_device_shutdown(struct device *dev) { struct i2c_client *client = i2c_verify_client(dev); @@ -678,6 +772,7 @@ struct bus_type i2c_bus_type = { .probe = i2c_device_probe, .remove = i2c_device_remove, .shutdown = i2c_device_shutdown, + .pm = &i2c_device_pm, }; EXPORT_SYMBOL_GPL(i2c_bus_type); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index e8f2ac8c9c3d..953a4eecb88f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -15,6 +15,7 @@ #include /* for struct device */ #include /* for completion */ #include +#include #include #include /* for Host Notify IRQ */ #include /* for struct device_node */ @@ -729,6 +730,7 @@ struct i2c_adapter { const struct i2c_adapter_quirks *quirks; struct irq_domain *host_notify_domain; + struct regulator *bus_regulator; }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) -- cgit From c021087c43c8f9b0bb070a85d49f2e3ac450c43e Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Thu, 27 May 2021 15:55:54 +0800 Subject: dt-binding: i2c: mt65xx: add vbus-supply property Add vbus-supply property for mt65xx. The regulator can be passed into core and turned off during suspend/sleep to reduce power consumption. Signed-off-by: Hsin-Yi Wang Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt index 7f0194fdd0cc..2c45647e9f0b 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt @@ -32,6 +32,7 @@ Optional properties: - mediatek,have-pmic: platform can control i2c form special pmic side. Only mt6589 and mt8135 support this feature. - mediatek,use-push-pull: IO config use push-pull mode. + - vbus-supply: phandle to the regulator that provides power to SCL/SDA. Example: -- cgit From 9029b9b2ae1355366530e43890fd6aa5db39e91e Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Thu, 27 May 2021 15:55:55 +0800 Subject: i2c: mediatek: mt65xx: add optional vbus-supply Add vbus-supply which provides power to SCL/SDA. Pass this regulator into core so it can be turned on/off for low power mode support. Signed-off-by: Hsin-Yi Wang Reviewed-by: Matthias Brugger Reviewed-by: Qii Wang Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index ea337ba46938..cb7fc7639396 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1220,6 +1220,13 @@ static int mtk_i2c_probe(struct platform_device *pdev) i2c->adap.quirks = i2c->dev_comp->quirks; i2c->adap.timeout = 2 * HZ; i2c->adap.retries = 1; + i2c->adap.bus_regulator = devm_regulator_get_optional(&pdev->dev, "vbus"); + if (IS_ERR(i2c->adap.bus_regulator)) { + if (PTR_ERR(i2c->adap.bus_regulator) == -ENODEV) + i2c->adap.bus_regulator = NULL; + else + return PTR_ERR(i2c->adap.bus_regulator); + } ret = mtk_i2c_parse_dt(pdev->dev.of_node, i2c); if (ret) -- cgit From 5ab9dc38e2cf5c577722e2d959496b4c2503d1d4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 1 Jun 2021 17:03:54 +0200 Subject: MAINTAINERS: Add linux-renesas-soc to the Renesas I2C entries The people on linux-renesas-soc are interested in changes to the Renesas I2C drivers and their DT bindings. Signed-off-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ab5fc6af8800..3b6b8d88be5e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15574,6 +15574,7 @@ F: drivers/clk/renesas/ RENESAS EMEV2 I2C DRIVER M: Wolfram Sang +L: linux-renesas-soc@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml F: drivers/i2c/busses/i2c-emev2.c @@ -15595,6 +15596,7 @@ F: drivers/iio/adc/rcar-gyroadc.c RENESAS R-CAR I2C DRIVERS M: Wolfram Sang +L: linux-renesas-soc@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml F: Documentation/devicetree/bindings/i2c/renesas,iic.txt @@ -15612,6 +15614,7 @@ F: drivers/thermal/rcar_thermal.c RENESAS RIIC DRIVER M: Chris Brandt +L: linux-renesas-soc@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/i2c/renesas,riic.yaml F: drivers/i2c/busses/i2c-riic.c -- cgit From 02fa1189927f69f0f9d617789943fb4ae748012b Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Wed, 26 May 2021 15:34:12 +0530 Subject: dt-bindings: i2c: Move i2c-omap.txt to YAML format Convert i2c-omap.txt to YAML schema for better checks and documentation. Following properties were used in DT but were not documented in txt bindings and has been included in YAML schema: 1. Include ti,am4372-i2c compatible 2. Document clocks property Signed-off-by: Vignesh Raghavendra Reviewed-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-omap.txt | 37 -------- .../devicetree/bindings/i2c/ti,omap4-i2c.yaml | 102 +++++++++++++++++++++ MAINTAINERS | 2 +- 3 files changed, 103 insertions(+), 38 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/i2c-omap.txt create mode 100644 Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml diff --git a/Documentation/devicetree/bindings/i2c/i2c-omap.txt b/Documentation/devicetree/bindings/i2c/i2c-omap.txt deleted file mode 100644 index a425b91af48f..000000000000 --- a/Documentation/devicetree/bindings/i2c/i2c-omap.txt +++ /dev/null @@ -1,37 +0,0 @@ -I2C for OMAP platforms - -Required properties : -- compatible : Must be - "ti,omap2420-i2c" for OMAP2420 SoCs - "ti,omap2430-i2c" for OMAP2430 SoCs - "ti,omap3-i2c" for OMAP3 SoCs - "ti,omap4-i2c" for OMAP4+ SoCs - "ti,am654-i2c", "ti,omap4-i2c" for AM654 SoCs - "ti,j721e-i2c", "ti,omap4-i2c" for J721E SoCs - "ti,am64-i2c", "ti,omap4-i2c" for AM64 SoCs -- ti,hwmods : Must be "i2c", n being the instance number (1-based) -- #address-cells = <1>; -- #size-cells = <0>; - -Recommended properties : -- clock-frequency : Desired I2C bus clock frequency in Hz. Otherwise - the default 100 kHz frequency will be used. - -Optional properties: -- Child nodes conforming to i2c bus binding - -Note: Current implementation will fetch base address, irq and dma -from omap hwmod data base during device registration. -Future plan is to migrate hwmod data base contents into device tree -blob so that, all the required data will be used from device tree dts -file. - -Examples : - -i2c1: i2c@0 { - compatible = "ti,omap3-i2c"; - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c1"; - clock-frequency = <400000>; -}; diff --git a/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml b/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml new file mode 100644 index 000000000000..ff165ad1bee8 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/ti,omap4-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bindings for I2C controllers on TI's OMAP and K3 SoCs + +maintainers: + - Vignesh Raghavendra + +properties: + compatible: + oneOf: + - enum: + - ti,omap2420-i2c + - ti,omap2430-i2c + - ti,omap3-i2c + - ti,omap4-i2c + - items: + - enum: + - ti,am4372-i2c + - ti,am64-i2c + - ti,am654-i2c + - ti,j721e-i2c + - const: ti,omap4-i2c + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: fck + + clock-frequency: true + + power-domains: true + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + ti,hwmods: + description: + Must be "i2c", n being the instance number (1-based). + This property is applicable only on legacy platforms mainly omap2/3 + and ti81xx and should not be used on other platforms. + $ref: /schemas/types.yaml#/definitions/string + deprecated: true + +# subnode's properties +patternProperties: + "@[0-9a-f]+$": + type: object + description: + Flash device uses the below defined properties in the subnode. + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +if: + properties: + compatible: + oneOf: + - const: ti,omap2420-i2c + - const: ti,omap2430-i2c + - const: ti,omap3-i2c + - const: ti,omap4-i2c + +then: + properties: + ti,hwmods: + items: + - pattern: "^i2c([1-9])$" + +else: + properties: + ti,hwmods: false + +examples: + - | + #include + #include + + main_i2c0: i2c@2000000 { + compatible = "ti,j721e-i2c", "ti,omap4-i2c"; + reg = <0x2000000 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 3b6b8d88be5e..2b6a6efdf737 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13365,7 +13365,7 @@ M: Vignesh R L: linux-omap@vger.kernel.org L: linux-i2c@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/i2c/i2c-omap.txt +F: Documentation/devicetree/bindings/i2c/ti,omap4-i2c.yaml F: drivers/i2c/busses/i2c-omap.c OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS) -- cgit From 93b2e8711fe2ad6d25829574906b09a2339d2c80 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 May 2021 13:10:49 +0200 Subject: dt-bindings: i2c: i2c-mux: Remove reset-active-low from ssd1307fb examples The "reset-active-low" property was removed from the ssd1307fb bindings in commit 519b4dba586198ee ("fbdev: ssd1307fb: Remove reset-active-low from the DT binding document") and from the ssd1307fb binding examples in commit 7d7e58d30e046d34 ("dt-bindings: display: ssd1307fb: Remove reset-active-low from examples"). Signed-off-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt index 21da3ecbb370..1bf267302251 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.txt @@ -62,7 +62,6 @@ Example: reg = <0x3c>; pwms = <&pwm 4 3000>; reset-gpios = <&gpio2 7 1>; - reset-active-low; }; }; -- cgit From 5690951154f7bd084e5e3676021c5bbf2042797e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 18 Jun 2021 13:04:07 +0200 Subject: dt-bindings: i2c: renesas,iic: Always declare generic compatibility According to the Hardware User's Manual, automatic transmission for PMIC control (DVFS) is not available on the R-Car E3 and RZ/G2E SoC. Experiments showed this really means that support for automatic DVFS is not present, while the IIC automatic transmission feature itself is still available, albeit not super useful. Hence there is no longer a reason not to declare compatibility with the R-Car Gen3-specific and generic versions, and the corresponding paragraph can be dropped. Signed-off-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/renesas,iic.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/renesas,iic.txt b/Documentation/devicetree/bindings/i2c/renesas,iic.txt index 93d412832e66..5de808f79b06 100644 --- a/Documentation/devicetree/bindings/i2c/renesas,iic.txt +++ b/Documentation/devicetree/bindings/i2c/renesas,iic.txt @@ -37,11 +37,6 @@ Required properties: When compatible with "renesas,rmobile-iic" it should be the last compatibility string listed. - The r8a77990 (R-Car E3) and r8a774c0 (RZ/G2E) - controllers are not considered compatible with - "renesas,rcar-gen3-iic" or "renesas,rmobile-iic" - due to the absence of automatic transmission registers. - - reg : address start and address range size of device - interrupts : interrupt of device - clocks : clock for device -- cgit From 632ce67773dace482a8c4fcbedd4c19154e38d37 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 18 Jun 2021 13:04:11 +0200 Subject: dt-bindings: i2c: renesas,iic: Convert to json-schema Convert the Renesas R-Mobile I2C Bus Interface (IIC) Device Tree binding documentation to json-schema. Document missing properties. R-Mobile A1 and SH-Mobile have multiple interrupts. Update the example to match reality. Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/renesas,iic.txt | 67 --------- .../bindings/i2c/renesas,rmobile-iic.yaml | 149 +++++++++++++++++++++ MAINTAINERS | 2 +- 3 files changed, 150 insertions(+), 68 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/renesas,iic.txt create mode 100644 Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml diff --git a/Documentation/devicetree/bindings/i2c/renesas,iic.txt b/Documentation/devicetree/bindings/i2c/renesas,iic.txt deleted file mode 100644 index 5de808f79b06..000000000000 --- a/Documentation/devicetree/bindings/i2c/renesas,iic.txt +++ /dev/null @@ -1,67 +0,0 @@ -Device tree configuration for Renesas IIC (sh_mobile) driver - -Required properties: -- compatible : - - "renesas,iic-r8a73a4" (R-Mobile APE6) - - "renesas,iic-r8a7740" (R-Mobile A1) - - "renesas,iic-r8a7742" (RZ/G1H) - - "renesas,iic-r8a7743" (RZ/G1M) - - "renesas,iic-r8a7744" (RZ/G1N) - - "renesas,iic-r8a7745" (RZ/G1E) - - "renesas,iic-r8a774a1" (RZ/G2M) - - "renesas,iic-r8a774b1" (RZ/G2N) - - "renesas,iic-r8a774c0" (RZ/G2E) - - "renesas,iic-r8a774e1" (RZ/G2H) - - "renesas,iic-r8a7790" (R-Car H2) - - "renesas,iic-r8a7791" (R-Car M2-W) - - "renesas,iic-r8a7792" (R-Car V2H) - - "renesas,iic-r8a7793" (R-Car M2-N) - - "renesas,iic-r8a7794" (R-Car E2) - - "renesas,iic-r8a7795" (R-Car H3) - - "renesas,iic-r8a7796" (R-Car M3-W) - - "renesas,iic-r8a77961" (R-Car M3-W+) - - "renesas,iic-r8a77965" (R-Car M3-N) - - "renesas,iic-r8a77990" (R-Car E3) - - "renesas,iic-sh73a0" (SH-Mobile AG5) - - "renesas,rcar-gen2-iic" (generic R-Car Gen2 or RZ/G1 - compatible device) - - "renesas,rcar-gen3-iic" (generic R-Car Gen3 or RZ/G2 - compatible device) - - "renesas,rmobile-iic" (generic device) - - When compatible with a generic R-Car version, nodes - must list the SoC-specific version corresponding to - the platform first followed by the generic R-Car - version. - - When compatible with "renesas,rmobile-iic" it should - be the last compatibility string listed. - -- reg : address start and address range size of device -- interrupts : interrupt of device -- clocks : clock for device -- #address-cells : should be <1> -- #size-cells : should be <0> - -Optional properties: -- clock-frequency : frequency of bus clock in Hz. Default 100kHz if unset. -- dmas : Must contain a list of two references to DMA - specifiers, one for transmission, and one for - reception. -- dma-names : Must contain a list of two DMA names, "tx" and "rx". - - -Pinctrl properties might be needed, too. See there. - -Example: - - iic0: i2c@e6500000 { - compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic", - "renesas,rmobile-iic"; - reg = <0 0xe6500000 0 0x425>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp3_clks R8A7790_CLK_IIC0>; - clock-frequency = <400000>; - #address-cells = <1>; - #size-cells = <0>; - }; diff --git a/Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml b/Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml new file mode 100644 index 000000000000..04e4ffd80bc0 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml @@ -0,0 +1,149 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/renesas,rmobile-iic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas R-Mobile I2C Bus Interface (IIC) + +maintainers: + - Wolfram Sang + +properties: + compatible: + oneOf: + - items: + - enum: + - renesas,iic-r8a73a4 # R-Mobile APE6 + - renesas,iic-r8a7740 # R-Mobile A1 + - renesas,iic-sh73a0 # SH-Mobile AG5 + - const: renesas,rmobile-iic # Generic + + - items: + - enum: + - renesas,iic-r8a7742 # RZ/G1H + - renesas,iic-r8a7743 # RZ/G1M + - renesas,iic-r8a7744 # RZ/G1N + - renesas,iic-r8a7745 # RZ/G1E + - renesas,iic-r8a7790 # R-Car H2 + - renesas,iic-r8a7791 # R-Car M2-W + - renesas,iic-r8a7792 # R-Car V2H + - renesas,iic-r8a7793 # R-Car M2-N + - renesas,iic-r8a7794 # R-Car E2 + - const: renesas,rcar-gen2-iic # R-Car Gen2 and RZ/G1 + - const: renesas,rmobile-iic # Generic + + - items: + - enum: + - renesas,iic-r8a774a1 # RZ/G2M + - renesas,iic-r8a774b1 # RZ/G2N + - renesas,iic-r8a774c0 # RZ/G2E + - renesas,iic-r8a774e1 # RZ/G2H + - renesas,iic-r8a7795 # R-Car H3 + - renesas,iic-r8a7796 # R-Car M3-W + - renesas,iic-r8a77961 # R-Car M3-W+ + - renesas,iic-r8a77965 # R-Car M3-N + - renesas,iic-r8a77990 # R-Car E3 + - const: renesas,rcar-gen3-iic # R-Car Gen3 and RZ/G2 + - const: renesas,rmobile-iic # Generic + + reg: + maxItems: 1 + + interrupts: true + + clock-frequency: + description: + Desired I2C bus clock frequency in Hz. The absence of this property + indicates the default frequency 100 kHz. + + clocks: + maxItems: 1 + + power-domains: + maxItems: 1 + + resets: + maxItems: 1 + + dmas: + minItems: 2 + maxItems: 4 + description: + Must contain a list of pairs of references to DMA specifiers, one for + transmission, and one for reception. + + dma-names: + minItems: 2 + maxItems: 4 + items: + enum: + - tx + - rx + +required: + - compatible + - reg + - interrupts + - clocks + - power-domains + - '#address-cells' + - '#size-cells' + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + + - if: + properties: + compatible: + contains: + enum: + - renesas,iic-r8a7740 + - renesas,iic-sh73a0 + then: + properties: + interrupts: + items: + - description: Arbitration Lost Interrupt (ALI) + - description: Non-acknowledge Detection Interrupt (TACKI) + - description: Wait Interrupt (WAITI) + - description: Data Transmit Enable interrupt (DTEI) + else: + properties: + interrupts: + items: + - description: Single combined interrupt + + - if: + properties: + compatible: + contains: + enum: + - renesas,rcar-gen2-iic + - renesas,rcar-gen3-iic + then: + required: + - resets + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + iic0: i2c@e6500000 { + compatible = "renesas,iic-r8a7790", "renesas,rcar-gen2-iic", + "renesas,rmobile-iic"; + reg = <0xe6500000 0x425>; + interrupts = ; + clocks = <&cpg CPG_MOD 318>; + clock-frequency = <400000>; + dmas = <&dmac0 0x61>, <&dmac0 0x62>, <&dmac1 0x61>, <&dmac1 0x62>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; + resets = <&cpg 318>; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 2b6a6efdf737..60059dd0ad38 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15599,7 +15599,7 @@ M: Wolfram Sang L: linux-renesas-soc@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml -F: Documentation/devicetree/bindings/i2c/renesas,iic.txt +F: Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml F: drivers/i2c/busses/i2c-rcar.c F: drivers/i2c/busses/i2c-sh_mobile.c -- cgit From a431a0914f9276aa70b7075cb43b9cdc537eaf29 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 15 Jun 2021 09:53:59 +0100 Subject: dt-bindings: i2c: renesas,riic: Document RZ/G2L I2C controller Document RZ/G2L I2C controller bindings. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang --- .../devicetree/bindings/i2c/renesas,riic.yaml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml index 2d6378164958..52d92ec7ec0b 100644 --- a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml +++ b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/i2c/renesas,riic.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Renesas RZ/A I2C Bus Interface (RIIC) +title: Renesas RZ/A and RZ/G2L I2C Bus Interface (RIIC) maintainers: - Chris Brandt @@ -17,9 +17,10 @@ properties: compatible: items: - enum: - - renesas,riic-r7s72100 # RZ/A1H - - renesas,riic-r7s9210 # RZ/A2M - - const: renesas,riic-rz # RZ/A + - renesas,riic-r7s72100 # RZ/A1H + - renesas,riic-r7s9210 # RZ/A2M + - renesas,riic-r9a07g044 # RZ/G2{L,LC} + - const: renesas,riic-rz # RZ/A or RZ/G2L reg: maxItems: 1 @@ -56,6 +57,16 @@ required: - '#address-cells' - '#size-cells' +if: + properties: + compatible: + contains: + enum: + - renesas,riic-r9a07g044 +then: + required: + - resets + unevaluatedProperties: false examples: -- cgit From 010e765b406f8e08685ea5b687c63a5ea234719a Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 15 Jun 2021 09:54:00 +0100 Subject: i2c: riic: Add RZ/G2L support RZ/G2L i2c controller is compatible with RZ/A i2c controller. By default IP is in reset state, so need to perform release reset before accessing any register. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Reviewed-by: Philipp Zabel Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-riic.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c index 4eccc0f69861..78b84445ee6a 100644 --- a/drivers/i2c/busses/i2c-riic.c +++ b/drivers/i2c/busses/i2c-riic.c @@ -42,8 +42,10 @@ #include #include #include +#include #include #include +#include #define RIIC_ICCR1 0x00 #define RIIC_ICCR2 0x04 @@ -86,6 +88,11 @@ #define RIIC_INIT_MSG -1 +enum riic_type { + RIIC_RZ_A, + RIIC_RZ_G2L, +}; + struct riic_dev { void __iomem *base; u8 *buf; @@ -395,7 +402,9 @@ static int riic_i2c_probe(struct platform_device *pdev) struct i2c_adapter *adap; struct resource *res; struct i2c_timings i2c_t; + struct reset_control *rstc; int i, ret; + enum riic_type type; riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL); if (!riic) @@ -412,6 +421,17 @@ static int riic_i2c_probe(struct platform_device *pdev) return PTR_ERR(riic->clk); } + type = (enum riic_type)of_device_get_match_data(&pdev->dev); + if (type == RIIC_RZ_G2L) { + rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(rstc)) { + dev_err(&pdev->dev, "Error: missing reset ctrl\n"); + return PTR_ERR(rstc); + } + + reset_control_deassert(rstc); + } + for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) { res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num); if (!res) @@ -472,7 +492,8 @@ static int riic_i2c_remove(struct platform_device *pdev) } static const struct of_device_id riic_i2c_dt_ids[] = { - { .compatible = "renesas,riic-rz" }, + { .compatible = "renesas,riic-r9a07g044", .data = (void *)RIIC_RZ_G2L }, + { .compatible = "renesas,riic-rz", .data = (void *)RIIC_RZ_A }, { /* Sentinel */ }, }; -- cgit From e11654ec22a3e00975a499fcfdbf0407e2d41b60 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Jun 2021 20:30:35 +0300 Subject: i2c: cht-wc: Replace of_node by NULL The driver is run on the platforms where OF node is always NULL. The confusion comes from IRQ domain APIs that take either OF or firmware node as input parameter. Since fwnode is not used here either, replace of_node by NULL. Signed-off-by: Andy Shevchenko Reviewed-by: Hans de Goede Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-cht-wc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c index 08f491ea21ac..1cf68f85b2e1 100644 --- a/drivers/i2c/busses/i2c-cht-wc.c +++ b/drivers/i2c/busses/i2c-cht-wc.c @@ -354,8 +354,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev) return ret; /* Alloc and register client IRQ */ - adap->irq_domain = irq_domain_add_linear(pdev->dev.of_node, 1, - &irq_domain_simple_ops, NULL); + adap->irq_domain = irq_domain_add_linear(NULL, 1, &irq_domain_simple_ops, NULL); if (!adap->irq_domain) return -ENOMEM; -- cgit From 44c54c4ec391412c7f529e53d27844dadc6d536a Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 25 May 2021 21:59:05 +0200 Subject: i2c: i801: Improve status polling Polling uses the same timeout as irq mode: 400 * 500us = 200ms = HZ / 5. So let's use the adapter->timeout value also for polling. This has the advantage that userspace can control the timeout value for polling as well. In addition change the code to make it better readable. Last but not least remove the timeout debug messages. Calls to both functions are followed by a call to i801_check_post() that will print an error message in case of timeout. Signed-off-by: Heiner Kallweit Reviewed-by: Jean Delvare Tested-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index f6d7866f11c3..2c6e84108013 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -156,9 +156,6 @@ #define SMBAUXCTL_CRC BIT(0) #define SMBAUXCTL_E32B BIT(1) -/* Other settings */ -#define MAX_RETRIES 400 - /* I801 command constants */ #define I801_QUICK 0x00 #define I801_BYTE 0x04 @@ -447,42 +444,35 @@ static int i801_check_post(struct i801_priv *priv, int status) /* Wait for BUSY being cleared and either INTR or an error flag being set */ static int i801_wait_intr(struct i801_priv *priv) { - int timeout = 0; - int status; + unsigned long timeout = jiffies + priv->adapter.timeout; + int status, busy; - /* We will always wait for a fraction of a second! */ do { usleep_range(250, 500); status = inb_p(SMBHSTSTS(priv)); - } while (((status & SMBHSTSTS_HOST_BUSY) || - !(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR))) && - (timeout++ < MAX_RETRIES)); + busy = status & SMBHSTSTS_HOST_BUSY; + status &= STATUS_ERROR_FLAGS | SMBHSTSTS_INTR; + if (!busy && status) + return status; + } while (time_is_after_eq_jiffies(timeout)); - if (timeout > MAX_RETRIES) { - dev_dbg(&priv->pci_dev->dev, "INTR Timeout!\n"); - return -ETIMEDOUT; - } - return status & (STATUS_ERROR_FLAGS | SMBHSTSTS_INTR); + return -ETIMEDOUT; } /* Wait for either BYTE_DONE or an error flag being set */ static int i801_wait_byte_done(struct i801_priv *priv) { - int timeout = 0; + unsigned long timeout = jiffies + priv->adapter.timeout; int status; - /* We will always wait for a fraction of a second! */ do { usleep_range(250, 500); status = inb_p(SMBHSTSTS(priv)); - } while (!(status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) && - (timeout++ < MAX_RETRIES)); + if (status & (STATUS_ERROR_FLAGS | SMBHSTSTS_BYTE_DONE)) + return status & STATUS_ERROR_FLAGS; + } while (time_is_after_eq_jiffies(timeout)); - if (timeout > MAX_RETRIES) { - dev_dbg(&priv->pci_dev->dev, "BYTE_DONE Timeout!\n"); - return -ETIMEDOUT; - } - return status & STATUS_ERROR_FLAGS; + return -ETIMEDOUT; } static int i801_transaction(struct i801_priv *priv, int xact) -- cgit From 8d83973e7a85b2fab168894ea327dfd4e6ef596e Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 25 May 2021 22:01:31 +0200 Subject: i2c: i801: Simplify initialization of i2c_board_info in i801_probe_optional_slaves Why shall we bother to open-code something that the compiler can do for us. Signed-off-by: Heiner Kallweit Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 2c6e84108013..9b40ea74e325 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1289,11 +1289,11 @@ static void i801_probe_optional_slaves(struct i801_priv *priv) return; if (apanel_addr) { - struct i2c_board_info info; + struct i2c_board_info info = { + .addr = apanel_addr, + .type = "fujitsu_apanel", + }; - memset(&info, 0, sizeof(struct i2c_board_info)); - info.addr = apanel_addr; - strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE); i2c_new_client_device(&priv->adapter, &info); } -- cgit From d4a994f69f0bed0ba49db12d7bae2c891dc4b51f Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 25 May 2021 22:04:23 +0200 Subject: i2c: i801: Use driver name constant instead of function dev_driver_string We are the driver, so we can use the driver name directly instead of retrieving it by calling dev_driver_string(). Signed-off-by: Heiner Kallweit Reviewed-by: Jean Delvare Tested-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 9b40ea74e325..6f056ef62151 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -88,6 +88,8 @@ * See the file Documentation/i2c/busses/i2c-i801.rst for details. */ +#define DRV_NAME "i801_smbus" + #include #include #include @@ -1805,8 +1807,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) if (i801_acpi_probe(priv)) return -ENODEV; - err = pcim_iomap_regions(dev, 1 << SMBBAR, - dev_driver_string(&dev->dev)); + 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", @@ -1864,8 +1865,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) init_completion(&priv->done); err = devm_request_irq(&dev->dev, dev->irq, i801_isr, - IRQF_SHARED, - dev_driver_string(&dev->dev), priv); + IRQF_SHARED, DRV_NAME, priv); if (err) { dev_err(&dev->dev, "Failed to allocate irq %d: %d\n", dev->irq, err); @@ -1955,7 +1955,7 @@ static int i801_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(i801_pm_ops, i801_suspend, i801_resume); static struct pci_driver i801_driver = { - .name = "i801_smbus", + .name = DRV_NAME, .id_table = i801_ids, .probe = i801_probe, .remove = i801_remove, -- cgit From c601610cd73d4cfc2dcbae185c134deb7c4c52cc Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 25 May 2021 22:07:17 +0200 Subject: i2c: i801: Improve i801_setup_hstcfg i801_setup_hstcfg() leaves the bits in priv->original_hstcfg that we're interested in intact. Therefore we can remove the return value from the function and use priv->original_hstcfg directly. Signed-off-by: Heiner Kallweit Reviewed-by: Jean Delvare Tested-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-i801.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 6f056ef62151..75037afe7c0a 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1684,19 +1684,17 @@ static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; } static inline void i801_acpi_remove(struct i801_priv *priv) { } #endif -static unsigned char i801_setup_hstcfg(struct i801_priv *priv) +static void i801_setup_hstcfg(struct i801_priv *priv) { unsigned char hstcfg = priv->original_hstcfg; hstcfg &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ hstcfg |= SMBHSTCFG_HST_EN; pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg); - return hstcfg; } static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) { - unsigned char temp; int err, i; struct i801_priv *priv; @@ -1818,16 +1816,16 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) } pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg); - temp = i801_setup_hstcfg(priv); + i801_setup_hstcfg(priv); if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN)) dev_info(&dev->dev, "Enabling SMBus device\n"); - if (temp & SMBHSTCFG_SMB_SMI_EN) { + if (priv->original_hstcfg & SMBHSTCFG_SMB_SMI_EN) { dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); /* Disable SMBus interrupt feature if SMBus using SMI# */ priv->features &= ~FEATURE_IRQ; } - if (temp & SMBHSTCFG_SPD_WD) + if (priv->original_hstcfg & SMBHSTCFG_SPD_WD) dev_info(&dev->dev, "SPD Write Disable is set\n"); /* Clear special mode bits */ -- cgit From 4aa908fe4704ef9c09a6b2c19b4b49855a3d6055 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 1 Jun 2021 17:25:44 +0200 Subject: dt-bindings: i2c: ce4100: Replace "ti,pcf8575" by "nxp,pcf8575" The TI part is equivalent to the NXP part, and its compatible value is not documented in the DT bindings. Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt index 569b16248514..1ff6f8487a2d 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt @@ -71,7 +71,7 @@ This is an example which is used on FalconFalls: /* This I2C controller has one gpio controller */ gpio@26 { #gpio-cells = <2>; - compatible = "ti,pcf8575"; + compatible = "nxp,pcf8575"; reg = <0x26>; gpio-controller; }; @@ -85,7 +85,7 @@ This is an example which is used on FalconFalls: gpio@26 { #gpio-cells = <2>; - compatible = "ti,pcf8575"; + compatible = "nxp,pcf8575"; reg = <0x26>; gpio-controller; }; -- cgit From dd66b39f600b0c4d17008226e76ff0f98a2ef674 Mon Sep 17 00:00:00 2001 From: Raviteja Narayanam Date: Tue, 24 Nov 2020 13:16:05 +0530 Subject: i2c: cadence: Clear HOLD bit before xfer_size register rolls over On Xilinx zynq SOC if the delay between address register write and control register write in cdns_mrecv function is more, the xfer size register rolls over and controller is stuck. This is an IP bug and is resolved in later versions of IP. To avoid this scenario, disable the interrupts on the current processor core between the two register writes and enable them later. This can help achieve the timing constraint. Signed-off-by: Raviteja Narayanam Acked-by: Michal Simek Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-cadence.c | 48 ++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index c1bbc4caeb5c..5a14f0265669 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -578,6 +578,11 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) { unsigned int ctrl_reg; unsigned int isr_status; + unsigned long flags; + bool hold_clear = false; + bool irq_save = false; + + u32 addr; id->p_recv_buf = id->p_msg->buf; id->recv_count = id->p_msg->len; @@ -618,14 +623,43 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id) cdns_i2c_writereg(id->recv_count, CDNS_I2C_XFER_SIZE_OFFSET); } - /* Set the slave address in address register - triggers operation */ - cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK, - CDNS_I2C_ADDR_OFFSET); - /* Clear the bus hold flag if bytes to receive is less than FIFO size */ + /* Determine hold_clear based on number of bytes to receive and hold flag */ if (!id->bus_hold_flag && - ((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) && - (id->recv_count <= CDNS_I2C_FIFO_DEPTH)) - cdns_i2c_clear_bus_hold(id); + ((id->p_msg->flags & I2C_M_RECV_LEN) != I2C_M_RECV_LEN) && + (id->recv_count <= CDNS_I2C_FIFO_DEPTH)) { + if (cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & CDNS_I2C_CR_HOLD) { + hold_clear = true; + if (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT) + irq_save = true; + } + } + + addr = id->p_msg->addr; + addr &= CDNS_I2C_ADDR_MASK; + + if (hold_clear) { + ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET) & ~CDNS_I2C_CR_HOLD; + /* + * In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size + * register reaches '0'. This is an IP bug which causes transfer size + * register overflow to 0xFF. To satisfy this timing requirement, + * disable the interrupts on current processor core between register + * writes to slave address register and control register. + */ + if (irq_save) + local_irq_save(flags); + + cdns_i2c_writereg(addr, CDNS_I2C_ADDR_OFFSET); + cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); + /* Read it back to avoid bufferring and make sure write happens */ + cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); + + if (irq_save) + local_irq_restore(flags); + } else { + cdns_i2c_writereg(addr, CDNS_I2C_ADDR_OFFSET); + } + cdns_i2c_writereg(CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET); } -- cgit From 9dbba3f87c7823cf35e63fb7a2449a5d54b3b799 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 2 Sep 2020 17:06:36 +0200 Subject: i2c: xiic: Simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and the error value gets printed. Signed-off-by: Krzysztof Kozlowski Acked-by: Michal Simek Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-xiic.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 2a8568b97c14..bb93db98404e 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -798,11 +798,10 @@ static int xiic_i2c_probe(struct platform_device *pdev) init_waitqueue_head(&i2c->wait); i2c->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(i2c->clk)) { - if (PTR_ERR(i2c->clk) != -EPROBE_DEFER) - dev_err(&pdev->dev, "input clock not found.\n"); - return PTR_ERR(i2c->clk); - } + if (IS_ERR(i2c->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk), + "input clock not found.\n"); + ret = clk_prepare_enable(i2c->clk); if (ret) { dev_err(&pdev->dev, "Unable to enable clock.\n"); -- cgit From 2d1a83a4f36f1a6fd8c510db409772e34bf4eed1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 2 Sep 2020 17:06:38 +0200 Subject: i2c: cadence: Simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and the error value gets printed. Signed-off-by: Krzysztof Kozlowski Acked-by: Michal Simek Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-cadence.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 5a14f0265669..565401bfbcc6 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -1251,11 +1251,10 @@ static int cdns_i2c_probe(struct platform_device *pdev) "Cadence I2C at %08lx", (unsigned long)r_mem->start); id->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(id->clk)) { - if (PTR_ERR(id->clk) != -EPROBE_DEFER) - dev_err(&pdev->dev, "input clock not found.\n"); - return PTR_ERR(id->clk); - } + if (IS_ERR(id->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(id->clk), + "input clock not found.\n"); + ret = clk_prepare_enable(id->clk); if (ret) dev_err(&pdev->dev, "Unable to enable clock.\n"); -- cgit From cc883cdf68f5e4d437450e1696953c6bbdff6c6b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 2 Sep 2020 17:06:39 +0200 Subject: i2c: davinci: Simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and the error value gets printed. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-davinci.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 232a7679b69b..e9d07323c604 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -768,10 +768,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) if (irq <= 0) { if (!irq) irq = -ENXIO; - if (irq != -EPROBE_DEFER) - dev_err(&pdev->dev, - "can't get irq resource ret=%d\n", irq); - return irq; + return dev_err_probe(&pdev->dev, irq, "can't get irq resource\n"); } dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev), -- cgit From 2f799b25dbaa75027041f55db49a14c59f3116aa Mon Sep 17 00:00:00 2001 From: Kwon Tae-young Date: Wed, 23 Jun 2021 17:36:43 +0900 Subject: i2c: imx: Fix some checkpatch warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following warnings reported by checkpatch:: drivers/i2c/busses/i2c-imx.c:173: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' drivers/i2c/busses/i2c-imx.c:175: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' drivers/i2c/busses/i2c-imx.c:176: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' drivers/i2c/busses/i2c-imx.c:177: WARNING: Prefer 'unsigned int' to bare use of 'unsigned' drivers/i2c/busses/i2c-imx.c:455: WARNING: Unnecessary ftrace-like logging - prefer using ftrace drivers/i2c/busses/i2c-imx.c:602: WARNING: Unnecessary ftrace-like logging - prefer using ftrace drivers/i2c/busses/i2c-imx.c:638: WARNING: Unnecessary ftrace-like logging - prefer using ftrace drivers/i2c/busses/i2c-imx.c:1170: WARNING: Unnecessary ftrace-like logging - prefer using ftrace drivers/i2c/busses/i2c-imx.c:1374: WARNING: Unnecessary ftrace-like logging - prefer using ftrace drivers/i2c/busses/i2c-imx.c:1398: WARNING: Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/ Signed-off-by: Kwon Tae-young Reviewed-by: Uwe Kleine-König Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-imx.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index dc5ca71906db..d5b5f084a27d 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -170,11 +170,11 @@ enum imx_i2c_type { struct imx_i2c_hwdata { enum imx_i2c_type devtype; - unsigned regshift; + unsigned int regshift; struct imx_i2c_clk_pair *clk_div; - unsigned ndivs; - unsigned i2sr_clr_opcode; - unsigned i2cr_ien_opcode; + unsigned int ndivs; + unsigned int i2sr_clr_opcode; + unsigned int i2cr_ien_opcode; }; struct imx_i2c_dma { @@ -452,8 +452,6 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool a unsigned long orig_jiffies = jiffies; unsigned int temp; - dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); - while (1) { temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR); @@ -599,8 +597,6 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx, bool atomic) unsigned int temp = 0; int result; - dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); - imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR); /* Enable I2C controller */ imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR); @@ -635,7 +631,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic) if (!i2c_imx->stopped) { /* Stop I2C transaction */ - dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); if (!(temp & I2CR_MSTA)) i2c_imx->stopped = 1; @@ -1167,8 +1162,6 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter, bool is_lastmsg = false; struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter); - dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); - /* Start I2C transfer */ result = i2c_imx_start(i2c_imx, atomic); if (result) { @@ -1371,8 +1364,6 @@ static int i2c_imx_probe(struct platform_device *pdev) dma_addr_t phy_addr; const struct imx_i2c_hwdata *match; - dev_dbg(&pdev->dev, "<%s>\n", __func__); - irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; @@ -1395,7 +1386,7 @@ static int i2c_imx_probe(struct platform_device *pdev) platform_get_device_id(pdev)->driver_data; /* Setup i2c_imx driver structure */ - strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name)); + strscpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name)); i2c_imx->adapter.owner = THIS_MODULE; i2c_imx->adapter.algo = &i2c_imx_algo; i2c_imx->adapter.dev.parent = &pdev->dev; -- cgit From b05c8922c98de489f52e5d327837857e35d25422 Mon Sep 17 00:00:00 2001 From: "Kewei.Xu" Date: Tue, 8 Jun 2021 11:16:38 +0800 Subject: dt-bindings: i2c: update bindings for MT8195 SoC Add a DT binding documentation for the MT8195 soc. Signed-off-by: Kewei.Xu Reviewed-by: Matthias Brugger Acked-by: Rob Herring Signed-off-by: Wolfram Sang --- Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt index 2c45647e9f0b..5ea216ae7084 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt @@ -15,6 +15,7 @@ Required properties: "mediatek,mt8173-i2c": for MediaTek MT8173 "mediatek,mt8183-i2c": for MediaTek MT8183 "mediatek,mt8192-i2c": for MediaTek MT8192 + "mediatek,mt8195-i2c", "mediatek,mt8192-i2c": for MediaTek MT8195 "mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516 - reg: physical base address of the controller and dma base, length of memory mapped region. -- cgit From b64210f2f7c11c757432ba3701d88241b2b98fb1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 4 Jun 2021 16:27:44 -0700 Subject: i2c: core: Disable client irq on reboot/shutdown If an i2c client receives an interrupt during reboot or shutdown it may be too late to service it by making an i2c transaction on the bus because the i2c controller has already been shutdown. This can lead to system hangs if the i2c controller tries to make a transfer that is doomed to fail because the access to the i2c pins is already shut down, or an iommu translation has been torn down so i2c controller register access doesn't work. Let's simply disable the irq if there isn't a shutdown callback for an i2c client when there is an irq associated with the device. This will make sure that irqs don't come in later than the time that we can handle it. We don't do this if the i2c client device already has a shutdown callback because presumably they're doing the right thing and quieting the device so irqs don't come in after the shutdown callback returns. Reported-by: kernel test robot [swboyd@chromium.org: Dropped newline, added commit text, added interrupt.h for robot build error] Signed-off-by: Stephen Boyd Signed-off-by: Dmitry Torokhov Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 2a222e495c70..84f12bf90644 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -725,6 +726,8 @@ static void i2c_device_shutdown(struct device *dev) driver = to_i2c_driver(dev->driver); if (driver->shutdown) driver->shutdown(client); + else if (client->irq > 0) + disable_irq(client->irq); } static void i2c_client_dev_release(struct device *dev) -- cgit From 31df7195b100f7e7b7ac07675d93b3b504400fe9 Mon Sep 17 00:00:00 2001 From: Alex Qiu Date: Mon, 17 May 2021 16:56:05 -0700 Subject: Documentation: i2c: Add doc for I2C sysfs This doc helps Linux users navigate through I2C sysfs and learn the system I2C topology. Signed-off-by: Alex Qiu Reviewed-by: Guenter Roeck Signed-off-by: Wolfram Sang --- Documentation/i2c/i2c-sysfs.rst | 395 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 395 insertions(+) create mode 100644 Documentation/i2c/i2c-sysfs.rst diff --git a/Documentation/i2c/i2c-sysfs.rst b/Documentation/i2c/i2c-sysfs.rst new file mode 100644 index 000000000000..6b68b95cd427 --- /dev/null +++ b/Documentation/i2c/i2c-sysfs.rst @@ -0,0 +1,395 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=============== +Linux I2C Sysfs +=============== + +Overview +======== + +I2C topology can be complex because of the existence of I2C MUX +(I2C Multiplexer). The Linux +kernel abstracts the MUX channels into logical I2C bus numbers. However, there +is a gap of knowledge to map from the I2C bus physical number and MUX topology +to logical I2C bus number. This doc is aimed to fill in this gap, so the +audience (hardware engineers and new software developers for example) can learn +the concept of logical I2C buses in the kernel, by knowing the physical I2C +topology and navigating through the I2C sysfs in Linux shell. This knowledge is +useful and essential to use ``i2c-tools`` for the purpose of development and +debugging. + +Target audience +--------------- + +People who need to use Linux shell to interact with I2C subsystem on a system +which the Linux is running on. + +Prerequisites +------------- + +1. Knowledge of general Linux shell file system commands and operations. + +2. General knowledge of I2C, I2C MUX and I2C topology. + +Location of I2C Sysfs +===================== + +Typically, the Linux Sysfs filesystem is mounted at the ``/sys`` directory, +so you can find the I2C Sysfs under ``/sys/bus/i2c/devices`` +where you can directly ``cd`` to it. +There is a list of symbolic links under that directory. The links that +start with ``i2c-`` are I2C buses, which may be either physical or logical. The +other links that begin with numbers and end with numbers are I2C devices, where +the first number is I2C bus number, and the second number is I2C address. + +Google Pixel 3 phone for example:: + + blueline:/sys/bus/i2c/devices $ ls + 0-0008 0-0061 1-0028 3-0043 4-0036 4-0041 i2c-1 i2c-3 + 0-000c 0-0066 2-0049 4-000b 4-0040 i2c-0 i2c-2 i2c-4 + +``i2c-2`` is an I2C bus whose number is 2, and ``2-0049`` is an I2C device +on bus 2 address 0x49 bound with a kernel driver. + +Terminologies +============= + +First, let us define a couple of terminologies to avoid confusions in the later +sections. + +(Physical) I2C Bus Controller +----------------------------- + +The hardware system that the Linux kernel is running on may have multiple +physical I2C bus controllers. The controllers are hardware and physical, and the +system may define multiple registers in the memory space to manipulate the +controllers. Linux kernel has I2C bus drivers under source directory +``drivers/i2c/busses`` to translate kernel I2C API into register +operations for different systems. This terminology is not limited to Linux +kernel only. + +I2C Bus Physical Number +----------------------- + +For each physical I2C bus controller, the system vendor may assign a physical +number to each controller. For example, the first I2C bus controller which has +the lowest register addresses may be called ``I2C-0``. + +Logical I2C Bus +--------------- + +Every I2C bus number you see in Linux I2C Sysfs is a logical I2C bus with a +number assigned. This is similar to the fact that software code is usually +written upon virtual memory space, instead of physical memory space. + +Each logical I2C bus may be an abstraction of a physical I2C bus controller, or +an abstraction of a channel behind an I2C MUX. In case it is an abstraction of a +MUX channel, whenever we access an I2C device via a such logical bus, the kernel +will switch the I2C MUX for you to the proper channel as part of the +abstraction. + +Physical I2C Bus +---------------- + +If the logical I2C bus is a direct abstraction of a physical I2C bus controller, +let us call it a physical I2C bus. + +Caveat +------ + +This may be a confusing part for people who only know about the physical I2C +design of a board. It is actually possible to rename the I2C bus physical number +to a different number in logical I2C bus level in Device Tree Source (DTS) under +section ``aliases``. See +`arch/arm/boot/dts/nuvoton-npcm730-gsj.dts +<../../arch/arm/boot/dts/nuvoton-npcm730-gsj.dts>`_ +for an example of DTS file. + +Best Practice: **(To kernel software developers)** It is better to keep the I2C +bus physical number the same as their corresponding logical I2C bus number, +instead of renaming or mapping them, so that it may be less confusing to other +users. These physical I2C buses can be served as good starting points for I2C +MUX fanouts. For the following examples, we will assume that the physical I2C +bus has a number same as their I2C bus physical number. + +Walk through Logical I2C Bus +============================ + +For the following content, we will use a more complex I2C topology as an +example. Here is a brief graph for the I2C topology. If you do not understand +this graph at the first glance, do not be afraid to continue reading this doc +and review it when you finish reading. + +:: + + i2c-7 (physical I2C bus controller 7) + `-- 7-0071 (4-channel I2C MUX at 0x71) + |-- i2c-60 (channel-0) + |-- i2c-73 (channel-1) + | |-- 73-0040 (I2C sensor device with hwmon directory) + | |-- 73-0070 (I2C MUX at 0x70, exists in DTS, but failed to probe) + | `-- 73-0072 (8-channel I2C MUX at 0x72) + | |-- i2c-78 (channel-0) + | |-- ... (channel-1...6, i2c-79...i2c-84) + | `-- i2c-85 (channel-7) + |-- i2c-86 (channel-2) + `-- i2c-203 (channel-3) + +Distinguish Physical and Logical I2C Bus +---------------------------------------- + +One simple way to distinguish between a physical I2C bus and a logical I2C bus, +is to read the symbolic link ``device`` under the I2C bus directory by using +command ``ls -l`` or ``readlink``. + +An alternative symbolic link to check is ``mux_device``. This link only exists +in logical I2C bus directory which is fanned out from another I2C bus. +Reading this link will also tell you which I2C MUX device created +this logical I2C bus. + +If the symbolic link points to a directory ending with ``.i2c``, it should be a +physical I2C bus, directly abstracting a physical I2C bus controller. For +example:: + + $ readlink /sys/bus/i2c/devices/i2c-7/device + ../../f0087000.i2c + $ ls /sys/bus/i2c/devices/i2c-7/mux_device + ls: /sys/bus/i2c/devices/i2c-7/mux_device: No such file or directory + +In this case, ``i2c-7`` is a physical I2C bus, so it does not have the symbolic +link ``mux_device`` under its directory. And if the kernel software developer +follows the common practice by not renaming physical I2C buses, this should also +mean the physical I2C bus controller 7 of the system. + +On the other hand, if the symbolic link points to another I2C bus, the I2C bus +presented by the current directory has to be a logical bus. The I2C bus pointed +by the link is the parent bus which may be either a physical I2C bus or a +logical one. In this case, the I2C bus presented by the current directory +abstracts an I2C MUX channel under the parent bus. + +For example:: + + $ readlink /sys/bus/i2c/devices/i2c-73/device + ../../i2c-7 + $ readlink /sys/bus/i2c/devices/i2c-73/mux_device + ../7-0071 + +``i2c-73`` is a logical bus fanout by an I2C MUX under ``i2c-7`` +whose I2C address is 0x71. +Whenever we access an I2C device with bus 73, the kernel will always +switch the I2C MUX addressed 0x71 to the proper channel for you as part of the +abstraction. + +Finding out Logical I2C Bus Number +---------------------------------- + +In this section, we will describe how to find out the logical I2C bus number +representing certain I2C MUX channels based on the knowledge of physical +hardware I2C topology. + +In this example, we have a system which has a physical I2C bus 7 and not renamed +in DTS. There is a 4-channel MUX at address 0x71 on that bus. There is another +8-channel MUX at address 0x72 behind the channel 1 of the 0x71 MUX. Let us +navigate through Sysfs and find out the logical I2C bus number of the channel 3 +of the 0x72 MUX. + +First of all, let us go to the directory of ``i2c-7``:: + + ~$ cd /sys/bus/i2c/devices/i2c-7 + /sys/bus/i2c/devices/i2c-7$ ls + 7-0071 i2c-60 name subsystem + delete_device i2c-73 new_device uevent + device i2c-86 of_node + i2c-203 i2c-dev power + +There, we see the 0x71 MUX as ``7-0071``. Go inside it:: + + /sys/bus/i2c/devices/i2c-7$ cd 7-0071/ + /sys/bus/i2c/devices/i2c-7/7-0071$ ls -l + channel-0 channel-3 modalias power + channel-1 driver name subsystem + channel-2 idle_state of_node uevent + +Read the link ``channel-1`` using ``readlink`` or ``ls -l``:: + + /sys/bus/i2c/devices/i2c-7/7-0071$ readlink channel-1 + ../i2c-73 + +We find out that the channel 1 of 0x71 MUX on ``i2c-7`` is assigned +with a logical I2C bus number of 73. +Let us continue the journey to directory ``i2c-73`` in either ways:: + + # cd to i2c-73 under I2C Sysfs root + /sys/bus/i2c/devices/i2c-7/7-0071$ cd /sys/bus/i2c/devices/i2c-73 + /sys/bus/i2c/devices/i2c-73$ + + # cd the channel symbolic link + /sys/bus/i2c/devices/i2c-7/7-0071$ cd channel-1 + /sys/bus/i2c/devices/i2c-7/7-0071/channel-1$ + + # cd the link content + /sys/bus/i2c/devices/i2c-7/7-0071$ cd ../i2c-73 + /sys/bus/i2c/devices/i2c-7/i2c-73$ + +Either ways, you will end up in the directory of ``i2c-73``. Similar to above, +we can now find the 0x72 MUX and what logical I2C bus numbers +that its channels are assigned:: + + /sys/bus/i2c/devices/i2c-73$ ls + 73-0040 device i2c-83 new_device + 73-004e i2c-78 i2c-84 of_node + 73-0050 i2c-79 i2c-85 power + 73-0070 i2c-80 i2c-dev subsystem + 73-0072 i2c-81 mux_device uevent + delete_device i2c-82 name + /sys/bus/i2c/devices/i2c-73$ cd 73-0072 + /sys/bus/i2c/devices/i2c-73/73-0072$ ls + channel-0 channel-4 driver of_node + channel-1 channel-5 idle_state power + channel-2 channel-6 modalias subsystem + channel-3 channel-7 name uevent + /sys/bus/i2c/devices/i2c-73/73-0072$ readlink channel-3 + ../i2c-81 + +There, we find out the logical I2C bus number of the channel 3 of the 0x72 MUX +is 81. We can later use this number to switch to its own I2C Sysfs directory or +issue ``i2c-tools`` commands. + +Tip: Once you understand the I2C topology with MUX, command +`i2cdetect -l +`_ +in +`I2C Tools +`_ +can give you +an overview of the I2C topology easily, if it is available on your system. For +example:: + + $ i2cdetect -l | grep -e '\-73' -e _7 | sort -V + i2c-7 i2c npcm_i2c_7 I2C adapter + i2c-73 i2c i2c-7-mux (chan_id 1) I2C adapter + i2c-78 i2c i2c-73-mux (chan_id 0) I2C adapter + i2c-79 i2c i2c-73-mux (chan_id 1) I2C adapter + i2c-80 i2c i2c-73-mux (chan_id 2) I2C adapter + i2c-81 i2c i2c-73-mux (chan_id 3) I2C adapter + i2c-82 i2c i2c-73-mux (chan_id 4) I2C adapter + i2c-83 i2c i2c-73-mux (chan_id 5) I2C adapter + i2c-84 i2c i2c-73-mux (chan_id 6) I2C adapter + i2c-85 i2c i2c-73-mux (chan_id 7) I2C adapter + +Pinned Logical I2C Bus Number +----------------------------- + +If not specified in DTS, when an I2C MUX driver is applied and the MUX device is +successfully probed, the kernel will assign the MUX channels with a logical bus +number based on the current biggest logical bus number incrementally. For +example, if the system has ``i2c-15`` as the highest logical bus number, and a +4-channel MUX is applied successfully, we will have ``i2c-16`` for the +MUX channel 0, and all the way to ``i2c-19`` for the MUX channel 3. + +The kernel software developer is able to pin the fanout MUX channels to a static +logical I2C bus number in the DTS. This doc will not go through the details on +how to implement this in DTS, but we can see an example in: +`arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts +<../../arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts>`_ + +In the above example, there is an 8-channel I2C MUX at address 0x70 on physical +I2C bus 2. The channel 2 of the MUX is defined as ``imux18`` in DTS, +and pinned to logical I2C bus number 18 with the line of ``i2c18 = &imux18;`` +in section ``aliases``. + +Take it further, it is possible to design a logical I2C bus number schema that +can be easily remembered by humans or calculated arithmetically. For example, we +can pin the fanout channels of a MUX on bus 3 to start at 30. So 30 will be the +logical bus number of the channel 0 of the MUX on bus 3, and 37 will be the +logical bus number of the channel 7 of the MUX on bus 3. + +I2C Devices +=========== + +In previous sections, we mostly covered the I2C bus. In this section, let us see +what we can learn from the I2C device directory whose link name is in the format +of ``${bus}-${addr}``. The ``${bus}`` part in the name is a logical I2C bus +decimal number, while the ``${addr}`` part is a hex number of the I2C address +of each device. + +I2C Device Directory Content +---------------------------- + +Inside each I2C device directory, there is a file named ``name``. +This file tells what device name it was used for the kernel driver to +probe this device. Use command ``cat`` to read its content. For example:: + + /sys/bus/i2c/devices/i2c-73$ cat 73-0040/name + ina230 + /sys/bus/i2c/devices/i2c-73$ cat 73-0070/name + pca9546 + /sys/bus/i2c/devices/i2c-73$ cat 73-0072/name + pca9547 + +There is a symbolic link named ``driver`` to tell what Linux kernel driver was +used to probe this device:: + + /sys/bus/i2c/devices/i2c-73$ readlink -f 73-0040/driver + /sys/bus/i2c/drivers/ina2xx + /sys/bus/i2c/devices/i2c-73$ readlink -f 73-0072/driver + /sys/bus/i2c/drivers/pca954x + +But if the link ``driver`` does not exist at the first place, +it may mean that the kernel driver failed to probe this device due to +some errors. The error may be found in ``dmesg``:: + + /sys/bus/i2c/devices/i2c-73$ ls 73-0070/driver + ls: 73-0070/driver: No such file or directory + /sys/bus/i2c/devices/i2c-73$ dmesg | grep 73-0070 + pca954x 73-0070: probe failed + pca954x 73-0070: probe failed + +Depending on what the I2C device is and what kernel driver was used to probe the +device, we may have different content in the device directory. + +I2C MUX Device +-------------- + +While you may be already aware of this in previous sections, an I2C MUX device +will have symbolic link ``channel-*`` inside its device directory. +These symbolic links point to their logical I2C bus directories:: + + /sys/bus/i2c/devices/i2c-73$ ls -l 73-0072/channel-* + lrwxrwxrwx ... 73-0072/channel-0 -> ../i2c-78 + lrwxrwxrwx ... 73-0072/channel-1 -> ../i2c-79 + lrwxrwxrwx ... 73-0072/channel-2 -> ../i2c-80 + lrwxrwxrwx ... 73-0072/channel-3 -> ../i2c-81 + lrwxrwxrwx ... 73-0072/channel-4 -> ../i2c-82 + lrwxrwxrwx ... 73-0072/channel-5 -> ../i2c-83 + lrwxrwxrwx ... 73-0072/channel-6 -> ../i2c-84 + lrwxrwxrwx ... 73-0072/channel-7 -> ../i2c-85 + +I2C Sensor Device / Hwmon +------------------------- + +I2C sensor device is also common to see. If they are bound by a kernel hwmon +(Hardware Monitoring) driver successfully, you will see a ``hwmon`` directory +inside the I2C device directory. Keep digging into it, you will find the Hwmon +Sysfs for the I2C sensor device:: + + /sys/bus/i2c/devices/i2c-73/73-0040/hwmon/hwmon17$ ls + curr1_input in0_lcrit_alarm name subsystem + device in1_crit power uevent + in0_crit in1_crit_alarm power1_crit update_interval + in0_crit_alarm in1_input power1_crit_alarm + in0_input in1_lcrit power1_input + in0_lcrit in1_lcrit_alarm shunt_resistor + +For more info on the Hwmon Sysfs, refer to the doc: + +`Naming and data format standards for sysfs files +<../hwmon/sysfs-interface.rst>`_ + +Instantiate I2C Devices in I2C Sysfs +------------------------------------ + +Refer to the doc: + +`How to instantiate I2C devices, Method 4: Instantiate from user-space +`_ -- cgit From 87cf5127968ab3c543ebd98253052b928f9b47da Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Wed, 19 May 2021 14:49:28 +0700 Subject: i2c: core-smbus: Expose PEC calculate function for generic use Expose the PEC calculation i2c_smbus_pec() for generic use. Signed-off-by: Quan Nguyen Acked-by: Matt Johnston Signed-off-by: Wolfram Sang --- drivers/i2c/i2c-core-smbus.c | 12 ++++++++++-- include/linux/i2c.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index d2d32c0fd8c3..e5b2d1465e7e 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c @@ -37,8 +37,15 @@ static u8 crc8(u16 data) return (u8)(data >> 8); } -/* Incremental CRC8 over count bytes in the array pointed to by p */ -static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count) +/** + * i2c_smbus_pec - Incremental CRC8 over the given input data array + * @crc: previous return crc8 value + * @p: pointer to data buffer. + * @count: number of bytes in data buffer. + * + * Incremental CRC8 over count bytes in the array pointed to by p + */ +u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count) { int i; @@ -46,6 +53,7 @@ static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count) crc = crc8((crc ^ p[i]) << 8); return crc; } +EXPORT_SYMBOL(i2c_smbus_pec); /* Assume a 7-bit address, which is reasonable for SMBus */ static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 953a4eecb88f..685f8c73d99e 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -148,6 +148,7 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, /* Now follow the 'nice' access routines. These also document the calling conventions of i2c_smbus_xfer. */ +u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count); s32 i2c_smbus_read_byte(const struct i2c_client *client); s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value); s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command); -- cgit From 763778cd79267dadf0ec7e044caf7563df0ab597 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Fri, 2 Jul 2021 15:27:24 +1200 Subject: i2c: mpc: Restore reread of I2C status register Prior to commit 1538d82f4647 ("i2c: mpc: Interrupt driven transfer") the old interrupt handler would reread MPC_I2C_SR after checking the CSR_MIF bit. When the driver was re-written this was removed as it seemed unnecessary. However as it turns out this is necessary for i2c devices which do clock stretching otherwise we end up thinking the bus is still busy when processing the interrupt. Fixes: 1538d82f4647 ("i2c: mpc: Interrupt driven transfer") Signed-off-by: Chris Packham Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 30d9e89a3db2..2ee4a9361e40 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -564,6 +564,8 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) status = readb(i2c->base + MPC_I2C_SR); if (status & CSR_MIF) { + /* Read again to allow register to stabilise */ + status = readb(i2c->base + MPC_I2C_SR); writeb(0, i2c->base + MPC_I2C_SR); mpc_i2c_do_intr(i2c, status); return IRQ_HANDLED; -- cgit From 9d6336831bdc78e5207eaf147cc17228b5e984c3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 25 Jun 2021 17:17:58 +0200 Subject: i2c: ali1535: mention that the device should not be disabled The comment from the i801 driver is valid here, too, so copy it. Reported-by: Jean Delvare Reviewed-by: Jean Delvare Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-ali1535.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index fb93152845f4..ee83c4581bce 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -508,6 +508,11 @@ static void ali1535_remove(struct pci_dev *dev) { i2c_del_adapter(&ali1535_adapter); release_region(ali1535_smba, ALI1535_SMB_IOSIZE); + + /* + * do not call pci_disable_device(dev) since it can cause hard hangs on + * some systems during power-off + */ } static struct pci_driver ali1535_driver = { -- cgit