firmware: ti_sci: Add support for getting resource with subtype

With SYSFW ABI 3.0 changes, interrupts coming out of an interrupt
controller is identified by a type and it is consistent across SoCs.
Similarly global events for Interrupt aggregator. So add an API to get
resource range using a resource type.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: Nishanth Menon <nm@ti.com>
Link: https://lore.kernel.org/r/20200806074826.24607-4-lokeshvutla@ti.com
This commit is contained in:
Lokesh Vutla 2020-08-06 13:18:16 +05:30 committed by Marc Zyngier
parent 9b98e02a3d
commit 53bf2b0e4e
2 changed files with 80 additions and 22 deletions

View File

@ -3208,61 +3208,50 @@ u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
EXPORT_SYMBOL_GPL(ti_sci_get_num_resources); EXPORT_SYMBOL_GPL(ti_sci_get_num_resources);
/** /**
* devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device * devm_ti_sci_get_resource_sets() - Get a TISCI resources assigned to a device
* @handle: TISCI handle * @handle: TISCI handle
* @dev: Device pointer to which the resource is assigned * @dev: Device pointer to which the resource is assigned
* @dev_id: TISCI device id to which the resource is assigned * @dev_id: TISCI device id to which the resource is assigned
* @of_prop: property name by which the resource are represented * @sub_types: Array of sub_types assigned corresponding to device
* @sets: Number of sub_types
* *
* Return: Pointer to ti_sci_resource if all went well else appropriate * Return: Pointer to ti_sci_resource if all went well else appropriate
* error pointer. * error pointer.
*/ */
struct ti_sci_resource * static struct ti_sci_resource *
devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
struct device *dev, u32 dev_id, char *of_prop) struct device *dev, u32 dev_id, u32 *sub_types,
u32 sets)
{ {
struct ti_sci_resource *res; struct ti_sci_resource *res;
bool valid_set = false; bool valid_set = false;
u32 resource_subtype;
int i, ret; int i, ret;
res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
if (!res) if (!res)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ret = of_property_count_elems_of_size(dev_of_node(dev), of_prop, res->sets = sets;
sizeof(u32));
if (ret < 0) {
dev_err(dev, "%s resource type ids not available\n", of_prop);
return ERR_PTR(ret);
}
res->sets = ret;
res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc), res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
GFP_KERNEL); GFP_KERNEL);
if (!res->desc) if (!res->desc)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
for (i = 0; i < res->sets; i++) { for (i = 0; i < res->sets; i++) {
ret = of_property_read_u32_index(dev_of_node(dev), of_prop, i,
&resource_subtype);
if (ret)
return ERR_PTR(-EINVAL);
ret = handle->ops.rm_core_ops.get_range(handle, dev_id, ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
resource_subtype, sub_types[i],
&res->desc[i].start, &res->desc[i].start,
&res->desc[i].num); &res->desc[i].num);
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, resource_subtype); dev_id, sub_types[i]);
res->desc[i].start = 0; res->desc[i].start = 0;
res->desc[i].num = 0; res->desc[i].num = 0;
continue; continue;
} }
dev_dbg(dev, "dev = %d, subtype = %d, start = %d, num = %d\n", dev_dbg(dev, "dev = %d, subtype = %d, start = %d, num = %d\n",
dev_id, resource_subtype, res->desc[i].start, dev_id, sub_types[i], res->desc[i].start,
res->desc[i].num); res->desc[i].num);
valid_set = true; valid_set = true;
@ -3280,6 +3269,62 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
/**
* devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
* @handle: TISCI handle
* @dev: Device pointer to which the resource is assigned
* @dev_id: TISCI device id to which the resource is assigned
* @of_prop: property name by which the resource are represented
*
* Return: Pointer to ti_sci_resource if all went well else appropriate
* error pointer.
*/
struct ti_sci_resource *
devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
struct device *dev, u32 dev_id, char *of_prop)
{
struct ti_sci_resource *res;
u32 *sub_types;
int sets;
sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop,
sizeof(u32));
if (sets < 0) {
dev_err(dev, "%s resource type ids not available\n", of_prop);
return ERR_PTR(sets);
}
sub_types = kcalloc(sets, sizeof(*sub_types), GFP_KERNEL);
if (!sub_types)
return ERR_PTR(-ENOMEM);
of_property_read_u32_array(dev_of_node(dev), of_prop, sub_types, sets);
res = devm_ti_sci_get_resource_sets(handle, dev, dev_id, sub_types,
sets);
kfree(sub_types);
return res;
}
EXPORT_SYMBOL_GPL(devm_ti_sci_get_of_resource);
/**
* devm_ti_sci_get_resource() - Get a resource range assigned to the device
* @handle: TISCI handle
* @dev: Device pointer to which the resource is assigned
* @dev_id: TISCI device id to which the resource is assigned
* @suub_type: TISCI resource subytpe representing the resource.
*
* Return: Pointer to ti_sci_resource if all went well else appropriate
* error pointer.
*/
struct ti_sci_resource *
devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
u32 dev_id, u32 sub_type)
{
return devm_ti_sci_get_resource_sets(handle, dev, dev_id, &sub_type, 1);
}
EXPORT_SYMBOL_GPL(devm_ti_sci_get_resource);
static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode, static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
void *cmd) void *cmd)
{ {

View File

@ -220,6 +220,9 @@ struct ti_sci_rm_core_ops {
u16 *range_start, u16 *range_num); u16 *range_start, u16 *range_num);
}; };
#define TI_SCI_RESASG_SUBTYPE_IR_OUTPUT 0
#define TI_SCI_RESASG_SUBTYPE_IA_VINT 0xa
#define TI_SCI_RESASG_SUBTYPE_GLOBAL_EVENT_SEVT 0xd
/** /**
* struct ti_sci_rm_irq_ops: IRQ management operations * struct ti_sci_rm_irq_ops: IRQ management operations
* @set_irq: Set an IRQ route between the requested source * @set_irq: Set an IRQ route between the requested source
@ -556,6 +559,9 @@ u32 ti_sci_get_num_resources(struct ti_sci_resource *res);
struct ti_sci_resource * struct ti_sci_resource *
devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
struct device *dev, u32 dev_id, char *of_prop); struct device *dev, u32 dev_id, char *of_prop);
struct ti_sci_resource *
devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
u32 dev_id, u32 sub_type);
#else /* CONFIG_TI_SCI_PROTOCOL */ #else /* CONFIG_TI_SCI_PROTOCOL */
@ -609,6 +615,13 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
{ {
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
static inline struct ti_sci_resource *
devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
u32 dev_id, u32 sub_type);
{
return ERR_PTR(-EINVAL);
}
#endif /* CONFIG_TI_SCI_PROTOCOL */ #endif /* CONFIG_TI_SCI_PROTOCOL */
#endif /* __TISCI_PROTOCOL_H */ #endif /* __TISCI_PROTOCOL_H */