Skip to content

Commit

Permalink
Merge tag 'iio-fixes-for-4.6d' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
gregkh committed May 5, 2016
2 parents 431adc0 + 393dbe4 commit 2b86c4a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
30 changes: 27 additions & 3 deletions drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
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.
* @client: i2c client.
Expand All @@ -115,14 +128,25 @@ static int inv_mpu_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct inv_mpu6050_state *st;
int result;
const char *name = id ? id->name : NULL;
int result, chip_type;
struct regmap *regmap;
const char *name;

if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_I2C_BLOCK))
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);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Failed to register i2c regmap %d\n",
Expand All @@ -131,7 +155,7 @@ static int inv_mpu_probe(struct i2c_client *client,
}

result = inv_mpu_core_probe(regmap, client->irq, name,
NULL, id->driver_data);
NULL, chip_type);
if (result < 0)
return result;

Expand Down
3 changes: 2 additions & 1 deletion drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static int inv_mpu_probe(struct spi_device *spi)
struct regmap *regmap;
const struct spi_device_id *id = spi_get_device_id(spi);
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);
if (IS_ERR(regmap)) {
Expand All @@ -55,7 +56,7 @@ static int inv_mpu_probe(struct spi_device *spi)
}

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)
Expand Down

0 comments on commit 2b86c4a

Please sign in to comment.