aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc
diff options
context:
space:
mode:
authorLaurent Pinchart <laurentp@cse-semaphore.com>2008-04-10 17:03:04 +0200
committerKumar Gala <galak@kernel.crashing.org>2008-04-17 01:01:37 -0500
commitda0a5f0c65913e4ec0a70a5019ce0a7bcaab21c9 (patch)
tree6aab633690a25acaf46d61416cff6a808deaad8d /arch/powerpc
parentd464df2667cf181419604e656773f80996cf0470 (diff)
[POWERPC] Add bootwrapper function to get virtual reg from the device tree.
This patch adds a new generic device tree processing function that retrieves virtual reg addresses from the device tree to the bootwrapper code. It also updates the bootwrapper code to use the new function. dt_get_virtual_reg() retrieves the virtual reg addresses from the "virtual-reg" property. If the property can't be found, it uses the "reg" property and walks the tree to translate it to absolute addresses. Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com> Acked-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/boot/cpm-serial.c34
-rw-r--r--arch/powerpc/boot/devtree.c20
-rw-r--r--arch/powerpc/boot/mpc52xx-psc.c9
-rw-r--r--arch/powerpc/boot/ns16550.c10
-rw-r--r--arch/powerpc/boot/ops.h1
5 files changed, 31 insertions, 43 deletions
diff --git a/arch/powerpc/boot/cpm-serial.c b/arch/powerpc/boot/cpm-serial.c
index 28296facb2a..1f6225aad29 100644
--- a/arch/powerpc/boot/cpm-serial.c
+++ b/arch/powerpc/boot/cpm-serial.c
@@ -177,7 +177,6 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp)
{
void *reg_virt[2];
int is_smc = 0, is_cpm2 = 0, n;
- unsigned long reg_phys;
void *parent, *muram;
if (dt_is_compatible(devp, "fsl,cpm1-smc-uart")) {
@@ -206,15 +205,8 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp)
if (n < 4)
return -1;
- n = getprop(devp, "virtual-reg", reg_virt, sizeof(reg_virt));
- if (n < (int)sizeof(reg_virt)) {
- for (n = 0; n < 2; n++) {
- if (!dt_xlate_reg(devp, n, &reg_phys, NULL))
- return -1;
-
- reg_virt[n] = (void *)reg_phys;
- }
- }
+ if (dt_get_virtual_reg(devp, reg_virt, 2) < 2)
+ return -1;
if (is_smc)
smc = reg_virt[0];
@@ -227,15 +219,8 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp)
if (!parent)
return -1;
- n = getprop(parent, "virtual-reg", reg_virt, sizeof(reg_virt));
- if (n < (int)sizeof(reg_virt)) {
- if (!dt_xlate_reg(parent, 0, &reg_phys, NULL))
- return -1;
-
- reg_virt[0] = (void *)reg_phys;
- }
-
- cpcr = reg_virt[0];
+ if (dt_get_virtual_reg(parent, &cpcr, 1) < 1)
+ return -1;
muram = finddevice("/soc/cpm/muram/data");
if (!muram)
@@ -246,15 +231,8 @@ int cpm_console_init(void *devp, struct serial_console_data *scdp)
* is one for both parent and child.
*/
- n = getprop(muram, "virtual-reg", reg_virt, sizeof(reg_virt));
- if (n < (int)sizeof(reg_virt)) {
- if (!dt_xlate_reg(muram, 0, &reg_phys, NULL))
- return -1;
-
- reg_virt[0] = (void *)reg_phys;
- }
-
- muram_start = reg_virt[0];
+ if (dt_get_virtual_reg(muram, (void **)&muram_start, 1) < 1)
+ return -1;
n = getprop(muram, "reg", &muram_offset, 4);
if (n < 4)
diff --git a/arch/powerpc/boot/devtree.c b/arch/powerpc/boot/devtree.c
index 60f561e307a..5d12336dc36 100644
--- a/arch/powerpc/boot/devtree.c
+++ b/arch/powerpc/boot/devtree.c
@@ -350,3 +350,23 @@ int dt_is_compatible(void *node, const char *compat)
return 0;
}
+
+int dt_get_virtual_reg(void *node, void **addr, int nres)
+{
+ unsigned long xaddr;
+ int n;
+
+ n = getprop(node, "virtual-reg", addr, nres * 4);
+ if (n > 0)
+ return n / 4;
+
+ for (n = 0; n < nres; n++) {
+ if (!dt_xlate_reg(node, n, &xaddr, NULL))
+ break;
+
+ addr[n] = (void *)xaddr;
+ }
+
+ return n;
+}
+
diff --git a/arch/powerpc/boot/mpc52xx-psc.c b/arch/powerpc/boot/mpc52xx-psc.c
index 1074626e6a3..d4cb4e4e093 100644
--- a/arch/powerpc/boot/mpc52xx-psc.c
+++ b/arch/powerpc/boot/mpc52xx-psc.c
@@ -51,14 +51,9 @@ static unsigned char psc_getc(void)
int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp)
{
- int n;
-
/* Get the base address of the psc registers */
- n = getprop(devp, "virtual-reg", &psc, sizeof(psc));
- if (n != sizeof(psc)) {
- if (!dt_xlate_reg(devp, 0, (void *)&psc, NULL))
- return -1;
- }
+ if (dt_get_virtual_reg(devp, &psc, 1) < 1)
+ return -1;
scdp->open = psc_open;
scdp->putc = psc_putc;
diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c
index f8f1b2f3141..aef3bdc8916 100644
--- a/arch/powerpc/boot/ns16550.c
+++ b/arch/powerpc/boot/ns16550.c
@@ -55,15 +55,9 @@ static u8 ns16550_tstc(void)
int ns16550_console_init(void *devp, struct serial_console_data *scdp)
{
int n;
- unsigned long reg_phys;
- n = getprop(devp, "virtual-reg", &reg_base, sizeof(reg_base));
- if (n != sizeof(reg_base)) {
- if (!dt_xlate_reg(devp, 0, &reg_phys, NULL))
- return -1;
-
- reg_base = (void *)reg_phys;
- }
+ if (dt_get_virtual_reg(devp, (void **)&reg_base, 1) < 1)
+ return -1;
n = getprop(devp, "reg-shift", &reg_shift, sizeof(reg_shift));
if (n != sizeof(reg_shift))
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index 4b0544b03c6..321e2f5afe7 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -95,6 +95,7 @@ int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
int dt_is_compatible(void *node, const char *compat);
void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize);
+int dt_get_virtual_reg(void *node, void **addr, int nres);
static inline void *finddevice(const char *name)
{