Merge branch 'i2c-mux/for-next' of https://github.com/peda-r/i2c-mux into i2c/for-4.17
"These patches verify the device id of the PCA984x mux chips using
standardized (but rarely implemented) i2c device identification."
diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt
index a777477..e91dbaf 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt
@@ -14,6 +14,7 @@
"renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC.
"renesas,i2c-r8a7796" if the device is a part of a R8A7796 SoC.
"renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC.
+ "renesas,i2c-r8a77995" if the device is a part of a R8A77995 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.
diff --git a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
index 2243909..fc7e178 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
@@ -13,6 +13,7 @@
- "renesas,iic-r8a7794" (R-Car E2)
- "renesas,iic-r8a7795" (R-Car H3)
- "renesas,iic-r8a7796" (R-Car M3-W)
+ - "renesas,iic-r8a77965" (R-Car M3-N)
- "renesas,iic-sh73a0" (SH-Mobile AG5)
- "renesas,rcar-gen2-iic" (generic R-Car Gen2 or RZ/G1
compatible device)
diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index b024284..12ec8484 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -128,6 +128,10 @@
#define HSI2C_TIMEOUT_EN (1u << 31)
#define HSI2C_TIMEOUT_MASK 0xff
+/* I2C_MANUAL_CMD register bits */
+#define HSI2C_CMD_READ_DATA (1u << 4)
+#define HSI2C_CMD_SEND_STOP (1u << 2)
+
/* I2C_TRANS_STATUS register bits */
#define HSI2C_MASTER_BUSY (1u << 17)
#define HSI2C_SLAVE_BUSY (1u << 16)
@@ -441,12 +445,6 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
i2c->state = -ETIMEDOUT;
goto stop;
}
-
- trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
- if ((trans_status & HSI2C_MASTER_ST_MASK) == HSI2C_MASTER_ST_LOSE) {
- i2c->state = -EAGAIN;
- goto stop;
- }
} else if (int_status & HSI2C_INT_I2C) {
trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);
if (trans_status & HSI2C_NO_DEV_ACK) {
@@ -544,6 +542,57 @@ static int exynos5_i2c_wait_bus_idle(struct exynos5_i2c *i2c)
return -EBUSY;
}
+static void exynos5_i2c_bus_recover(struct exynos5_i2c *i2c)
+{
+ u32 val;
+
+ val = readl(i2c->regs + HSI2C_CTL) | HSI2C_RXCHON;
+ writel(val, i2c->regs + HSI2C_CTL);
+ val = readl(i2c->regs + HSI2C_CONF) & ~HSI2C_AUTO_MODE;
+ writel(val, i2c->regs + HSI2C_CONF);
+
+ /*
+ * Specification says master should send nine clock pulses. It can be
+ * emulated by sending manual read command (nine pulses for read eight
+ * bits + one pulse for NACK).
+ */
+ writel(HSI2C_CMD_READ_DATA, i2c->regs + HSI2C_MANUAL_CMD);
+ exynos5_i2c_wait_bus_idle(i2c);
+ writel(HSI2C_CMD_SEND_STOP, i2c->regs + HSI2C_MANUAL_CMD);
+ exynos5_i2c_wait_bus_idle(i2c);
+
+ val = readl(i2c->regs + HSI2C_CTL) & ~HSI2C_RXCHON;
+ writel(val, i2c->regs + HSI2C_CTL);
+ val = readl(i2c->regs + HSI2C_CONF) | HSI2C_AUTO_MODE;
+ writel(val, i2c->regs + HSI2C_CONF);
+}
+
+static void exynos5_i2c_bus_check(struct exynos5_i2c *i2c)
+{
+ unsigned long timeout;
+
+ if (i2c->variant->hw != HSI2C_EXYNOS7)
+ return;
+
+ /*
+ * HSI2C_MASTER_ST_LOSE state in EXYNOS7 variant before transaction
+ * indicates that bus is stuck (SDA is low). In such case bus recovery
+ * can be performed.
+ */
+ timeout = jiffies + msecs_to_jiffies(100);
+ for (;;) {
+ u32 st = readl(i2c->regs + HSI2C_TRANS_STATUS);
+
+ if ((st & HSI2C_MASTER_ST_MASK) != HSI2C_MASTER_ST_LOSE)
+ return;
+
+ if (time_is_before_jiffies(timeout))
+ return;
+
+ exynos5_i2c_bus_recover(i2c);
+ }
+}
+
/*
* exynos5_i2c_message_start: Configures the bus and starts the xfer
* i2c: struct exynos5_i2c pointer for the current bus
@@ -598,6 +647,8 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
writel(fifo_ctl, i2c->regs + HSI2C_FIFO_CTL);
writel(i2c_ctl, i2c->regs + HSI2C_CTL);
+ exynos5_i2c_bus_check(i2c);
+
/*
* Enable interrupts before starting the transfer so that we don't
* miss any INT_I2C interrupts.
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 462948e..90946a8 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -40,7 +40,6 @@
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <linux/io.h>
-#include <linux/mutex.h>
/* PIIX4 SMBus address offsets */
@@ -153,10 +152,7 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
/*
* SB800 globals
- * piix4_mutex_sb800 protects piix4_port_sel_sb800 and the pair
- * of I/O ports at SB800_PIIX4_SMB_IDX.
*/
-static DEFINE_MUTEX(piix4_mutex_sb800);
static u8 piix4_port_sel_sb800;
static u8 piix4_port_mask_sb800;
static u8 piix4_port_shift_sb800;
@@ -298,12 +294,19 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
else
smb_en = (aux) ? 0x28 : 0x2c;
- mutex_lock(&piix4_mutex_sb800);
+ if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb")) {
+ dev_err(&PIIX4_dev->dev,
+ "SMB base address index region 0x%x already in use.\n",
+ SB800_PIIX4_SMB_IDX);
+ return -EBUSY;
+ }
+
outb_p(smb_en, SB800_PIIX4_SMB_IDX);
smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX);
smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1);
- mutex_unlock(&piix4_mutex_sb800);
+
+ release_region(SB800_PIIX4_SMB_IDX, 2);
if (!smb_en) {
smb_en_status = smba_en_lo & 0x10;
@@ -373,7 +376,12 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
break;
}
} else {
- mutex_lock(&piix4_mutex_sb800);
+ if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2,
+ "sb800_piix4_smb")) {
+ release_region(piix4_smba, SMBIOSIZE);
+ return -EBUSY;
+ }
+
outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX);
port_sel = inb_p(SB800_PIIX4_SMB_IDX + 1);
piix4_port_sel_sb800 = (port_sel & 0x01) ?
@@ -381,7 +389,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
SB800_PIIX4_PORT_IDX;
piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
- mutex_unlock(&piix4_mutex_sb800);
+ release_region(SB800_PIIX4_SMB_IDX, 2);
}
dev_info(&PIIX4_dev->dev,
@@ -462,13 +470,13 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter)
/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
- msleep(2);
+ usleep_range(2000, 2100);
else
- msleep(1);
+ usleep_range(250, 500);
while ((++timeout < MAX_TIMEOUT) &&
((temp = inb_p(SMBHSTSTS)) & 0x01))
- msleep(1);
+ usleep_range(250, 500);
/* If the SMBus is still busy, we give up */
if (timeout == MAX_TIMEOUT) {
@@ -679,7 +687,8 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
u8 port;
int retval;
- mutex_lock(&piix4_mutex_sb800);
+ if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb"))
+ return -EBUSY;
/* Request the SMBUS semaphore, avoid conflicts with the IMC */
smbslvcnt = inb_p(SMBSLVCNT);
@@ -695,8 +704,8 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
} while (--retries);
/* SMBus is still owned by the IMC, we give up */
if (!retries) {
- mutex_unlock(&piix4_mutex_sb800);
- return -EBUSY;
+ retval = -EBUSY;
+ goto release;
}
/*
@@ -753,8 +762,8 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc)
piix4_imc_wakeup();
- mutex_unlock(&piix4_mutex_sb800);
-
+release:
+ release_region(SB800_PIIX4_SMB_IDX, 2);
return retval;
}
@@ -899,13 +908,6 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
bool notify_imc = false;
is_sb800 = true;
- if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) {
- dev_err(&dev->dev,
- "SMBus base address index region 0x%x already in use!\n",
- SB800_PIIX4_SMB_IDX);
- return -EBUSY;
- }
-
if (dev->vendor == PCI_VENDOR_ID_AMD &&
dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) {
u8 imc;
@@ -922,20 +924,16 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* base address location etc changed in SB800 */
retval = piix4_setup_sb800(dev, id, 0);
- if (retval < 0) {
- release_region(SB800_PIIX4_SMB_IDX, 2);
+ if (retval < 0)
return retval;
- }
/*
* Try to register multiplexed main SMBus adapter,
* give up if we can't
*/
retval = piix4_add_adapters_sb800(dev, retval, notify_imc);
- if (retval < 0) {
- release_region(SB800_PIIX4_SMB_IDX, 2);
+ if (retval < 0)
return retval;
- }
} else {
retval = piix4_setup(dev, id);
if (retval < 0)
@@ -983,11 +981,8 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
if (adapdata->smba) {
i2c_del_adapter(adap);
- if (adapdata->port == (0 << piix4_port_shift_sb800)) {
+ if (adapdata->port == (0 << piix4_port_shift_sb800))
release_region(adapdata->smba, SMBIOSIZE);
- if (adapdata->sb800_main)
- release_region(SB800_PIIX4_SMB_IDX, 2);
- }
kfree(adapdata);
kfree(adap);
}
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c
index 7aa7b9c..a01389b 100644
--- a/drivers/i2c/busses/i2c-scmi.c
+++ b/drivers/i2c/busses/i2c-scmi.c
@@ -182,7 +182,8 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
status = acpi_evaluate_object(smbus_cmi->handle, method, &input,
&buffer);
if (ACPI_FAILURE(status)) {
- ACPI_ERROR((AE_INFO, "Evaluating %s: %i", method, status));
+ acpi_handle_err(smbus_cmi->handle,
+ "Failed to evaluate %s: %i\n", method, status);
return -EIO;
}
@@ -190,19 +191,19 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
if (pkg && pkg->type == ACPI_TYPE_PACKAGE)
obj = pkg->package.elements;
else {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
+ acpi_handle_err(smbus_cmi->handle, "Invalid argument type\n");
result = -EIO;
goto out;
}
if (obj == NULL || obj->type != ACPI_TYPE_INTEGER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
+ acpi_handle_err(smbus_cmi->handle, "Invalid argument type\n");
result = -EIO;
goto out;
}
result = obj->integer.value;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s return status: %i\n",
- method, result));
+ acpi_handle_debug(smbus_cmi->handle, "%s return status: %i\n", method,
+ result);
switch (result) {
case ACPI_SMBUS_STATUS_OK:
@@ -227,7 +228,7 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
obj = pkg->package.elements + 1;
if (obj->type != ACPI_TYPE_INTEGER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
+ acpi_handle_err(smbus_cmi->handle, "Invalid argument type\n");
result = -EIO;
goto out;
}
@@ -239,7 +240,8 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
case I2C_SMBUS_BYTE_DATA:
case I2C_SMBUS_WORD_DATA:
if (obj->type != ACPI_TYPE_INTEGER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
+ acpi_handle_err(smbus_cmi->handle,
+ "Invalid argument type\n");
result = -EIO;
goto out;
}
@@ -250,7 +252,8 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags,
break;
case I2C_SMBUS_BLOCK_DATA:
if (obj->type != ACPI_TYPE_BUFFER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
+ acpi_handle_err(smbus_cmi->handle,
+ "Invalid argument type\n");
result = -EIO;
goto out;
}
@@ -300,6 +303,7 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
const char *name)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_handle *handle = smbus_cmi->handle;
union acpi_object *obj;
acpi_status status;
@@ -308,8 +312,8 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
smbus_cmi->methods->mt_info,
NULL, &buffer);
if (ACPI_FAILURE(status)) {
- ACPI_ERROR((AE_INFO, "Evaluating %s: %i",
- smbus_cmi->methods->mt_info, status));
+ acpi_handle_err(handle, "Failed to evaluate %s: %i\n",
+ smbus_cmi->methods->mt_info, status);
return -EIO;
}
@@ -317,18 +321,18 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
if (obj && obj->type == ACPI_TYPE_PACKAGE)
obj = obj->package.elements;
else {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
+ acpi_handle_err(handle, "Invalid argument type\n");
kfree(buffer.pointer);
return -EIO;
}
if (obj->type != ACPI_TYPE_INTEGER) {
- ACPI_ERROR((AE_INFO, "Invalid argument type"));
+ acpi_handle_err(handle, "Invalid argument type\n");
kfree(buffer.pointer);
return -EIO;
} else
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SMBus CMI Version %x"
- "\n", (int)obj->integer.value));
+ acpi_handle_debug(handle, "SMBus CMI Version %x\n",
+ (int)obj->integer.value);
kfree(buffer.pointer);
smbus_cmi->cap_info = 1;
@@ -337,8 +341,7 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi,
else if (!strcmp(name, smbus_cmi->methods->mt_sbw))
smbus_cmi->cap_write = 1;
else
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported CMI method: %s\n",
- name));
+ acpi_handle_debug(handle, "Unsupported CMI method: %s\n", name);
return 0;
}
diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c
index 47c8d00..ba600d7 100644
--- a/drivers/i2c/busses/i2c-stm32f4.c
+++ b/drivers/i2c/busses/i2c-stm32f4.c
@@ -349,7 +349,7 @@ static void stm32f4_i2c_read_msg(struct stm32f4_i2c_dev *i2c_dev)
static void stm32f4_i2c_terminate_xfer(struct stm32f4_i2c_dev *i2c_dev)
{
struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
- void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2;
+ void __iomem *reg;
stm32f4_i2c_disable_irq(i2c_dev);
diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c
index b970bf8..1f6d780 100644
--- a/drivers/i2c/busses/i2c-xlp9xx.c
+++ b/drivers/i2c/busses/i2c-xlp9xx.c
@@ -125,7 +125,16 @@ static void xlp9xx_i2c_update_rx_fifo_thres(struct xlp9xx_i2c_dev *priv)
{
u32 thres;
- thres = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE);
+ if (priv->len_recv)
+ /* interrupt after the first read to examine
+ * the length byte before proceeding further
+ */
+ thres = 1;
+ else if (priv->msg_buf_remaining > XLP9XX_I2C_FIFO_SIZE)
+ thres = XLP9XX_I2C_FIFO_SIZE;
+ else
+ thres = priv->msg_buf_remaining;
+
xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
thres << XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT);
}
@@ -144,7 +153,7 @@ static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv)
static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
{
- u32 len, i;
+ u32 len, i, val;
u8 rlen, *buf = priv->msg_buf;
len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
@@ -156,19 +165,27 @@ static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
rlen = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
*buf++ = rlen;
len--;
+
if (priv->client_pec)
++rlen;
/* update remaining bytes and message length */
priv->msg_buf_remaining = rlen;
priv->msg_len = rlen + 1;
priv->len_recv = false;
+
+ /* Update transfer length to read only actual data */
+ val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
+ val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
+ ((rlen + 1) << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
+ xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
+ } else {
+ len = min(priv->msg_buf_remaining, len);
+ for (i = 0; i < len; i++, buf++)
+ *buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
+
+ priv->msg_buf_remaining -= len;
}
- len = min(priv->msg_buf_remaining, len);
- for (i = 0; i < len; i++, buf++)
- *buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
-
- priv->msg_buf_remaining -= len;
priv->msg_buf = buf;
if (priv->msg_buf_remaining)
@@ -324,7 +341,8 @@ static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg,
dev_dbg(priv->dev, "transfer error %x!\n", priv->msg_err);
if (priv->msg_err & XLP9XX_I2C_INTEN_BUSERR)
xlp9xx_i2c_init(priv);
- return -EIO;
+ return (priv->msg_err & XLP9XX_I2C_INTEN_NACKADDR) ?
+ -ENXIO : -EIO;
}
if (timeleft == 0) {
@@ -356,8 +374,8 @@ static int xlp9xx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
static u32 xlp9xx_i2c_functionality(struct i2c_adapter *adapter)
{
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C |
- I2C_FUNC_10BIT_ADDR;
+ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_READ_BLOCK_DATA |
+ I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR;
}
static const struct i2c_algorithm xlp9xx_i2c_algo = {
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index aa03eeb..16a3b73 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -126,6 +126,10 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
struct i2c_client *client = to_i2c_client(dev);
int rc;
+ rc = of_device_uevent_modalias(dev, env);
+ if (rc != -ENODEV)
+ return rc;
+
rc = acpi_device_uevent_modalias(dev, env);
if (rc != -ENODEV)
return rc;
@@ -441,6 +445,10 @@ show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
struct i2c_client *client = to_i2c_client(dev);
int len;
+ len = of_device_modalias(dev, buf, PAGE_SIZE);
+ if (len != -ENODEV)
+ return len;
+
len = acpi_device_modalias(dev, buf, PAGE_SIZE -1);
if (len != -ENODEV)
return len;
diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c
index 8d474bb..c405270 100644
--- a/drivers/i2c/i2c-core-of.c
+++ b/drivers/i2c/i2c-core-of.c
@@ -4,7 +4,7 @@
* Copyright (C) 2008 Jochen Friedrich <jochen@scram.de>
* based on a previous patch from Jon Smirl <jonsmirl@gmail.com>
*
- * Copyright (C) 2013 Wolfram Sang <wsa@the-dreams.de>
+ * Copyright (C) 2013, 2018 Wolfram Sang <wsa@the-dreams.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -25,12 +25,11 @@
static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
struct device_node *node)
{
- struct i2c_client *result;
+ struct i2c_client *client;
struct i2c_board_info info = {};
struct dev_archdata dev_ad = {};
- const __be32 *addr_be;
u32 addr;
- int len;
+ int ret;
dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node);
@@ -40,13 +39,12 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
return ERR_PTR(-EINVAL);
}
- addr_be = of_get_property(node, "reg", &len);
- if (!addr_be || (len < sizeof(*addr_be))) {
+ ret = of_property_read_u32(node, "reg", &addr);
+ if (ret) {
dev_err(&adap->dev, "of_i2c: invalid reg on %pOF\n", node);
- return ERR_PTR(-EINVAL);
+ return ERR_PTR(ret);
}
- addr = be32_to_cpup(addr_be);
if (addr & I2C_TEN_BIT_ADDRESS) {
addr &= ~I2C_TEN_BIT_ADDRESS;
info.flags |= I2C_CLIENT_TEN;
@@ -57,15 +55,9 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
info.flags |= I2C_CLIENT_SLAVE;
}
- if (i2c_check_addr_validity(addr, info.flags)) {
- dev_err(&adap->dev, "of_i2c: invalid addr=%x on %pOF\n",
- addr, node);
- return ERR_PTR(-EINVAL);
- }
-
info.addr = addr;
- info.of_node = of_node_get(node);
info.archdata = &dev_ad;
+ info.of_node = of_node_get(node);
if (of_property_read_bool(node, "host-notify"))
info.flags |= I2C_CLIENT_HOST_NOTIFY;
@@ -73,13 +65,13 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
if (of_get_property(node, "wakeup-source", NULL))
info.flags |= I2C_CLIENT_WAKE;
- result = i2c_new_device(adap, &info);
- if (result == NULL) {
+ client = i2c_new_device(adap, &info);
+ if (!client) {
dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node);
of_node_put(node);
return ERR_PTR(-EINVAL);
}
- return result;
+ return client;
}
void of_i2c_register_devices(struct i2c_adapter *adap)
@@ -103,7 +95,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
client = of_i2c_register_device(adap, node);
if (IS_ERR(client)) {
- dev_warn(&adap->dev,
+ dev_err(&adap->dev,
"Failed to create I2C device for %pOF\n",
node);
of_node_clear_flag(node, OF_POPULATED);
diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c
index 59d5cf3..b5aec33 100644
--- a/drivers/i2c/i2c-core-smbus.c
+++ b/drivers/i2c/i2c-core-smbus.c
@@ -308,17 +308,21 @@ static void i2c_smbus_try_get_dmabuf(struct i2c_msg *msg, u8 init_val)
msg->buf[0] = init_val;
}
-/* Simulate a SMBus command using the i2c protocol
- No checking of parameters is done! */
+/*
+ * Simulate a SMBus command using the I2C protocol.
+ * No checking of parameters is done!
+ */
static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
unsigned short flags,
char read_write, u8 command, int size,
union i2c_smbus_data *data)
{
- /* So we need to generate a series of msgs. In the case of writing, we
- need to use only one message; when reading, we need two. We initialize
- most things with sane defaults, to keep the code below somewhat
- simpler. */
+ /*
+ * So we need to generate a series of msgs. In the case of writing, we
+ * need to use only one message; when reading, we need two. We
+ * initialize most things with sane defaults, to keep the code below
+ * somewhat simpler.
+ */
unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
int num = read_write == I2C_SMBUS_READ ? 2 : 1;