Patchwork [U-Boot] board/freescale/common/cds_pci_ft.c: Fix rotate wrong cells in interrupt-map property

login
register
mail settings
Submitter Jiang Bin
Date Nov. 20, 2012, 8:31 a.m.
Message ID <1353400284-10531-1-git-send-email-bin.jiang@windriver.com>
Download mbox | patch
Permalink /patch/200326/
State Accepted, archived
Delegated to: Andy Fleming
Headers show

Comments

Jiang Bin - Nov. 20, 2012, 8:31 a.m.
For linux 3.x, the size of each item in interrupt-map property is 9 not 7.
Don't use the static value and calculate the size with following cells:
	PCI #address-cells, PCI #interrupt-cells,
	PIC address, PIC #address-cells, PIC #interrupt-cells.

Signed-off-by: Bin Jiang <bin.jiang@windriver.com>
---
 board/freescale/common/cds_pci_ft.c |   26 +++++++++++++++++++++++---
 1 files changed, 23 insertions(+), 3 deletions(-)

Patch

diff --git a/board/freescale/common/cds_pci_ft.c b/board/freescale/common/cds_pci_ft.c
index 8a09f99..32233db 100644
--- a/board/freescale/common/cds_pci_ft.c
+++ b/board/freescale/common/cds_pci_ft.c
@@ -31,7 +31,8 @@  static void cds_pci_fixup(void *blob)
 	int node;
 	const char *path;
 	int len, slot, i;
-	u32 *map = NULL;
+	u32 *map = NULL, *piccells = NULL;
+	int off, cells;
 
 	node = fdt_path_offset(blob, "/aliases");
 	if (node >= 0) {
@@ -41,6 +42,25 @@  static void cds_pci_fixup(void *blob)
 			if (node >= 0) {
 				map = fdt_getprop_w(blob, node, "interrupt-map", &len);
 			}
+			/* Each item in "interrupt-map" property is translated with
+			 * following cells:
+			 * PCI #address-cells, PCI #interrupt-cells,
+			 * PIC address, PIC #address-cells, PIC #interrupt-cells.
+			 */
+			cells = fdt_getprop_u32_default(blob, path, "#address-cells", 1);
+			cells += fdt_getprop_u32_default(blob, path, "#interrupt-cells", 1);
+			off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*(map+cells)));
+			if (off <= 0)
+				return;
+			cells += 1;
+			piccells = (u32 *)fdt_getprop(blob, off, "#address-cells", NULL);
+			if (piccells == NULL)
+				return;
+			cells += *piccells;
+			piccells = (u32 *)fdt_getprop(blob, off, "#interrupt-cells", NULL);
+			if (piccells == NULL)
+				return;
+			cells += *piccells;
 		}
 	}
 
@@ -49,12 +69,12 @@  static void cds_pci_fixup(void *blob)
 
 		slot = get_pci_slot();
 
-		for (i=0;i<len;i+=7) {
+		for (i=0;i<len;i+=cells) {
 			/* We rotate the interrupt pins so that the mapping
 			 * changes depending on the slot the carrier card is in.
 			 */
 			map[3] = ((map[3] + slot - 2) % 4) + 1;
-			map+=7;
+			map+=cells;
 		}
 	}
 }