aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-12-03 10:48:24 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-12-03 10:48:24 -0500
commitae4806a38bc8db0b48e746445c41afd249568d68 (patch)
treef7c3f8c079690fdbdec063335620303fa9eec585
parent49a418d78378769cf78b8c645f7e469f4dae2bbd (diff)
parentedef30980dc06bea547baefcfc8d910682b6e060 (diff)
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Here are two bugfixes for I2C, fixing a memleak in the core and irq allocation for i801. Also three bugfixes for the at24 eeprom driver which Bartosz collected while taking over maintainership for this driver" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: eeprom: at24: check at24_read/write arguments eeprom: at24: fix reading from 24MAC402/24MAC602 eeprom: at24: correctly set the size for at24mac402 i2c: i2c-boardinfo: fix memory leaks on devinfo i2c: i801: Fix Failed to allocate irq -2147483648 error
-rw-r--r--drivers/i2c/busses/i2c-i801.c3
-rw-r--r--drivers/i2c/i2c-boardinfo.c2
-rw-r--r--drivers/misc/eeprom/at24.c19
3 files changed, 23 insertions, 1 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 9e12a53ef7b8..8eac00efadc1 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -1617,6 +1617,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
1617 /* Default timeout in interrupt mode: 200 ms */ 1617 /* Default timeout in interrupt mode: 200 ms */
1618 priv->adapter.timeout = HZ / 5; 1618 priv->adapter.timeout = HZ / 5;
1619 1619
1620 if (dev->irq == IRQ_NOTCONNECTED)
1621 priv->features &= ~FEATURE_IRQ;
1622
1620 if (priv->features & FEATURE_IRQ) { 1623 if (priv->features & FEATURE_IRQ) {
1621 u16 pcictl, pcists; 1624 u16 pcictl, pcists;
1622 1625
diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c
index 31186ead5a40..509a6007cdf6 100644
--- a/drivers/i2c/i2c-boardinfo.c
+++ b/drivers/i2c/i2c-boardinfo.c
@@ -86,6 +86,7 @@ int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsig
86 property_entries_dup(info->properties); 86 property_entries_dup(info->properties);
87 if (IS_ERR(devinfo->board_info.properties)) { 87 if (IS_ERR(devinfo->board_info.properties)) {
88 status = PTR_ERR(devinfo->board_info.properties); 88 status = PTR_ERR(devinfo->board_info.properties);
89 kfree(devinfo);
89 break; 90 break;
90 } 91 }
91 } 92 }
@@ -98,6 +99,7 @@ int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsig
98 GFP_KERNEL); 99 GFP_KERNEL);
99 if (!devinfo->board_info.resources) { 100 if (!devinfo->board_info.resources) {
100 status = -ENOMEM; 101 status = -ENOMEM;
102 kfree(devinfo);
101 break; 103 break;
102 } 104 }
103 } 105 }
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index e0b4b36ef010..305a7a464d09 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -425,7 +425,8 @@ static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf,
425 memset(msg, 0, sizeof(msg)); 425 memset(msg, 0, sizeof(msg));
426 msg[0].addr = client->addr; 426 msg[0].addr = client->addr;
427 msg[0].buf = addrbuf; 427 msg[0].buf = addrbuf;
428 addrbuf[0] = 0x90 + offset; 428 /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */
429 addrbuf[0] = 0xa0 - at24->chip.byte_len + offset;
429 msg[0].len = 1; 430 msg[0].len = 1;
430 msg[1].addr = client->addr; 431 msg[1].addr = client->addr;
431 msg[1].flags = I2C_M_RD; 432 msg[1].flags = I2C_M_RD;
@@ -568,6 +569,9 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count)
568 if (unlikely(!count)) 569 if (unlikely(!count))
569 return count; 570 return count;
570 571
572 if (off + count > at24->chip.byte_len)
573 return -EINVAL;
574
571 client = at24_translate_offset(at24, &off); 575 client = at24_translate_offset(at24, &off);
572 576
573 ret = pm_runtime_get_sync(&client->dev); 577 ret = pm_runtime_get_sync(&client->dev);
@@ -613,6 +617,9 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
613 if (unlikely(!count)) 617 if (unlikely(!count))
614 return -EINVAL; 618 return -EINVAL;
615 619
620 if (off + count > at24->chip.byte_len)
621 return -EINVAL;
622
616 client = at24_translate_offset(at24, &off); 623 client = at24_translate_offset(at24, &off);
617 624
618 ret = pm_runtime_get_sync(&client->dev); 625 ret = pm_runtime_get_sync(&client->dev);
@@ -730,6 +737,16 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
730 dev_warn(&client->dev, 737 dev_warn(&client->dev,
731 "page_size looks suspicious (no power of 2)!\n"); 738 "page_size looks suspicious (no power of 2)!\n");
732 739
740 /*
741 * REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while
742 * the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4.
743 *
744 * Eventually we'll get rid of the magic values altoghether in favor of
745 * real structs, but for now just manually set the right size.
746 */
747 if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4)
748 chip.byte_len = 6;
749
733 /* Use I2C operations unless we're stuck with SMBus extensions. */ 750 /* Use I2C operations unless we're stuck with SMBus extensions. */
734 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 751 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
735 if (chip.flags & AT24_FLAG_ADDR16) 752 if (chip.flags & AT24_FLAG_ADDR16)