1
0
Fork 0

max77818-utils: add MAX77818_START_NON_FGCC_OP/MAX77818_FINISH_NON_FGCC_OP

In order to do a set of operations in sequence while disabling FGCC,
two macros are defined to start by disabling FGCC mode end finish by
re-enabling FGCC mode, while ensuring that the operation is not interrupted
by another similar sequence by applying the same lock as used in the
MAX77818_DO_NON_FGCC_OP macro  when starting the operation and releasing
the lock when finishin the opration.
pull/10/head
Steinar Bakkemo 2020-05-04 13:30:36 +02:00
parent fa988b33eb
commit de8a5c1952
2 changed files with 84 additions and 19 deletions

View File

@ -10,16 +10,11 @@
/* Parameter to be given from command line in order to tune the delay introduced after
* clearing the FGCC bit before forwarding requests to the charger driver */
static int post_fgcc_change_delay_us = 100000;
//module_param(post_fgcc_change_delay_us, int, 0644);
//MODULE_PARM_DESC(post_fgcc_change_delay_us,
// "Debug parameter used to tune the post FGCC change delay introduced "
// "to let the charger/fuelgauge take back charging control before doing "
// "any other configuration changes on either");
/* DO NOT CALL DIRECTLY !!
*
* ONLY TO _BE CALLED FROM MAX77818_DO_NON_FGCC_OP macro */
int max77818_set_fgcc_mode(struct max77818_dev *max77818_dev,
int max77818_utils_set_fgcc_mode(struct max77818_dev *max77818_dev,
bool enabled,
bool *cur_mode)
{

View File

@ -1,13 +1,13 @@
#ifndef __MAX17818_UTILS_H_
#define __MAX17818_UTILS_H_
#ifndef __MAX17818_BATTERY_UTILS_H_
#define __MAX17818_BATTERY_UTILS_H_
#include <linux/mfd/max77818/max77818.h>
/* Exported function required for modules external to the max77818_battery
* module to be able to use the MAX77818_DO_NON_FGCC_OP macrov*/
int max77818_set_fgcc_mode(struct max77818_dev *max77818_dev,
bool enabled,
bool *cur_mode);
int max77818_utils_set_fgcc_mode(struct max77818_dev *max77818_dev,
bool enabled,
bool *cur_mode);
/* Magic to enable optional macro param */
#define VARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
@ -16,6 +16,76 @@ int max77818_set_fgcc_mode(struct max77818_dev *max77818_dev,
#define CONCAT_(a, b) a##b
#define CONCAT(a, b) CONCAT_(a, b)
/* Common macro to be user from any context having access to the common
* max77818 struct defined in the max77818 MDF driver */
#define MAX77818_START_NON_FGCC_OP_3(max77818_dev, fgcc_restore_state, op_description) ( \
{ \
int ret = 0; \
bool restore_state = 0; \
\
if (!max77818_dev) { \
dev_err(max77818_dev->dev, \
"max77818_dev is NULL in MAX77818_DO_NON_FGCC_OP\n"); \
ret = -EINVAL; \
} \
else { \
dev_dbg(max77818_dev->dev, "Applying lock\n"); \
mutex_lock(&max77818_dev->lock); \
\
dev_dbg(max77818_dev->dev, "Clearing FGCC mode\n"); \
ret = max77818_utils_set_fgcc_mode(max77818_dev, \
false, \
&restore_state); \
if (ret) { \
dev_err(max77818_dev->dev, \
"Failed to clear FGCC bit in CONFIG register\n"); \
} \
else { \
fgcc_restore_state = restore_state; \
} \
\
/* UNLOCKING IS DONE IN MAX77818_FINISH_NON_FGCC_OP */ \
} \
ret; \
})
#define MAX77818_START_NON_FGCC_OP_2(max77818_dev, fgcc_restore_state) MAX77818_START_NON_FGCC_OP_3(max77818_dev, fgcc_restore_state, "")
#define MAX77818_START_NON_FGCC_OP(...) ( CONCAT(MAX77818_START_NON_FGCC_OP_, VARGS(__VA_ARGS__))(__VA_ARGS__) )
/* Common macro to be user from any context having access to the common
* max77818 struct defined in the max77818 MDF driver */
#define MAX77818_FINISH_NON_FGCC_OP_3(max77818_dev, fgcc_restore_state, op_description) ( \
{ \
int ret = 0; \
\
if (!max77818_dev) { \
dev_err(max77818_dev->dev, \
"max77818_dev is NULL in MAX77818_DO_NON_FGCC_OP\n"); \
ret = -EINVAL; \
} \
else { \
if (fgcc_restore_state) { \
dev_dbg(max77818_dev->dev, "Restoring FGCC mode\n"); \
\
ret = max77818_utils_set_fgcc_mode(max77818_dev, \
true, \
NULL); \
if (ret) { \
dev_err(max77818_dev->dev, \
"Failed to set FGCC bit in CONFIG register\n"); \
} \
} \
else { \
dev_dbg(max77818_dev->dev, \
"Leaving FGCC bit as it were (OFF)\n"); \
} \
dev_dbg(max77818_dev->dev, "Releasing lock\n"); \
mutex_unlock(&max77818_dev->lock); \
} \
ret; \
})
#define MAX77818_FINISH_NON_FGCC_OP_2(max77818_dev, fgcc_restore_state) MAX77818_FINISH_NON_FGCC_OP_3(max77818_dev, fgcc_restore_state, "")
#define MAX77818_FINISH_NON_FGCC_OP(...) ( CONCAT(MAX77818_FINISH_NON_FGCC_OP_, VARGS(__VA_ARGS__))(__VA_ARGS__) )
/* Common macro to be used from any context having access to the common
* max77818 struct defined in the max77818 MFD driver */
#define MAX77818_DO_NON_FGCC_OP_3(max77818_dev, op, op_description) ( \
@ -25,7 +95,7 @@ int max77818_set_fgcc_mode(struct max77818_dev *max77818_dev,
\
if (!max77818_dev) { \
dev_err(max77818_dev->dev, \
"max77818_dev is NULL in MAX77818_DO_NON_FGCC_OP_3\n"); \
"max77818_dev is NULL in MAX77818_DO_NON_FGCC_OP\n"); \
ret = -EINVAL; \
} \
else { \
@ -33,9 +103,9 @@ int max77818_set_fgcc_mode(struct max77818_dev *max77818_dev,
\
dev_dbg(max77818_dev->dev, "Clearing FGCC mode\n"); \
\
ret = max77818_set_fgcc_mode(max77818_dev, \
false, \
&restore_state); \
ret = max77818_utils_set_fgcc_mode(max77818_dev, \
false, \
&restore_state); \
if (ret) { \
dev_err(max77818_dev->dev, \
"Failed to clear FGCC bit in CONFIG register\n"); \
@ -52,7 +122,8 @@ int max77818_set_fgcc_mode(struct max77818_dev *max77818_dev,
if (restore_state) { \
dev_dbg(max77818_dev->dev, "Restoring FGCC mode\n"); \
\
ret = max77818_set_fgcc_mode(max77818_dev, true, NULL); \
ret = max77818_utils_set_fgcc_mode( \
max77818_dev, true, NULL); \
if (ret) { \
dev_err(max77818_dev->dev, \
"Failed to set FGCC bit in CONFIG register\n"); \
@ -64,12 +135,11 @@ int max77818_set_fgcc_mode(struct max77818_dev *max77818_dev,
} \
} \
} \
mutex_unlock(&max77818_dev->lock); \
} \
mutex_unlock(&max77818_dev->lock); \
ret; \
})
#define MAX77818_DO_NON_FGCC_OP_2(max77818_dev, op) MAX77818_DO_NON_FGCC_OP_3(max77818_dev, op, "")
#define MAX77818_DO_NON_FGCC_OP(...) ( CONCAT(MAX77818_DO_NON_FGCC_OP_, VARGS(__VA_ARGS__))(__VA_ARGS__) )
#endif /* __MAX17818_UTILS_H_ */
#endif /* __MAX17818_BATTERY_UTILS_H_ */