firmware: ti_sci: rm: Add support for second resource range
authorPeter Ujfalusi <peter.ujfalusi@ti.com>
Sun, 25 Oct 2020 19:10:03 +0000 (12:10 -0700)
committerSantosh Shilimkar <santosh.shilimkar@oracle.com>
Mon, 2 Nov 2020 03:37:59 +0000 (19:37 -0800)
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>
drivers/firmware/ti_sci.c
drivers/firmware/ti_sci.h
include/linux/soc/ti/ti_sci_protocol.h

index 7a777e9..2793bb9 100644 (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)) {
                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;
        } else {
                desc->start = resp->range_start;
                desc->num = resp->range_num;
+               desc->start_sec = resp->range_start_sec;
+               desc->num_sec = resp->range_num_sec;
        };
 
 fail:
@@ -3157,12 +3160,18 @@ u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
 
        raw_spin_lock_irqsave(&res->lock, flags);
        for (set = 0; set < res->sets; set++) {
-               free_bit = find_first_zero_bit(res->desc[set].res_map,
-                                              res->desc[set].num);
-               if (free_bit != res->desc[set].num) {
-                       set_bit(free_bit, res->desc[set].res_map);
+               struct ti_sci_resource_desc *desc = &res->desc[set];
+               int res_count = desc->num + desc->num_sec;
+
+               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);
-                       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);
@@ -3183,10 +3192,14 @@ void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
 
        raw_spin_lock_irqsave(&res->lock, flags);
        for (set = 0; set < res->sets; set++) {
-               if (res->desc[set].start <= id &&
-                   (res->desc[set].num + res->desc[set].start) > id)
-                       clear_bit(id - res->desc[set].start,
-                                 res->desc[set].res_map);
+               struct ti_sci_resource_desc *desc = &res->desc[set];
+
+               if (desc->num && desc->start <= id &&
+                   (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);
 }
@@ -3203,7 +3216,7 @@ u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
        u32 set, count = 0;
 
        for (set = 0; set < res->sets; set++)
-               count += res->desc[set].num;
+               count += res->desc[set].num + res->desc[set].num_sec;
 
        return count;
 }
@@ -3227,7 +3240,7 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
 {
        struct ti_sci_resource *res;
        bool valid_set = false;
-       int i, ret;
+       int i, ret, res_count;
 
        res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
        if (!res)
@@ -3246,18 +3259,19 @@ devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
                if (ret) {
                        dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n",
                                dev_id, sub_types[i]);
-                       res->desc[i].start = 0;
-                       res->desc[i].num = 0;
+                       memset(&res->desc[i], 0, sizeof(res->desc[i]));
                        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,
-                       res->desc[i].num);
+                       res->desc[i].num, res->desc[i].start_sec,
+                       res->desc[i].num_sec);
 
                valid_set = true;
+               res_count = res->desc[i].num + res->desc[i].num_sec;
                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);
                if (!res->desc[i].res_map)
                        return ERR_PTR(-ENOMEM);
index dca19ca..4d980eb 100644 (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.
  * @hdr:               Generic Header
- * @range_start:       Start index of the resource range.
- * @range_num:         Number of resources in the range.
+ * @range_start:       Start index of the first resource 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.
  */
@@ -583,6 +585,8 @@ struct ti_sci_msg_resp_get_resource_range {
        struct ti_sci_msg_hdr hdr;
        u16 range_start;
        u16 range_num;
+       u16 range_start_sec;
+       u16 range_num_sec;
 } __packed;
 
 /**
index 6cd537d..9699b26 100644 (file)
@@ -197,13 +197,17 @@ struct ti_sci_clk_ops {
 
 /**
  * struct ti_sci_resource_desc - Description of TI SCI resource instance range.
- * @start:     Start index of the resource.
- * @num:       Number of resources.
+ * @start:     Start index of the first resource range.
+ * @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.
  */
 struct ti_sci_resource_desc {
        u16 start;
        u16 num;
+       u16 start_sec;
+       u16 num_sec;
        unsigned long *res_map;
 };