Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: chemical: bme680: add power management

Add runtime power management to the device.

Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241202192341.33187-4-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Vasileios Amoiridis and committed by
Jonathan Cameron
1e60a654 601f7269

+106 -7
+2
drivers/iio/chemical/bme680.h
··· 2 2 #ifndef BME680_H_ 3 3 #define BME680_H_ 4 4 5 + #include <linux/pm.h> 5 6 #include <linux/regmap.h> 6 7 7 8 #define BME680_REG_CHIP_ID 0xD0 ··· 81 80 #define BME680_CALIB_RANGE_3_LEN 5 82 81 83 82 extern const struct regmap_config bme680_regmap_config; 83 + extern const struct dev_pm_ops bme680_dev_pm_ops; 84 84 85 85 int bme680_core_probe(struct device *dev, struct regmap *regmap, 86 86 const char *name);
+102 -7
drivers/iio/chemical/bme680_core.c
··· 14 14 #include <linux/device.h> 15 15 #include <linux/log2.h> 16 16 #include <linux/module.h> 17 + #include <linux/pm.h> 18 + #include <linux/pm_runtime.h> 17 19 #include <linux/regmap.h> 18 20 #include <linux/regulator/consumer.h> 19 21 ··· 822 820 return 0; 823 821 } 824 822 825 - static int bme680_read_raw(struct iio_dev *indio_dev, 826 - struct iio_chan_spec const *chan, 827 - int *val, int *val2, long mask) 823 + static int __bme680_read_raw(struct iio_dev *indio_dev, 824 + struct iio_chan_spec const *chan, 825 + int *val, int *val2, long mask) 828 826 { 829 827 struct bme680_data *data = iio_priv(indio_dev); 830 828 int chan_val, ret; ··· 937 935 } 938 936 } 939 937 938 + static int bme680_read_raw(struct iio_dev *indio_dev, 939 + struct iio_chan_spec const *chan, 940 + int *val, int *val2, long mask) 941 + { 942 + struct bme680_data *data = iio_priv(indio_dev); 943 + struct device *dev = regmap_get_device(data->regmap); 944 + int ret; 945 + 946 + ret = pm_runtime_resume_and_get(dev); 947 + if (ret) 948 + return ret; 949 + 950 + ret = __bme680_read_raw(indio_dev, chan, val, val2, mask); 951 + pm_runtime_mark_last_busy(dev); 952 + pm_runtime_put_autosuspend(dev); 953 + 954 + return ret; 955 + } 956 + 940 957 static bool bme680_is_valid_oversampling(int rate) 941 958 { 942 959 return (rate > 0 && rate <= 16 && is_power_of_2(rate)); 943 960 } 944 961 945 - static int bme680_write_raw(struct iio_dev *indio_dev, 946 - struct iio_chan_spec const *chan, 947 - int val, int val2, long mask) 962 + static int __bme680_write_raw(struct iio_dev *indio_dev, 963 + struct iio_chan_spec const *chan, 964 + int val, int val2, long mask) 948 965 { 949 966 struct bme680_data *data = iio_priv(indio_dev); 950 967 ··· 1006 985 default: 1007 986 return -EINVAL; 1008 987 } 988 + } 989 + 990 + static int bme680_write_raw(struct iio_dev *indio_dev, 991 + struct iio_chan_spec const *chan, 992 + int val, int val2, long mask) 993 + { 994 + struct bme680_data *data = iio_priv(indio_dev); 995 + struct device *dev = regmap_get_device(data->regmap); 996 + int ret; 997 + 998 + ret = pm_runtime_resume_and_get(dev); 999 + if (ret) 1000 + return ret; 1001 + 1002 + ret = __bme680_write_raw(indio_dev, chan, val, val2, mask); 1003 + pm_runtime_mark_last_busy(dev); 1004 + pm_runtime_put_autosuspend(dev); 1005 + 1006 + return ret; 1009 1007 } 1010 1008 1011 1009 static const char bme680_oversampling_ratio_show[] = "1 2 4 8 16"; ··· 1127 1087 return IRQ_HANDLED; 1128 1088 } 1129 1089 1090 + static int bme680_buffer_preenable(struct iio_dev *indio_dev) 1091 + { 1092 + struct bme680_data *data = iio_priv(indio_dev); 1093 + struct device *dev = regmap_get_device(data->regmap); 1094 + 1095 + return pm_runtime_resume_and_get(dev); 1096 + } 1097 + 1098 + static int bme680_buffer_postdisable(struct iio_dev *indio_dev) 1099 + { 1100 + struct bme680_data *data = iio_priv(indio_dev); 1101 + struct device *dev = regmap_get_device(data->regmap); 1102 + 1103 + pm_runtime_mark_last_busy(dev); 1104 + pm_runtime_put_autosuspend(dev); 1105 + return 0; 1106 + } 1107 + 1108 + static const struct iio_buffer_setup_ops bme680_buffer_setup_ops = { 1109 + .preenable = bme680_buffer_preenable, 1110 + .postdisable = bme680_buffer_postdisable, 1111 + }; 1112 + 1130 1113 int bme680_core_probe(struct device *dev, struct regmap *regmap, 1131 1114 const char *name) 1132 1115 { ··· 1223 1160 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, 1224 1161 iio_pollfunc_store_time, 1225 1162 bme680_trigger_handler, 1226 - NULL); 1163 + &bme680_buffer_setup_ops); 1227 1164 if (ret) 1228 1165 return dev_err_probe(dev, ret, 1229 1166 "iio triggered buffer setup failed\n"); 1230 1167 1168 + /* Enable runtime PM */ 1169 + pm_runtime_set_autosuspend_delay(dev, BME680_STARTUP_TIME_US); 1170 + pm_runtime_use_autosuspend(dev); 1171 + pm_runtime_set_active(dev); 1172 + ret = devm_pm_runtime_enable(dev); 1173 + if (ret) 1174 + return ret; 1175 + 1231 1176 return devm_iio_device_register(dev, indio_dev); 1232 1177 } 1233 1178 EXPORT_SYMBOL_NS_GPL(bme680_core_probe, "IIO_BME680"); 1179 + 1180 + static int bme680_runtime_suspend(struct device *dev) 1181 + { 1182 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 1183 + struct bme680_data *data = iio_priv(indio_dev); 1184 + 1185 + return bme680_set_mode(data, BME680_MODE_SLEEP); 1186 + } 1187 + 1188 + static int bme680_runtime_resume(struct device *dev) 1189 + { 1190 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 1191 + struct bme680_data *data = iio_priv(indio_dev); 1192 + int ret; 1193 + 1194 + ret = bme680_chip_config(data); 1195 + if (ret) 1196 + return ret; 1197 + 1198 + return bme680_gas_config(data); 1199 + } 1200 + 1201 + EXPORT_RUNTIME_DEV_PM_OPS(bme680_dev_pm_ops, bme680_runtime_suspend, 1202 + bme680_runtime_resume, NULL); 1234 1203 1235 1204 MODULE_AUTHOR("Himanshu Jha <himanshujha199640@gmail.com>"); 1236 1205 MODULE_DESCRIPTION("Bosch BME680 Driver");
+1
drivers/iio/chemical/bme680_i2c.c
··· 51 51 .driver = { 52 52 .name = "bme680_i2c", 53 53 .of_match_table = bme680_of_i2c_match, 54 + .pm = pm_ptr(&bme680_dev_pm_ops), 54 55 }, 55 56 .probe = bme680_i2c_probe, 56 57 .id_table = bme680_i2c_id,
+1
drivers/iio/chemical/bme680_spi.c
··· 154 154 .driver = { 155 155 .name = "bme680_spi", 156 156 .of_match_table = bme680_of_spi_match, 157 + .pm = pm_ptr(&bme680_dev_pm_ops), 157 158 }, 158 159 .probe = bme680_spi_probe, 159 160 .id_table = bme680_spi_id,