firmware: ti_sci: rm: Add support for second resource range

Sysfw added support for a second range in the resource range API to be able
to describe complex allocations mainly for DMA channels.

Update the ti_sci part to consider the second range as well.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
This commit is contained in:
Peter Ujfalusi 2020-10-25 12:10:03 -07:00 committed by Santosh Shilimkar
parent 967a020bd3
commit 519c5c0c55
3 changed files with 43 additions and 21 deletions

View File

@ -1751,11 +1751,14 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
if (!ti_sci_is_response_ack(resp)) { if (!ti_sci_is_response_ack(resp)) {
ret = -ENODEV; ret = -ENODEV;
} else if (!resp->range_start && !resp->range_num) { } else if (!resp->range_num && !resp->range_num_sec) {
/* Neither of the two resource range is valid */
ret = -ENODEV; ret = -ENODEV;
} else { } else {
desc->start = resp->range_start; desc->start = resp->range_start;
desc->num = resp->range_num; desc->num = resp->range_num;
desc->start_sec = resp->range_start_sec;
desc->num_sec = resp->range_num_sec;
}; };
fail: fail:
@ -3157,12 +3160,18 @@ u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
raw_spin_lock_irqsave(&res->lock, flags); raw_spin_lock_irqsave(&res->lock, flags);
for (set = 0; set < res->sets; set++) { for (set = 0; set < res->sets; set++) {
free_bit = find_first_zero_bit(res->desc[set].res_map, struct ti_sci_resource_desc *desc = &res->desc[set];
res->desc[set].num); int res_count = desc->num + desc->num_sec;
if (free_bit != res->desc[set].num) {
set_bit(free_bit, res->desc[set].res_map); free_bit = find_first_zero_bit(desc->res_map, res_count);
if (free_bit != res_count) {
set_bit(free_bit, desc->res_map);
raw_spin_unlock_irqrestore(&res->lock, flags); raw_spin_unlock_irqrestore(&res->lock, flags);
return res->desc[set].start + free_bit;
if (desc->num && free_bit < desc->num)
return desc->start + free_bit;
else
return desc->start_sec + free_bit;
} }
} }
raw_spin_unlock_irqrestore(&res->lock, flags); raw_spin_unlock_irqrestore(&res->lock, flags);
@ -3183,10 +3192,14 @@ void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
raw_spin_lock_irqsave(&res->lock, flags); raw_spin_lock_irqsave(&res->lock, flags);
for (set = 0; set < res->sets; set++) { for (set = 0; set < res->sets; set++) {
if (res->desc[set].start <= id && struct ti_sci_resource_desc *desc = &res->desc[set];
(res->desc[set].num + res->desc[set].start) > id)
clear_bit(id - res->desc[set].start, if (desc->num && desc->start <= id &&
res->desc[set].res_map); (desc->start + desc->num) > id)
clear_bit(id - desc->start, desc->res_map);
else if (desc->num_sec && desc->start_sec <= id &&
(desc->start_sec + desc->num_sec) > id)
clear_bit(id - desc->start_sec, desc->res_map);
} }
raw_spin_unlock_irqrestore(&res->lock, flags); raw_spin_unlock_irqrestore(&res->lock, flags);
} }
@ -3203,7 +3216,7 @@ u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
u32 set, count = 0; u32 set, count = 0;
for (set = 0; set < res->sets; set++) for (set = 0; set < res->sets; set++)
count += res->desc[set].num; count += res->desc[set].num + res->desc[set].num_sec;
return count; return count;
} }
@ -3227,7 +3240,7 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
{ {
struct ti_sci_resource *res; struct ti_sci_resource *res;
bool valid_set = false; bool valid_set = false;
int i, ret; int i, ret, res_count;
res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
if (!res) if (!res)
@ -3246,18 +3259,19 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
if (ret) { if (ret) {
dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n", dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n",
dev_id, sub_types[i]); dev_id, sub_types[i]);
res->desc[i].start = 0; memset(&res->desc[i], 0, sizeof(res->desc[i]));
res->desc[i].num = 0;
continue; continue;
} }
dev_dbg(dev, "dev = %d, subtype = %d, start = %d, num = %d\n", dev_dbg(dev, "dev/sub_type: %d/%d, start/num: %d/%d | %d/%d\n",
dev_id, sub_types[i], res->desc[i].start, dev_id, sub_types[i], res->desc[i].start,
res->desc[i].num); res->desc[i].num, res->desc[i].start_sec,
res->desc[i].num_sec);
valid_set = true; valid_set = true;
res_count = res->desc[i].num + res->desc[i].num_sec;
res->desc[i].res_map = res->desc[i].res_map =
devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) * devm_kzalloc(dev, BITS_TO_LONGS(res_count) *
sizeof(*res->desc[i].res_map), GFP_KERNEL); sizeof(*res->desc[i].res_map), GFP_KERNEL);
if (!res->desc[i].res_map) if (!res->desc[i].res_map)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);

View File

@ -574,8 +574,10 @@ struct ti_sci_msg_req_get_resource_range {
/** /**
* struct ti_sci_msg_resp_get_resource_range - Response to resource get range. * struct ti_sci_msg_resp_get_resource_range - Response to resource get range.
* @hdr: Generic Header * @hdr: Generic Header
* @range_start: Start index of the resource range. * @range_start: Start index of the first resource range.
* @range_num: Number of resources in the range. * @range_num: Number of resources in the first range.
* @range_start_sec: Start index of the second resource range.
* @range_num_sec: Number of resources in the second range.
* *
* Response to request TI_SCI_MSG_GET_RESOURCE_RANGE. * Response to request TI_SCI_MSG_GET_RESOURCE_RANGE.
*/ */
@ -583,6 +585,8 @@ struct ti_sci_msg_resp_get_resource_range {
struct ti_sci_msg_hdr hdr; struct ti_sci_msg_hdr hdr;
u16 range_start; u16 range_start;
u16 range_num; u16 range_num;
u16 range_start_sec;
u16 range_num_sec;
} __packed; } __packed;
/** /**

View File

@ -197,13 +197,17 @@ struct ti_sci_clk_ops {
/** /**
* struct ti_sci_resource_desc - Description of TI SCI resource instance range. * struct ti_sci_resource_desc - Description of TI SCI resource instance range.
* @start: Start index of the resource. * @start: Start index of the first resource range.
* @num: Number of resources. * @num: Number of resources in the first range.
* @start_sec: Start index of the second resource range.
* @num_sec: Number of resources in the second range.
* @res_map: Bitmap to manage the allocation of these resources. * @res_map: Bitmap to manage the allocation of these resources.
*/ */
struct ti_sci_resource_desc { struct ti_sci_resource_desc {
u16 start; u16 start;
u16 num; u16 num;
u16 start_sec;
u16 num_sec;
unsigned long *res_map; unsigned long *res_map;
}; };