mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-01 16:14:13 +08:00
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:
parent
9b98e02a3d
commit
53bf2b0e4e
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user