bif: bif-core: add BIF object matching support
Update the BIF slave matching criteria so that BIF consumer drivers can find BIF slaves which contain BIF objects of a certain type. Also add functions which allow consumers to get handles for the BIF objects which match specified search criteria. Change-Id: Ice7042ecb3829db8f5601d91940c5f7bef383d3d Signed-off-by: David Collins <collinsd@codeaurora.org>
This commit is contained in:
parent
356ab1e444
commit
5bfb07eada
|
@ -235,10 +235,10 @@ registration order.
|
|||
Get/put handle for a BIF slave:
|
||||
-------------------------------
|
||||
|
||||
int bif_slave_match_count(const struct bif_ctrl *ctrl,
|
||||
int bif_slave_match_count(struct bif_ctrl *ctrl,
|
||||
const struct bif_match_criteria *match_criteria);
|
||||
|
||||
struct bif_slave *bif_slave_match_get(const struct bif_ctrl *ctrl,
|
||||
struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl,
|
||||
unsigned int id, const struct bif_match_criteria *match_criteria);
|
||||
|
||||
void bif_slave_put(struct bif_slave *slave);
|
||||
|
@ -293,7 +293,6 @@ int bif_ctrl_notifier_register(struct bif_ctrl *ctrl,
|
|||
int bif_ctrl_notifier_unregister(struct bif_ctrl *ctrl,
|
||||
struct notifier_block *nb);
|
||||
|
||||
|
||||
Read or write BIF slave registers:
|
||||
----------------------------------
|
||||
|
||||
|
@ -315,6 +314,20 @@ Raw NVM writing may be needed in order to intialize the NVM BIF object list.
|
|||
However, its use can be dangerous as it can overwrite existing objects in the
|
||||
list and make the list unparsable.
|
||||
|
||||
BIF object search in slave non-volatile memory:
|
||||
-----------------------------------------------
|
||||
int bif_object_match_count(struct bif_slave *slave,
|
||||
const struct bif_obj_match_criteria *match_criteria);
|
||||
|
||||
struct bif_object *bif_object_match_get(struct bif_slave *slave,
|
||||
unsigned int id, const struct bif_obj_match_criteria *match_criteria);
|
||||
|
||||
void bif_object_put(struct bif_object *object);
|
||||
|
||||
bif_object_match_count() and bif_object_match_get() can be used together in
|
||||
order to retrieve the set of BIF objects within a slave which match certain
|
||||
criteria. bif_object_put() is used to free the memory allocated by
|
||||
bif_object_match_get().
|
||||
|
||||
Get or set the BIF bus state or period:
|
||||
---------------------------------------
|
||||
|
|
|
@ -1526,16 +1526,29 @@ void bif_ctrl_put(struct bif_ctrl *ctrl)
|
|||
}
|
||||
EXPORT_SYMBOL(bif_ctrl_put);
|
||||
|
||||
static bool bif_slave_object_match(const struct bif_object *object,
|
||||
const struct bif_match_criteria *criteria)
|
||||
{
|
||||
return (object->type == criteria->obj_type)
|
||||
&& (object->version == criteria->obj_version
|
||||
|| !(criteria->match_mask & BIF_MATCH_OBJ_VERSION))
|
||||
&& (object->manufacturer_id == criteria->obj_manufacturer_id
|
||||
|| !(criteria->match_mask & BIF_MATCH_OBJ_MANUFACTURER_ID));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if all parameters are matched, otherwise false.
|
||||
* function_type and function_version mean that their exists some function in
|
||||
* the slave which has the specified type and subtype. ctrl == NULL is treated
|
||||
* as a wildcard.
|
||||
*/
|
||||
static bool bif_slave_match(const struct bif_ctrl *ctrl,
|
||||
static bool bif_slave_match(struct bif_ctrl *ctrl,
|
||||
struct bif_slave_dev *sdev, const struct bif_match_criteria *criteria)
|
||||
{
|
||||
int i, type, version;
|
||||
struct bif_object *object;
|
||||
bool function_found = false;
|
||||
bool object_found = false;
|
||||
|
||||
if (ctrl && (ctrl->bdev != sdev->bdev))
|
||||
return false;
|
||||
|
@ -1563,10 +1576,29 @@ static bool bif_slave_match(const struct bif_ctrl *ctrl,
|
|||
if (type == criteria->function_type &&
|
||||
(version == criteria->function_version
|
||||
|| !(criteria->match_mask
|
||||
& BIF_MATCH_FUNCTION_VERSION)))
|
||||
return true;
|
||||
& BIF_MATCH_FUNCTION_VERSION))) {
|
||||
function_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (!function_found)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (criteria->match_mask & BIF_MATCH_OBJ_TYPE) {
|
||||
if (!sdev->nvm_function)
|
||||
return false;
|
||||
bif_ctrl_lock(ctrl);
|
||||
list_for_each_entry(object, &sdev->nvm_function->object_list,
|
||||
list) {
|
||||
if (bif_slave_object_match(object, criteria)) {
|
||||
object_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bif_ctrl_unlock(ctrl);
|
||||
if (!object_found)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1579,7 +1611,7 @@ static bool bif_slave_match(const struct bif_ctrl *ctrl,
|
|||
* @ctrl: BIF controller consumer handle
|
||||
* @match_criteria: Matching criteria used to filter slaves
|
||||
*/
|
||||
int bif_slave_match_count(const struct bif_ctrl *ctrl,
|
||||
int bif_slave_match_count(struct bif_ctrl *ctrl,
|
||||
const struct bif_match_criteria *match_criteria)
|
||||
{
|
||||
struct bif_slave_dev *sdev;
|
||||
|
@ -1610,7 +1642,7 @@ EXPORT_SYMBOL(bif_slave_match_count);
|
|||
*
|
||||
* Returns a BIF slave handle if successful or an ERR_PTR if not.
|
||||
*/
|
||||
struct bif_slave *bif_slave_match_get(const struct bif_ctrl *ctrl,
|
||||
struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl,
|
||||
unsigned int id, const struct bif_match_criteria *match_criteria)
|
||||
{
|
||||
struct bif_slave_dev *sdev;
|
||||
|
@ -1699,6 +1731,135 @@ int bif_slave_find_function(struct bif_slave *slave, u8 function, u8 *version,
|
|||
}
|
||||
EXPORT_SYMBOL(bif_slave_find_function);
|
||||
|
||||
static bool bif_object_match(const struct bif_object *object,
|
||||
const struct bif_obj_match_criteria *criteria)
|
||||
{
|
||||
return (object->type == criteria->type
|
||||
|| !(criteria->match_mask & BIF_OBJ_MATCH_TYPE))
|
||||
&& (object->version == criteria->version
|
||||
|| !(criteria->match_mask & BIF_OBJ_MATCH_VERSION))
|
||||
&& (object->manufacturer_id == criteria->manufacturer_id
|
||||
|| !(criteria->match_mask & BIF_OBJ_MATCH_MANUFACTURER_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* bif_object_match_count() - returns the number of objects associated with the
|
||||
* specified BIF slave which fit the matching criteria
|
||||
* @slave: BIF slave handle
|
||||
* @match_criteria: Matching criteria used to filter objects
|
||||
*/
|
||||
int bif_object_match_count(struct bif_slave *slave,
|
||||
const struct bif_obj_match_criteria *match_criteria)
|
||||
{
|
||||
struct bif_object *object;
|
||||
int count = 0;
|
||||
|
||||
if (IS_ERR_OR_NULL(slave) || IS_ERR_OR_NULL(match_criteria)) {
|
||||
pr_err("Invalid pointer input.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!slave->sdev->nvm_function)
|
||||
return 0;
|
||||
|
||||
bif_slave_ctrl_lock(slave);
|
||||
list_for_each_entry(object, &slave->sdev->nvm_function->object_list,
|
||||
list) {
|
||||
if (bif_object_match(object, match_criteria))
|
||||
count++;
|
||||
}
|
||||
bif_slave_ctrl_unlock(slave);
|
||||
|
||||
return count;
|
||||
}
|
||||
EXPORT_SYMBOL(bif_object_match_count);
|
||||
|
||||
/**
|
||||
* bif_object_match_get() - get a BIF object handle for the id'th object found
|
||||
* in the non-volatile memory of the specified BIF slave
|
||||
* which fits the matching criteria
|
||||
* @slave: BIF slave handle
|
||||
* @id: Index into the set of matching objects
|
||||
* @match_criteria: Matching criteria used to filter objects
|
||||
*
|
||||
* id must be in range [0, bif_object_match_count(slave, match_criteria) - 1].
|
||||
*
|
||||
* Returns a BIF object handle if successful or an ERR_PTR if not. This handle
|
||||
* must be freed using bif_object_put() when it is no longer needed.
|
||||
*/
|
||||
struct bif_object *bif_object_match_get(struct bif_slave *slave,
|
||||
unsigned int id, const struct bif_obj_match_criteria *match_criteria)
|
||||
{
|
||||
struct bif_object *object;
|
||||
struct bif_object *object_found = NULL;
|
||||
struct bif_object *object_consumer = ERR_PTR(-ENODEV);
|
||||
int count = 0;
|
||||
|
||||
if (IS_ERR_OR_NULL(slave) || IS_ERR_OR_NULL(match_criteria)) {
|
||||
pr_err("Invalid pointer input.\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (!slave->sdev->nvm_function)
|
||||
return object_consumer;
|
||||
|
||||
bif_slave_ctrl_lock(slave);
|
||||
list_for_each_entry(object, &slave->sdev->nvm_function->object_list,
|
||||
list) {
|
||||
if (bif_object_match(object, match_criteria))
|
||||
count++;
|
||||
if (count == id + 1) {
|
||||
object_found = object;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (object_found) {
|
||||
object_consumer = kmemdup(object_found,
|
||||
sizeof(*object_consumer), GFP_KERNEL);
|
||||
if (!object_consumer) {
|
||||
pr_err("out of memory\n");
|
||||
object_consumer = ERR_PTR(-ENOMEM);
|
||||
goto done;
|
||||
}
|
||||
|
||||
object_consumer->data = kmemdup(object_found->data,
|
||||
object_found->length - 8, GFP_KERNEL);
|
||||
if (!object_consumer->data) {
|
||||
pr_err("out of memory\n");
|
||||
kfree(object_consumer);
|
||||
object_consumer = ERR_PTR(-ENOMEM);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use prev pointer in consumer struct to point to original
|
||||
* struct in the internal linked list.
|
||||
*/
|
||||
object_consumer->list.prev = &object_found->list;
|
||||
}
|
||||
|
||||
done:
|
||||
bif_slave_ctrl_unlock(slave);
|
||||
|
||||
return object_consumer;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(bif_object_match_get);
|
||||
|
||||
/**
|
||||
* bif_object_put() - frees the memory allocated for a BIF object pointer
|
||||
* returned by bif_object_match_get()
|
||||
* @object: BIF object to free
|
||||
*/
|
||||
void bif_object_put(struct bif_object *object)
|
||||
{
|
||||
if (object)
|
||||
kfree(object->data);
|
||||
kfree(object);
|
||||
}
|
||||
EXPORT_SYMBOL(bif_object_put);
|
||||
|
||||
/**
|
||||
* bif_slave_read() - read contiguous memory values from a BIF slave
|
||||
* @slave: BIF slave handle
|
||||
|
|
|
@ -311,10 +311,11 @@ enum bif_mipi_object_type {
|
|||
* @type: Object type
|
||||
* @version: Object version
|
||||
* @manufacturer_id: Manufacturer ID number allocated by MIPI
|
||||
* @length: Length of the entire object including header and CRC
|
||||
* @length: Length of the entire object including header and CRC;
|
||||
* data length == total length - 8.
|
||||
* @data: Raw byte data found in the object
|
||||
* @crc: CRC of the object calculated using CRC-CCITT
|
||||
* @list: Linked-list connection parameter
|
||||
* @list: Linked-list connection parameter; internal use only
|
||||
* @addr: BIF slave address correspond to the start of the object
|
||||
*
|
||||
* manufacturer_id == 0x0000 if MIPI type and version.
|
||||
|
@ -415,6 +416,9 @@ enum bif_bus_event {
|
|||
#define BIF_MATCH_FUNCTION_TYPE BIT(2)
|
||||
#define BIF_MATCH_FUNCTION_VERSION BIT(3)
|
||||
#define BIF_MATCH_IGNORE_PRESENCE BIT(4)
|
||||
#define BIF_MATCH_OBJ_TYPE BIT(5)
|
||||
#define BIF_MATCH_OBJ_VERSION BIT(6)
|
||||
#define BIF_MATCH_OBJ_MANUFACTURER_ID BIT(7)
|
||||
|
||||
/**
|
||||
* struct bif_match_criteria - specifies the matching criteria that a BIF
|
||||
|
@ -431,6 +435,17 @@ enum bif_bus_event {
|
|||
* @ignore_presence: If true, then slaves that are currently not present
|
||||
* will be successfully matched against. By default, only
|
||||
* present slaves can be matched.
|
||||
* @obj_type: Defines the type of a BIF object found in the
|
||||
* non-volatile memory of a slave.
|
||||
* @obj_version: Defines the version of a BIF object found in the
|
||||
* non-volatile memory of a slave.
|
||||
* @obj_manufacturer_id: Manufacturer ID of a BIF object found in the
|
||||
* non-volatile memory of a slave.
|
||||
*
|
||||
* If function_type and function_verion are both specified, then they must both
|
||||
* match for a single BIF function. If obj_type and obj_version or
|
||||
* obj_manufacturer_id are specified, then all must match for a single BIF
|
||||
* object.
|
||||
*/
|
||||
struct bif_match_criteria {
|
||||
u32 match_mask;
|
||||
|
@ -439,6 +454,34 @@ struct bif_match_criteria {
|
|||
u8 function_type;
|
||||
u8 function_version;
|
||||
bool ignore_presence;
|
||||
u8 obj_type;
|
||||
u8 obj_version;
|
||||
u16 obj_manufacturer_id;
|
||||
};
|
||||
|
||||
/* Mask values to be ORed for use in bif_obj_match_criteria.match_mask. */
|
||||
#define BIF_OBJ_MATCH_TYPE BIT(0)
|
||||
#define BIF_OBJ_MATCH_VERSION BIT(1)
|
||||
#define BIF_OBJ_MATCH_MANUFACTURER_ID BIT(2)
|
||||
|
||||
/**
|
||||
* struct bif_obj_match_criteria - specifies the matching criteria that a BIF
|
||||
* consumer uses to find an appropriate BIF data object
|
||||
* within a slave
|
||||
* @match_mask: Mask value specifying which parameters to match upon.
|
||||
* This value should be some ORed combination of
|
||||
* BIF_OBJ_MATCH_* specified above.
|
||||
* @type: Defines the type of the object. The type may be either
|
||||
* MIPI or manufacturer defined.
|
||||
* @version: Defines the version of the object. The version may be
|
||||
* either MIPI or manufacturer defined.
|
||||
* @manufacturer_id: Manufacturer ID number allocated by MIPI.
|
||||
*/
|
||||
struct bif_obj_match_criteria {
|
||||
u32 match_mask;
|
||||
u8 type;
|
||||
u8 version;
|
||||
u16 manufacturer_id;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -486,10 +529,10 @@ void bif_ctrl_put(struct bif_ctrl *ctrl);
|
|||
|
||||
int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl);
|
||||
|
||||
int bif_slave_match_count(const struct bif_ctrl *ctrl,
|
||||
int bif_slave_match_count(struct bif_ctrl *ctrl,
|
||||
const struct bif_match_criteria *match_criteria);
|
||||
|
||||
struct bif_slave *bif_slave_match_get(const struct bif_ctrl *ctrl,
|
||||
struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl,
|
||||
unsigned int id, const struct bif_match_criteria *match_criteria);
|
||||
|
||||
void bif_slave_put(struct bif_slave *slave);
|
||||
|
@ -505,6 +548,14 @@ struct bif_ctrl *bif_get_ctrl_handle(struct bif_slave *slave);
|
|||
int bif_slave_find_function(struct bif_slave *slave, u8 function, u8 *version,
|
||||
u16 *function_pointer);
|
||||
|
||||
int bif_object_match_count(struct bif_slave *slave,
|
||||
const struct bif_obj_match_criteria *match_criteria);
|
||||
|
||||
struct bif_object *bif_object_match_get(struct bif_slave *slave,
|
||||
unsigned int id, const struct bif_obj_match_criteria *match_criteria);
|
||||
|
||||
void bif_object_put(struct bif_object *object);
|
||||
|
||||
int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf, int len);
|
||||
int bif_slave_write(struct bif_slave *slave, u16 addr, u8 *buf, int len);
|
||||
|
||||
|
@ -563,11 +614,11 @@ static inline void bif_ctrl_put(struct bif_ctrl *ctrl) { return; }
|
|||
static inline int bif_ctrl_signal_battery_changed(struct bif_ctrl *ctrl)
|
||||
{ return -EPERM; }
|
||||
|
||||
static inline int bif_slave_match_count(const struct bif_ctrl *ctrl,
|
||||
static inline int bif_slave_match_count(struct bif_ctrl *ctrl,
|
||||
const struct bif_match_criteria *match_criteria)
|
||||
{ return -EPERM; }
|
||||
|
||||
static inline struct bif_slave *bif_slave_match_get(const struct bif_ctrl *ctrl,
|
||||
static inline struct bif_slave *bif_slave_match_get(struct bif_ctrl *ctrl,
|
||||
unsigned int id, const struct bif_match_criteria *match_criteria)
|
||||
{ return ERR_PTR(-EPERM); }
|
||||
|
||||
|
@ -588,6 +639,17 @@ static inline int bif_slave_find_function(struct bif_slave *slave, u8 function,
|
|||
u8 *version, u16 *function_pointer)
|
||||
{ return -EPERM; }
|
||||
|
||||
static inline int bif_object_match_count(struct bif_slave *slave,
|
||||
const struct bif_obj_match_criteria *match_criteria)
|
||||
{ return -EPERM; }
|
||||
|
||||
static inline struct bif_object *bif_object_match_get(struct bif_slave *slave,
|
||||
unsigned int id, const struct bif_obj_match_criteria *match_criteria)
|
||||
{ return ERR_PTR(-EPERM); }
|
||||
|
||||
static inline void bif_object_put(struct bif_object *object)
|
||||
{}
|
||||
|
||||
static inline int bif_slave_read(struct bif_slave *slave, u16 addr, u8 *buf,
|
||||
int len)
|
||||
{ return -EPERM; }
|
||||
|
|
Loading…
Reference in New Issue