[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 |