[rtems-libbsd commit] linux/of_irq.h: Generalize of_irq_to_resource()
Sebastian Huber
sebh at rtems.org
Tue Jan 23 13:58:20 UTC 2018
Module: rtems-libbsd
Branch: master
Commit: cfc149bff3044b5029c2b574d5d3de05b979bf62
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=cfc149bff3044b5029c2b574d5d3de05b979bf62
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Wed Jan 10 14:11:57 2018 +0100
linux/of_irq.h: Generalize of_irq_to_resource()
Determine interrupt cells via device tree.
Update #3277.
---
rtemsbsd/sys/powerpc/compat.c | 61 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 51 insertions(+), 10 deletions(-)
diff --git a/rtemsbsd/sys/powerpc/compat.c b/rtemsbsd/sys/powerpc/compat.c
index 45f06e5..01502e8 100644
--- a/rtemsbsd/sys/powerpc/compat.c
+++ b/rtemsbsd/sys/powerpc/compat.c
@@ -362,32 +362,73 @@ of_address_to_resource(struct device_node *dn, int index,
return (0);
}
+static int
+get_interrupt_cells(const void *fdt, int node)
+{
+ do {
+ const fdt32_t *p;
+ int len;
+
+ p = fdt_getprop(fdt, node, "interrupt-parent", &len);
+ if (p != NULL) {
+ if (len != sizeof(*p))
+ return (-EINVAL);
+
+ node = fdt_node_offset_by_phandle(fdt,
+ fdt32_to_cpu(*p));
+ } else {
+ node = fdt_parent_offset(fdt, node);
+ }
+
+ p = fdt_getprop(fdt, node, "#interrupt-cells", &len);
+ if (p != NULL) {
+ if (len != sizeof(*p))
+ return (-EINVAL);
+
+ return ((int)fdt32_to_cpu(*p));
+ }
+ } while (node >= 0);
+
+ return (-EINVAL);
+}
+
int
of_irq_to_resource(struct device_node *dn, int index,
struct resource *res)
{
const void *fdt = bsp_fdt_get();
int len;
- const fdt32_t *p;
+ uint32_t spec_buf[8];
+ const fdt32_t *spec;
+ int node;
+ int ic;
int i;
+ int j;
+ int item_len;
int irq;
if (res != NULL)
memset(res, 0, sizeof(*res));
- p = fdt_getprop(fdt, dn->offset, "interrupts", &len);
- if (p == NULL)
+ node = dn->offset;
+
+ spec = fdt_getprop(fdt, node, "interrupts", &len);
+ if (spec == NULL)
return (-EINVAL);
- i = index * 16;
- if (i + 16 > len)
+ ic = get_interrupt_cells(fdt, node);
+ if (ic < 0 || ic >= RTEMS_ARRAY_SIZE(spec_buf))
+ return (EINVAL);
+
+ item_len = ic * 4;
+ i = index * item_len;
+ if (i + item_len > len)
return (-EINVAL);
- irq = (int)fdt32_to_cpu(p[i / sizeof(*p)]);
-#ifdef __PPC__
- /* FIXME */
- irq -= 16;
-#endif
+ for (j = 0; j < ic; ++j)
+ spec_buf[j] = fdt32_to_cpu(spec[i / sizeof(*spec)]);
+
+ irq = bsp_fdt_map_intr(spec_buf, (size_t)ic);
if (res != NULL) {
res->start = irq;
More information about the vc
mailing list