Skip to content

Commit

Permalink
iio: Reconcile operation order between iio_register/unregister and pm…
Browse files Browse the repository at this point in the history
… functions

At probe, runtime pm should be setup before registering the sysfs interface so
that all the power attributes are accurate and functional when registering.
Also, when removing the device we should unregister first to make sure
that the interfaces that may result in wakeups are no longer available.

Fix this behaviour for the following drivers: bmc150, bmg160, kmx61,
kxcj-1013, mma9551, mma9553, rpr0521.

Signed-off-by: Adriana Reus <adriana.reus@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
  • Loading branch information
adrianareus authored and jic23 committed Nov 8, 2015
1 parent 536bbca commit 7d0ead5
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 87 deletions.
20 changes: 9 additions & 11 deletions drivers/iio/accel/bmc150-accel-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1623,24 +1623,22 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
}
}

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(dev, "Unable to register iio device\n");
goto err_trigger_unregister;
}

ret = pm_runtime_set_active(dev);
if (ret)
goto err_iio_unregister;
goto err_trigger_unregister;

pm_runtime_enable(dev);
pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(dev);

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(dev, "Unable to register iio device\n");
goto err_trigger_unregister;
}

return 0;

err_iio_unregister:
iio_device_unregister(indio_dev);
err_trigger_unregister:
bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1);
err_buffer_cleanup:
Expand All @@ -1655,12 +1653,12 @@ int bmc150_accel_core_remove(struct device *dev)
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmc150_accel_data *data = iio_priv(indio_dev);

iio_device_unregister(indio_dev);

pm_runtime_disable(data->dev);
pm_runtime_set_suspended(data->dev);
pm_runtime_put_noidle(data->dev);

iio_device_unregister(indio_dev);

bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1);

iio_triggered_buffer_cleanup(indio_dev);
Expand Down
20 changes: 9 additions & 11 deletions drivers/iio/accel/kxcjk-1013.c
Original file line number Diff line number Diff line change
Expand Up @@ -1264,25 +1264,23 @@ static int kxcjk1013_probe(struct i2c_client *client,
goto err_trigger_unregister;
}

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto err_buffer_cleanup;
}

ret = pm_runtime_set_active(&client->dev);
if (ret)
goto err_iio_unregister;
goto err_buffer_cleanup;

pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev,
KXCJK1013_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto err_buffer_cleanup;
}

return 0;

err_iio_unregister:
iio_device_unregister(indio_dev);
err_buffer_cleanup:
if (data->dready_trig)
iio_triggered_buffer_cleanup(indio_dev);
Expand All @@ -1302,12 +1300,12 @@ static int kxcjk1013_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct kxcjk1013_data *data = iio_priv(indio_dev);

iio_device_unregister(indio_dev);

pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);

iio_device_unregister(indio_dev);

if (data->dready_trig) {
iio_triggered_buffer_cleanup(indio_dev);
iio_trigger_unregister(data->dready_trig);
Expand Down
19 changes: 9 additions & 10 deletions drivers/iio/accel/mma9551.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,25 +495,23 @@ static int mma9551_probe(struct i2c_client *client,
if (ret < 0)
goto out_poweroff;

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto out_poweroff;
}

ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
goto out_iio_unregister;
goto out_poweroff;

pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev,
MMA9551_AUTO_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto out_poweroff;
}

return 0;

out_iio_unregister:
iio_device_unregister(indio_dev);
out_poweroff:
mma9551_set_device_state(client, false);

Expand All @@ -525,11 +523,12 @@ static int mma9551_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct mma9551_data *data = iio_priv(indio_dev);

iio_device_unregister(indio_dev);

pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);

iio_device_unregister(indio_dev);
mutex_lock(&data->mutex);
mma9551_set_device_state(data->client, false);
mutex_unlock(&data->mutex);
Expand Down
20 changes: 9 additions & 11 deletions drivers/iio/accel/mma9553.c
Original file line number Diff line number Diff line change
Expand Up @@ -1133,27 +1133,24 @@ static int mma9553_probe(struct i2c_client *client,
}
}

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto out_poweroff;
}

ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
goto out_iio_unregister;
goto out_poweroff;

pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev,
MMA9551_AUTO_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);

dev_dbg(&indio_dev->dev, "Registered device %s\n", name);
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto out_poweroff;
}

dev_dbg(&indio_dev->dev, "Registered device %s\n", name);
return 0;

out_iio_unregister:
iio_device_unregister(indio_dev);
out_poweroff:
mma9551_set_device_state(client, false);
return ret;
Expand All @@ -1164,11 +1161,12 @@ static int mma9553_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct mma9553_data *data = iio_priv(indio_dev);

iio_device_unregister(indio_dev);

pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);

iio_device_unregister(indio_dev);
mutex_lock(&data->mutex);
mma9551_set_device_state(data->client, false);
mutex_unlock(&data->mutex);
Expand Down
19 changes: 9 additions & 10 deletions drivers/iio/gyro/bmg160_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1077,25 +1077,23 @@ int bmg160_core_probe(struct device *dev, struct regmap *regmap, int irq,
goto err_trigger_unregister;
}

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(dev, "unable to register iio device\n");
goto err_buffer_cleanup;
}

ret = pm_runtime_set_active(dev);
if (ret)
goto err_iio_unregister;
goto err_buffer_cleanup;

pm_runtime_enable(dev);
pm_runtime_set_autosuspend_delay(dev,
BMG160_AUTO_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(dev);

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(dev, "unable to register iio device\n");
goto err_buffer_cleanup;
}

return 0;

err_iio_unregister:
iio_device_unregister(indio_dev);
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_trigger_unregister:
Expand All @@ -1113,11 +1111,12 @@ void bmg160_core_remove(struct device *dev)
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmg160_data *data = iio_priv(indio_dev);

iio_device_unregister(indio_dev);

pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_put_noidle(dev);

iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);

if (data->dready_trig) {
Expand Down
24 changes: 11 additions & 13 deletions drivers/iio/imu/kmx61.c
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,14 @@ static int kmx61_probe(struct i2c_client *client,
}
}

ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
goto err_buffer_cleanup_mag;

pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);

ret = iio_device_register(data->acc_indio_dev);
if (ret < 0) {
dev_err(&client->dev, "Failed to register acc iio device\n");
Expand All @@ -1402,18 +1410,8 @@ static int kmx61_probe(struct i2c_client *client,
goto err_iio_unregister_acc;
}

ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
goto err_iio_unregister_mag;

pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);

return 0;

err_iio_unregister_mag:
iio_device_unregister(data->mag_indio_dev);
err_iio_unregister_acc:
iio_device_unregister(data->acc_indio_dev);
err_buffer_cleanup_mag:
Expand All @@ -1437,13 +1435,13 @@ static int kmx61_remove(struct i2c_client *client)
{
struct kmx61_data *data = i2c_get_clientdata(client);

iio_device_unregister(data->acc_indio_dev);
iio_device_unregister(data->mag_indio_dev);

pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);

iio_device_unregister(data->acc_indio_dev);
iio_device_unregister(data->mag_indio_dev);

if (client->irq > 0) {
iio_triggered_buffer_cleanup(data->acc_indio_dev);
iio_triggered_buffer_cleanup(data->mag_indio_dev);
Expand Down
14 changes: 4 additions & 10 deletions drivers/iio/light/rpr0521.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,34 +507,28 @@ static int rpr0521_probe(struct i2c_client *client,
dev_err(&client->dev, "rpr0521 chip init failed\n");
return ret;
}
ret = iio_device_register(indio_dev);
if (ret < 0)
return ret;

ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
goto err_iio_unregister;
return ret;

pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);

return 0;

err_iio_unregister:
iio_device_unregister(indio_dev);
return ret;
return iio_device_register(indio_dev);
}

static int rpr0521_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);

iio_device_unregister(indio_dev);

pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);

iio_device_unregister(indio_dev);
rpr0521_poweroff(iio_priv(indio_dev));

return 0;
Expand Down
20 changes: 9 additions & 11 deletions drivers/iio/magnetometer/bmc150_magn.c
Original file line number Diff line number Diff line change
Expand Up @@ -928,27 +928,24 @@ static int bmc150_magn_probe(struct i2c_client *client,
goto err_free_irq;
}

ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto err_buffer_cleanup;
}

ret = pm_runtime_set_active(&client->dev);
if (ret)
goto err_iio_unregister;
goto err_buffer_cleanup;

pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev,
BMC150_MAGN_AUTO_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);

dev_dbg(&indio_dev->dev, "Registered device %s\n", name);
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto err_buffer_cleanup;
}

dev_dbg(&indio_dev->dev, "Registered device %s\n", name);
return 0;

err_iio_unregister:
iio_device_unregister(indio_dev);
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_free_irq:
Expand All @@ -967,11 +964,12 @@ static int bmc150_magn_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct bmc150_magn_data *data = iio_priv(indio_dev);

iio_device_unregister(indio_dev);

pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_put_noidle(&client->dev);

iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);

if (client->irq > 0)
Expand Down

0 comments on commit 7d0ead5

Please sign in to comment.