Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Jan 2012 19:55:51 +0000 (UTC)
From:      Olivier Houchard <cognet@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r230315 - in projects/armv6/sys/dev: fdt uart
Message-ID:  <201201181955.q0IJtp9S054699@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cognet
Date: Wed Jan 18 19:55:51 2012
New Revision: 230315
URL: http://svn.freebsd.org/changeset/base/230315

Log:
  Add a function to get the PA from range, instead of (ab)using fdt_immr_pa,
  and use it for the UART driver
  
  Submitted by:	dmarion

Modified:
  projects/armv6/sys/dev/fdt/fdt_common.c
  projects/armv6/sys/dev/fdt/fdt_common.h
  projects/armv6/sys/dev/uart/uart_bus_fdt.c

Modified: projects/armv6/sys/dev/fdt/fdt_common.c
==============================================================================
--- projects/armv6/sys/dev/fdt/fdt_common.c	Wed Jan 18 19:54:32 2012	(r230314)
+++ projects/armv6/sys/dev/fdt/fdt_common.c	Wed Jan 18 19:55:51 2012	(r230315)
@@ -63,30 +63,12 @@ vm_offset_t fdt_immr_va;
 vm_offset_t fdt_immr_size;
 
 int
-fdt_immr_addr(vm_offset_t immr_va)
+fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size)
 {
 	pcell_t ranges[6], *rangesptr;
-	phandle_t node;
-	u_long base, size;
 	pcell_t addr_cells, size_cells, par_addr_cells;
 	int len, tuple_size, tuples;
 
-	/*
-	 * Try to access the SOC node directly i.e. through /aliases/.
-	 */
-	if ((node = OF_finddevice("soc")) != 0)
-		if (fdt_is_compatible_strict(node, "simple-bus"))
-			goto moveon;
-	/*
-	 * Find the node the long way.
-	 */
-	if ((node = OF_finddevice("/")) == 0)
-		return (ENXIO);
-
-	if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0)
-		return (ENXIO);
-
-moveon:
 	if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
 		return (ENXIO);
 	/*
@@ -100,6 +82,9 @@ moveon:
 	if (len > sizeof(ranges))
 		return (ENOMEM);
 
+	if (!(range_id < len))
+		return (ERANGE);
+
 	if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
 		return (EINVAL);
 
@@ -111,21 +96,48 @@ moveon:
 	    addr_cells, size_cells)) {
 		return (ERANGE);
 	}
-	base = 0;
-	size = 0;
-	rangesptr = &ranges[0];
+	*base = 0;
+	*size = 0;
+	rangesptr = &ranges[range_id];
 
-	base = fdt_data_get((void *)rangesptr, addr_cells);
+	*base = fdt_data_get((void *)rangesptr, addr_cells);
 	rangesptr += addr_cells;
-	base += fdt_data_get((void *)rangesptr, par_addr_cells);
+	*base += fdt_data_get((void *)rangesptr, par_addr_cells);
 	rangesptr += par_addr_cells;
-	size = fdt_data_get((void *)rangesptr, size_cells);
+	*size = fdt_data_get((void *)rangesptr, size_cells);
+	return (0);
+}
 
-	fdt_immr_pa = base;
-	fdt_immr_va = immr_va;
-	fdt_immr_size = size;
+int
+fdt_immr_addr(vm_offset_t immr_va)
+{
+	phandle_t node;
+	u_long base, size;
+	int r;
 
-	return (0);
+	/*
+	 * Try to access the SOC node directly i.e. through /aliases/.
+	 */
+	if ((node = OF_finddevice("soc")) != 0)
+		if (fdt_is_compatible_strict(node, "simple-bus"))
+			goto moveon;
+	/*
+	 * Find the node the long way.
+	 */
+	if ((node = OF_finddevice("/")) == 0)
+		return (ENXIO);
+
+	if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0)
+		return (ENXIO);
+
+moveon:
+	if ((r = fdt_get_range(node, 0, &base, &size)) == 0) {
+		fdt_immr_pa = base;
+		fdt_immr_va = immr_va;
+		fdt_immr_size = size;
+	}
+
+	return (r);
 }
 
 /*

Modified: projects/armv6/sys/dev/fdt/fdt_common.h
==============================================================================
--- projects/armv6/sys/dev/fdt/fdt_common.h	Wed Jan 18 19:54:32 2012	(r230314)
+++ projects/armv6/sys/dev/fdt/fdt_common.h	Wed Jan 18 19:55:51 2012	(r230315)
@@ -90,6 +90,7 @@ int fdt_data_verify(void *, int);
 phandle_t fdt_find_compatible(phandle_t, const char *, int);
 int fdt_get_mem_regions(struct mem_region *, int *, uint32_t *);
 int fdt_get_phyaddr(phandle_t node, int *);
+int fdt_get_range(phandle_t, int, u_long *, u_long *);
 int fdt_immr_addr(vm_offset_t);
 int fdt_regsize(phandle_t, u_long *, u_long *);
 int fdt_intr_decode(phandle_t, pcell_t *, int *, int *, int *);

Modified: projects/armv6/sys/dev/uart/uart_bus_fdt.c
==============================================================================
--- projects/armv6/sys/dev/uart/uart_bus_fdt.c	Wed Jan 18 19:54:32 2012	(r230314)
+++ projects/armv6/sys/dev/uart/uart_bus_fdt.c	Wed Jan 18 19:55:51 2012	(r230315)
@@ -137,7 +137,7 @@ uart_cpu_getdev(int devtype, struct uart
 	struct uart_class *class;
 	phandle_t node, chosen;
 	pcell_t shift, br, rclk;
-	u_long start, size;
+	u_long start, size, pbase, psize;
 	int err;
 
 	uart_bus_space_mem = fdtbus_bs_tag;
@@ -198,7 +198,9 @@ uart_cpu_getdev(int devtype, struct uart
 	err = fdt_regsize(node, &start, &size);
 	if (err)
 		return (ENXIO);
-	start += fdt_immr_pa;
+
+	fdt_get_range(OF_parent(node), 0, &pbase, &psize);
+	start += pbase;
 
 	return (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201181955.q0IJtp9S054699>