2020#include <linux/module.h>
2121#include <linux/mutex.h>
2222#include <linux/of.h>
23+ #include <linux/pm_runtime.h>
2324#include <linux/regmap.h>
2425
2526#define INA3221_DRIVER_NAME "ina3221"
5354#define INA3221_CONFIG_CHs_EN_MASK GENMASK(14, 12)
5455#define INA3221_CONFIG_CHx_EN (x ) BIT(14 - (x))
5556
57+ #define INA3221_CONFIG_DEFAULT 0x7127
5658#define INA3221_RSHUNT_DEFAULT 10000
5759
5860enum ina3221_fields {
@@ -103,13 +105,15 @@ struct ina3221_input {
103105
104106/**
105107 * struct ina3221_data - device specific information
108+ * @pm_dev: Device pointer for pm runtime
106109 * @regmap: Register map of the device
107110 * @fields: Register fields of the device
108111 * @inputs: Array of channel input source specific structures
109112 * @lock: mutex lock to serialize sysfs attribute accesses
110113 * @reg_config: Register value of INA3221_CONFIG
111114 */
112115struct ina3221_data {
116+ struct device * pm_dev ;
113117 struct regmap * regmap ;
114118 struct regmap_field * fields [F_MAX_FIELDS ];
115119 struct ina3221_input inputs [INA3221_NUM_CHANNELS ];
@@ -119,7 +123,8 @@ struct ina3221_data {
119123
120124static inline bool ina3221_is_enabled (struct ina3221_data * ina , int channel )
121125{
122- return ina -> reg_config & INA3221_CONFIG_CHx_EN (channel );
126+ return pm_runtime_active (ina -> pm_dev ) &&
127+ (ina -> reg_config & INA3221_CONFIG_CHx_EN (channel ));
123128}
124129
125130/* Lookup table for Bus and Shunt conversion times in usec */
@@ -290,21 +295,48 @@ static int ina3221_write_enable(struct device *dev, int channel, bool enable)
290295{
291296 struct ina3221_data * ina = dev_get_drvdata (dev );
292297 u16 config , mask = INA3221_CONFIG_CHx_EN (channel );
298+ u16 config_old = ina -> reg_config & mask ;
293299 int ret ;
294300
295301 config = enable ? mask : 0 ;
296302
303+ /* Bypass if enable status is not being changed */
304+ if (config_old == config )
305+ return 0 ;
306+
307+ /* For enabling routine, increase refcount and resume() at first */
308+ if (enable ) {
309+ ret = pm_runtime_get_sync (ina -> pm_dev );
310+ if (ret < 0 ) {
311+ dev_err (dev , "Failed to get PM runtime\n" );
312+ return ret ;
313+ }
314+ }
315+
297316 /* Enable or disable the channel */
298317 ret = regmap_update_bits (ina -> regmap , INA3221_CONFIG , mask , config );
299318 if (ret )
300- return ret ;
319+ goto fail ;
301320
302321 /* Cache the latest config register value */
303322 ret = regmap_read (ina -> regmap , INA3221_CONFIG , & ina -> reg_config );
304323 if (ret )
305- return ret ;
324+ goto fail ;
325+
326+ /* For disabling routine, decrease refcount or suspend() at last */
327+ if (!enable )
328+ pm_runtime_put_sync (ina -> pm_dev );
306329
307330 return 0 ;
331+
332+ fail :
333+ if (enable ) {
334+ dev_err (dev , "Failed to enable channel %d: error %d\n" ,
335+ channel , ret );
336+ pm_runtime_put_sync (ina -> pm_dev );
337+ }
338+
339+ return ret ;
308340}
309341
310342static int ina3221_read (struct device * dev , enum hwmon_sensor_types type ,
@@ -631,44 +663,65 @@ static int ina3221_probe(struct i2c_client *client,
631663 return ret ;
632664 }
633665
634- ret = regmap_field_write (ina -> fields [F_RST ], true);
635- if (ret ) {
636- dev_err (dev , "Unable to reset device\n" );
637- return ret ;
638- }
639-
640- /* Sync config register after reset */
641- ret = regmap_read (ina -> regmap , INA3221_CONFIG , & ina -> reg_config );
642- if (ret )
643- return ret ;
666+ /* The driver will be reset, so use reset value */
667+ ina -> reg_config = INA3221_CONFIG_DEFAULT ;
644668
645669 /* Disable channels if their inputs are disconnected */
646670 for (i = 0 ; i < INA3221_NUM_CHANNELS ; i ++ ) {
647671 if (ina -> inputs [i ].disconnected )
648672 ina -> reg_config &= ~INA3221_CONFIG_CHx_EN (i );
649673 }
650- ret = regmap_write (ina -> regmap , INA3221_CONFIG , ina -> reg_config );
651- if (ret )
652- return ret ;
653674
675+ ina -> pm_dev = dev ;
654676 mutex_init (& ina -> lock );
655677 dev_set_drvdata (dev , ina );
656678
679+ /* Enable PM runtime -- status is suspended by default */
680+ pm_runtime_enable (ina -> pm_dev );
681+
682+ /* Initialize (resume) the device */
683+ for (i = 0 ; i < INA3221_NUM_CHANNELS ; i ++ ) {
684+ if (ina -> inputs [i ].disconnected )
685+ continue ;
686+ /* Match the refcount with number of enabled channels */
687+ ret = pm_runtime_get_sync (ina -> pm_dev );
688+ if (ret < 0 )
689+ goto fail ;
690+ }
691+
657692 hwmon_dev = devm_hwmon_device_register_with_info (dev , client -> name , ina ,
658693 & ina3221_chip_info ,
659694 ina3221_groups );
660695 if (IS_ERR (hwmon_dev )) {
661696 dev_err (dev , "Unable to register hwmon device\n" );
662- mutex_destroy ( & ina -> lock );
663- return PTR_ERR ( hwmon_dev ) ;
697+ ret = PTR_ERR ( hwmon_dev );
698+ goto fail ;
664699 }
665700
666701 return 0 ;
702+
703+ fail :
704+ pm_runtime_disable (ina -> pm_dev );
705+ pm_runtime_set_suspended (ina -> pm_dev );
706+ /* pm_runtime_put_noidle() will decrease the PM refcount until 0 */
707+ for (i = 0 ; i < INA3221_NUM_CHANNELS ; i ++ )
708+ pm_runtime_put_noidle (ina -> pm_dev );
709+ mutex_destroy (& ina -> lock );
710+
711+ return ret ;
667712}
668713
669714static int ina3221_remove (struct i2c_client * client )
670715{
671716 struct ina3221_data * ina = dev_get_drvdata (& client -> dev );
717+ int i ;
718+
719+ pm_runtime_disable (ina -> pm_dev );
720+ pm_runtime_set_suspended (ina -> pm_dev );
721+
722+ /* pm_runtime_put_noidle() will decrease the PM refcount until 0 */
723+ for (i = 0 ; i < INA3221_NUM_CHANNELS ; i ++ )
724+ pm_runtime_put_noidle (ina -> pm_dev );
672725
673726 mutex_destroy (& ina -> lock );
674727
@@ -726,7 +779,9 @@ static int __maybe_unused ina3221_resume(struct device *dev)
726779}
727780
728781static const struct dev_pm_ops ina3221_pm = {
729- SET_SYSTEM_SLEEP_PM_OPS (ina3221_suspend , ina3221_resume )
782+ SET_SYSTEM_SLEEP_PM_OPS (pm_runtime_force_suspend ,
783+ pm_runtime_force_resume )
784+ SET_RUNTIME_PM_OPS (ina3221_suspend , ina3221_resume , NULL )
730785};
731786
732787static const struct of_device_id ina3221_of_match_table [] = {
0 commit comments