Commit 2b86c4a8 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-fixes-for-4.6d' of...

Merge tag 'iio-fixes-for-4.6d' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus

Jonathan writes:

Fourth set of IIO fixes for the 4.6 cycle.

This last minute set is concerned with a regression in the mpu6050 driver.
The regression causes a null pointer dereference on any ACPI device
that has one of these present such as the ASUS T100TA Baytrail/T.

The issue was known but thought (i.e. missunderstood by me)
to only be a possible with no reports, so was routed via the normal merge
window.  Turns out this was wrong (thanks to Alan for reporting the crash).

The pull is just for the null dereference fix and a followup fix
that also stops the reported name of the device being NULL.

* mpu6050
  - Fix a 'possible' NULL dereference introduced as part of splitting the
  driver to allow both i2c and spi to be supported.  The issue affects ACPI
  systems with this device.
  - Fix a follow up issue where the name and chip id both get set to null if
  the device driver instance is instantiated from ACPI tables.
parents 431adc0a 393dbe4e
...@@ -104,6 +104,19 @@ static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap, ...@@ -104,6 +104,19 @@ static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
return 0; return 0;
} }
static const char *inv_mpu_match_acpi_device(struct device *dev, int *chip_id)
{
const struct acpi_device_id *id;
id = acpi_match_device(dev->driver->acpi_match_table, dev);
if (!id)
return NULL;
*chip_id = (int)id->driver_data;
return dev_name(dev);
}
/** /**
* inv_mpu_probe() - probe function. * inv_mpu_probe() - probe function.
* @client: i2c client. * @client: i2c client.
...@@ -115,14 +128,25 @@ static int inv_mpu_probe(struct i2c_client *client, ...@@ -115,14 +128,25 @@ static int inv_mpu_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct inv_mpu6050_state *st; struct inv_mpu6050_state *st;
int result; int result, chip_type;
const char *name = id ? id->name : NULL;
struct regmap *regmap; struct regmap *regmap;
const char *name;
if (!i2c_check_functionality(client->adapter, if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_I2C_BLOCK)) I2C_FUNC_SMBUS_I2C_BLOCK))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (id) {
chip_type = (int)id->driver_data;
name = id->name;
} else if (ACPI_HANDLE(&client->dev)) {
name = inv_mpu_match_acpi_device(&client->dev, &chip_type);
if (!name)
return -ENODEV;
} else {
return -ENOSYS;
}
regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config); regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config);
if (IS_ERR(regmap)) { if (IS_ERR(regmap)) {
dev_err(&client->dev, "Failed to register i2c regmap %d\n", dev_err(&client->dev, "Failed to register i2c regmap %d\n",
...@@ -131,7 +155,7 @@ static int inv_mpu_probe(struct i2c_client *client, ...@@ -131,7 +155,7 @@ static int inv_mpu_probe(struct i2c_client *client,
} }
result = inv_mpu_core_probe(regmap, client->irq, name, result = inv_mpu_core_probe(regmap, client->irq, name,
NULL, id->driver_data); NULL, chip_type);
if (result < 0) if (result < 0)
return result; return result;
......
...@@ -46,6 +46,7 @@ static int inv_mpu_probe(struct spi_device *spi) ...@@ -46,6 +46,7 @@ static int inv_mpu_probe(struct spi_device *spi)
struct regmap *regmap; struct regmap *regmap;
const struct spi_device_id *id = spi_get_device_id(spi); const struct spi_device_id *id = spi_get_device_id(spi);
const char *name = id ? id->name : NULL; const char *name = id ? id->name : NULL;
const int chip_type = id ? id->driver_data : 0;
regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config); regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
if (IS_ERR(regmap)) { if (IS_ERR(regmap)) {
...@@ -55,7 +56,7 @@ static int inv_mpu_probe(struct spi_device *spi) ...@@ -55,7 +56,7 @@ static int inv_mpu_probe(struct spi_device *spi)
} }
return inv_mpu_core_probe(regmap, spi->irq, name, return inv_mpu_core_probe(regmap, spi->irq, name,
inv_mpu_i2c_disable, id->driver_data); inv_mpu_i2c_disable, chip_type);
} }
static int inv_mpu_remove(struct spi_device *spi) static int inv_mpu_remove(struct spi_device *spi)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment