summary refs log tree commit diff
path: root/drivers/of/irq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-07 14:43:33 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-07 14:43:33 -0700
commit74fee4e88fd196c712abfdae89acfa272abf10f8 (patch)
tree942a2668830b36f5cf9bc9f2c77948f8b04c2742 /drivers/of/irq.c
parent7d955656121f547ff9a708ed7ee4c86a08bf628a (diff)
parent84024468cf1612783e6ab317da5b72fa41487ac6 (diff)
downloadlinux-74fee4e88fd196c712abfdae89acfa272abf10f8.tar.gz
Merge tag 'devicetree-for-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull DeviceTree updates from Rob Herring:
 "There's a few orphans in the conversion to %pOF printf specifiers
  included here that no one else picked up.

  Summary:

   - Convert more DT code to use of_property_read_* API.

   - Improve DT overlay support when adding multiple overlays

   - Convert printk's to %pOF format specifiers. Most went via subsystem
     trees, but picked up the remaining orphans

   - Correct unittests to use preferred "okay" for "status" property
     value

   - Add a KASLR seed property

   - Vendor prefixes for Mellanox, Theobroma System, Adaptrum, Moxa

   - Fix modalias buffer handling

   - Clean-up of include paths for building dtbs

   - Add bindings for amc6821, isl1208, tsl2x7x, srf02, and srf10
     devices

   - Add nvmem bindings for MediaTek MT7623 and MT7622 SoC

   - Add compatible string for Allwinner H5 Mali-450 GPU

   - Fix links to old OpenFirmware docs with new mirror on
     devicetree.org

   - Remove status property from binding doc examples"

* tag 'devicetree-for-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (45 commits)
  devicetree: Adjust status "ok" -> "okay" under drivers/of/
  dt-bindings: Remove "status" from examples
  dt-bindings: pinctrl: sh-pfc: Use generic node name
  dt-bindings: Add vendor Mellanox
  dt-binding: net/phy: fix interrupts description
  virt: Convert to using %pOF instead of full_name
  macintosh: Convert to using %pOF instead of full_name
  ide: pmac: Convert to using %pOF instead of full_name
  microblaze: Convert to using %pOF instead of full_name
  dt-bindings: usb: musb: Grammar s/the/to/, s/is/are/
  of: Use PLATFORM_DEVID_NONE definition
  of/device: Fix of_device_get_modalias() buffer handling
  of/device: Prevent buffer overflow in of_device_modalias()
  dt-bindings: add amc6821, isl1208 trivial bindings
  dt-bindings: add vendor prefix for Theobroma Systems
  of: search scripts/dtc/include-prefixes path for both CPP and DTC
  of: remove arch/$(SRCARCH)/boot/dts from include search path for CPP
  of: remove drivers/of/testcase-data from include search path for CPP
  of: return of_get_cpu_node from of_cpu_device_node_get if CPUs are not registered
  iio: srf08: add device tree binding for srf02 and srf10
  ...
Diffstat (limited to 'drivers/of/irq.c')
-rw-r--r--drivers/of/irq.c77
1 files changed, 31 insertions, 46 deletions
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index ab21c846eb27..ec00ae7384c2 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -59,20 +59,19 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
 struct device_node *of_irq_find_parent(struct device_node *child)
 {
 	struct device_node *p;
-	const __be32 *parp;
+	phandle parent;
 
 	if (!of_node_get(child))
 		return NULL;
 
 	do {
-		parp = of_get_property(child, "interrupt-parent", NULL);
-		if (parp == NULL)
+		if (of_property_read_u32(child, "interrupt-parent", &parent)) {
 			p = of_get_parent(child);
-		else {
+		} else	{
 			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
 				p = of_node_get(of_irq_dflt_pic);
 			else
-				p = of_find_node_by_phandle(be32_to_cpup(parp));
+				p = of_find_node_by_phandle(parent);
 		}
 		of_node_put(child);
 		child = p;
@@ -117,11 +116,8 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 	 * is none, we are nice and just walk up the tree
 	 */
 	do {
-		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
-		if (tmp != NULL) {
-			intsize = be32_to_cpu(*tmp);
+		if (!of_property_read_u32(ipar, "#interrupt-cells", &intsize))
 			break;
-		}
 		tnode = ipar;
 		ipar = of_irq_find_parent(ipar);
 		of_node_put(tnode);
@@ -131,7 +127,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 		goto fail;
 	}
 
-	pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
+	pr_debug("of_irq_parse_raw: ipar=%pOF, size=%d\n", ipar, intsize);
 
 	if (out_irq->args_count != intsize)
 		goto fail;
@@ -169,8 +165,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 		/* Now check if cursor is an interrupt-controller and if it is
 		 * then we are done
 		 */
-		if (of_get_property(ipar, "interrupt-controller", NULL) !=
-				NULL) {
+		if (of_property_read_bool(ipar, "interrupt-controller")) {
 			pr_debug(" -> got it !\n");
 			return 0;
 		}
@@ -229,14 +224,14 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 			/* Get #interrupt-cells and #address-cells of new
 			 * parent
 			 */
-			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
-			if (tmp == NULL) {
+			if (of_property_read_u32(newpar, "#interrupt-cells",
+						 &newintsize)) {
 				pr_debug(" -> parent lacks #interrupt-cells!\n");
 				goto fail;
 			}
-			newintsize = be32_to_cpu(*tmp);
-			tmp = of_get_property(newpar, "#address-cells", NULL);
-			newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp);
+			if (of_property_read_u32(newpar, "#address-cells",
+						 &newaddrsize))
+				newaddrsize = 0;
 
 			pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
 			    newintsize, newaddrsize);
@@ -269,7 +264,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 	skiplevel:
 		/* Iterate again with new parent */
 		out_irq->np = newpar;
-		pr_debug(" -> new parent: %s\n", of_node_full_name(newpar));
+		pr_debug(" -> new parent: %pOF\n", newpar);
 		of_node_put(ipar);
 		ipar = newpar;
 		newpar = NULL;
@@ -297,11 +292,11 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw);
 int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq)
 {
 	struct device_node *p;
-	const __be32 *intspec, *tmp, *addr;
-	u32 intsize, intlen;
+	const __be32 *addr;
+	u32 intsize;
 	int i, res;
 
-	pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index);
+	pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index);
 
 	/* OldWorld mac stuff is "special", handle out of line */
 	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
@@ -316,42 +311,32 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
 	if (!res)
 		return of_irq_parse_raw(addr, out_irq);
 
-	/* Get the interrupts property */
-	intspec = of_get_property(device, "interrupts", &intlen);
-	if (intspec == NULL)
-		return -EINVAL;
-
-	intlen /= sizeof(*intspec);
-
-	pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
-
 	/* Look for the interrupt parent. */
 	p = of_irq_find_parent(device);
 	if (p == NULL)
 		return -EINVAL;
 
 	/* Get size of interrupt specifier */
-	tmp = of_get_property(p, "#interrupt-cells", NULL);
-	if (tmp == NULL) {
+	if (of_property_read_u32(p, "#interrupt-cells", &intsize)) {
 		res = -EINVAL;
 		goto out;
 	}
-	intsize = be32_to_cpu(*tmp);
 
-	pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
-
-	/* Check index */
-	if ((index + 1) * intsize > intlen) {
-		res = -EINVAL;
-		goto out;
-	}
+	pr_debug(" parent=%pOF, intsize=%d\n", p, intsize);
 
 	/* Copy intspec into irq structure */
-	intspec += index * intsize;
 	out_irq->np = p;
 	out_irq->args_count = intsize;
-	for (i = 0; i < intsize; i++)
-		out_irq->args[i] = be32_to_cpup(intspec++);
+	for (i = 0; i < intsize; i++) {
+		res = of_property_read_u32_index(device, "interrupts",
+						 (index * intsize) + i,
+						 out_irq->args + i);
+		if (res)
+			goto out;
+	}
+
+	pr_debug(" intspec=%d\n", *out_irq->args);
+
 
 	/* Check if there are any interrupt-map translations to process */
 	res = of_irq_parse_raw(addr, out_irq);
@@ -508,7 +493,7 @@ void __init of_irq_init(const struct of_device_id *matches)
 	INIT_LIST_HEAD(&intc_parent_list);
 
 	for_each_matching_node_and_match(np, matches, &match) {
-		if (!of_find_property(np, "interrupt-controller", NULL) ||
+		if (!of_property_read_bool(np, "interrupt-controller") ||
 				!of_device_is_available(np))
 			continue;
 
@@ -555,8 +540,8 @@ void __init of_irq_init(const struct of_device_id *matches)
 
 			of_node_set_flag(desc->dev, OF_POPULATED);
 
-			pr_debug("of_irq_init: init %s (%p), parent %p\n",
-				 desc->dev->full_name,
+			pr_debug("of_irq_init: init %pOF (%p), parent %p\n",
+				 desc->dev,
 				 desc->dev, desc->interrupt_parent);
 			ret = desc->irq_init_cb(desc->dev,
 						desc->interrupt_parent);