|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH V2 10/33] xen/arm: Add helpers to retrieve an interrupt description from the device tree
On Wed, 2013-05-08 at 03:33 +0100, Julien Grall wrote:
> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
>
> Changes in v2:
> - Move interrupt type from xen/irq.h to xen/device_tree.h
> - Prefix all defines by DT_
> ---
> xen/common/device_tree.c | 362
> +++++++++++++++++++++++++++++++++++++++++
> xen/include/xen/device_tree.h | 130 +++++++++++++++
> 2 files changed, 492 insertions(+)
>
> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> index 8d37018..e5ff779 100644
> --- a/xen/common/device_tree.c
> +++ b/xen/common/device_tree.c
> @@ -27,8 +27,11 @@
>
> struct dt_early_info __initdata early_info;
> void *device_tree_flattened;
> +dt_irq_xlate_func dt_irq_xlate;
> /* Host device tree */
> struct dt_device_node *dt_host;
> +/* Interrupt controller node*/
> +const struct dt_device_node *dt_interrupt_controller;
>
> /**
> * struct dt_alias_prop - Alias property in 'aliases' node
> @@ -1020,6 +1023,81 @@ int dt_device_get_address(const struct dt_device_node
> *dev, int index,
> return 0;
> }
>
> +/**
> + * dt_find_node_by_phandle - Find a node given a phandle
> + * @handle: phandle of the node to find
> + *
> + * Returns a node pointer.
> + */
> +static const struct dt_device_node *dt_find_node_by_phandle(dt_phandle
> handle)
> +{
> + const struct dt_device_node *np;
> +
> + for_each_device_node(dt_host, np)
> + if ( np->phandle == handle )
> + break;
> +
> + return np;
> +}
> +
> +/**
> + * dt_irq_find_parent - Given a device node, find its interrupt parent node
> + * @child: pointer to device node
> + *
> + * Returns a pointer to the interrupt parent node, or NULL if the interrupt
> + * parent could not be determined.
> + */
> +static const struct dt_device_node *
> +dt_irq_find_parent(const struct dt_device_node *child)
> +{
> + const struct dt_device_node *p;
> + const __be32 *parp;
> +
> + do
> + {
> + parp = dt_get_property(child, "interrupt-parent", NULL);
> + if ( parp == NULL )
> + p = dt_get_parent(child);
> + else
> + p = dt_find_node_by_phandle(be32_to_cpup(parp));
> + child = p;
> + } while ( p && dt_get_property(p, "#interrupt-cells", NULL) == NULL );
> +
> + return p;
> +}
> +
> +unsigned int dt_number_of_irq(const struct dt_device_node *device)
> +{
> + const struct dt_device_node *p;
> + const __be32 *intspec, *tmp;
> + u32 intsize, intlen;
> +
> + dt_dprintk("dt_irq_number: dev=%s\n", device->full_name);
> +
> + /* Get the interrupts property */
> + intspec = dt_get_property(device, "interrupts", &intlen);
> + if ( intspec == NULL )
> + return 0;
> + intlen /= sizeof(*intspec);
> +
> + dt_dprintk(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
> +
> + /* Look for the interrupt parent. */
> + p = dt_irq_find_parent(device);
> + if ( p == NULL )
> + return 0;
> +
> + /* Get size of interrupt specifier */
> + tmp = dt_get_property(p, "#interrupt-cells", NULL);
> + if ( tmp == NULL )
> + return 0;
> + intsize = be32_to_cpu(*tmp);
> +
> + dt_dprintk(" intsize=%d intlen=%d\n", intsize, intlen);
> +
> + return (intlen / intsize);
> +}
> +
> unsigned int dt_number_of_address(const struct dt_device_node *dev)
> {
> const __be32 *prop;
> @@ -1051,6 +1129,274 @@ unsigned int dt_number_of_address(const struct
> dt_device_node *dev)
> }
>
> /**
> + * dt_irq_map_raw - Low level interrupt tree parsing
> + * @parent: the device interrupt parent
> + * @intspec: interrupt specifier ("interrupts" property of the device)
> + * @ointsize: size of the passed in interrupt specifier
> + * @addr: address specifier (start of "reg" property of the device)
> + * @oirq: structure dt_raw_irq filled by this function
> + *
> + * Returns 0 on success and a negative number on error
> + *
> + * This function is a low-level interrupt tree walking function. It
> + * can be used to do a partial walk with synthetized reg and interrupts
synthesized
> +/**
> + * dt_raw_irq - container for device_node/irq_specifier for an irq controller
> + * @controller: pointer to interrupt controller deivce tree node
> + * @size: size of interrupt specifier
> + * @specifier: array of cells @size long specifing the specific interrupt
specifying
> * DO NOT modify it!
> */
> extern struct dt_device_node *dt_host;
>
> +/**
> + * Primary interrupt controller
> + * Exynos SOC has an interrupt combiner, interrupt has no physical
^an
> + * meaning when it's not connected to the primary controller.
> + * We will only map interrupt whose parent controller is
> + * dt_interrupt_controller. It should always be a GIC.
> + * TODO: Handle multiple GIC
> + */
> +extern const struct dt_device_node *dt_interrupt_controller;
> +
> +/**
> + * Find the interrupt controller
> + * For the moment we handle only one interrupt controller: the first
> + * one without parent and is compatible with the string "compat".
... parent which is ...
> +/**
> * dt_number_of_address - Get the number of addresse for a device
addresses
> * @device: the device whose number of address is to be retrieved
> *
> @@ -300,6 +399,37 @@ int dt_device_get_address(const struct dt_device_node
> *dev, int index,
> unsigned int dt_number_of_address(const struct dt_device_node *device);
>
> /**
> + * dt_device_get_irq - Resolve an interrupt for a device
> + * @device: the device whose interrupt is to be resolved
> + * @index: index of the interrupt to resolve
> + * @out_irq: structure dt_irq filled by this function
> + *
> + * This function resolves an interrupt, walking the tree, for a given
> + * device-tree node. It's the high level pendant to dt_device_get_raw_irq().
> + */
> +int dt_device_get_irq(const struct dt_device_node *device, int index,
> + struct dt_irq *irq);
> +
> +/**
> + * dt_device_get_raw_irq - Resolve an interrupt for a device without
> translation
> + * @device: the device whose interrupt is to be resolved
> + * @index: index of the interrupt to resolve
> + * @out_irq: structure dt_raw_irq filled by this function
> + *
> + * This function resolves an interrupt for a device, no translation is
> + * made. dt_irq_translate can be called after.
> + */
> +int dt_device_get_raw_irq(const struct dt_device_node *device, int index,
> + struct dt_raw_irq *irq);
> +
> +/**
> + * dt_irq_transalte - Translate an irq
translate
Like with the previous patch I'm inclined to trust the logic is correct.
So if you fix the typoes:
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |