[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.