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
parent
fa988b33eb
commit
de8a5c1952
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue