From: Kumar Gala <galak@freescale.com>

Add the ability to identify an SOC by a name and id.  There are cases in
which the integer identifier is not sufficient to specify a specific SOC. 
In these cases we can use a string to further qualify the match.

Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 arch/ppc/syslib/ppc_sys.c |   52 +++++++++++++++++++++++++++++++++++++++++++++-
 include/asm-ppc/ppc_sys.h |    1 
 2 files changed, 52 insertions(+), 1 deletion(-)

diff -puN arch/ppc/syslib/ppc_sys.c~ppc32-ppc_sys-system-on-chip-identification-additions arch/ppc/syslib/ppc_sys.c
--- 25/arch/ppc/syslib/ppc_sys.c~ppc32-ppc_sys-system-on-chip-identification-additions	Mon Aug 29 16:03:58 2005
+++ 25-akpm/arch/ppc/syslib/ppc_sys.c	Mon Aug 29 16:03:58 2005
@@ -6,6 +6,7 @@
  * Maintainer: Kumar Gala <kumar.gala@freescale.com>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
+ * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -35,10 +36,59 @@ void __init identify_ppc_sys_by_id(u32 i
 
 void __init identify_ppc_sys_by_name(char *name)
 {
-	/* TODO */
+	unsigned int i = 0;
+	while (ppc_sys_specs[i].ppc_sys_name[0])
+	{
+		if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
+			break;
+		i++;
+	}
+	cur_ppc_sys_spec = &ppc_sys_specs[i];
 	return;
 }
 
+static int __init count_sys_specs(void)
+{
+	int i = 0;
+	while (ppc_sys_specs[i].ppc_sys_name[0])
+		i++;
+	return i;
+}
+
+static int __init find_chip_by_name_and_id(char *name, u32 id)
+{
+	int ret = -1;
+	unsigned int i = 0;
+	unsigned int j = 0;
+	unsigned int dups = 0;
+
+	unsigned char matched[count_sys_specs()];
+
+	while (ppc_sys_specs[i].ppc_sys_name[0]) {
+		if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
+			matched[j++] = i;
+		i++;
+	}
+	if (j != 0) {
+		for (i = 0; i < j; i++) {
+			if ((ppc_sys_specs[matched[i]].mask & id) ==
+			    ppc_sys_specs[matched[i]].value) {
+				ret = matched[i];
+				dups++;
+			}
+		}
+		ret = (dups == 1) ? ret : (-1 * dups);
+	}
+	return ret;
+}
+
+void __init identify_ppc_sys_by_name_and_id(char *name, u32 id)
+{
+	int i = find_chip_by_name_and_id(name, id);
+	BUG_ON(i < 0);
+	cur_ppc_sys_spec = &ppc_sys_specs[i];
+}
+
 /* Update all memory resources by paddr, call before platform_device_register */
 void __init
 ppc_sys_fixup_mem_resource(struct platform_device *pdev, phys_addr_t paddr)
diff -puN include/asm-ppc/ppc_sys.h~ppc32-ppc_sys-system-on-chip-identification-additions include/asm-ppc/ppc_sys.h
--- 25/include/asm-ppc/ppc_sys.h~ppc32-ppc_sys-system-on-chip-identification-additions	Mon Aug 29 16:03:58 2005
+++ 25-akpm/include/asm-ppc/ppc_sys.h	Mon Aug 29 16:03:58 2005
@@ -52,6 +52,7 @@ extern struct ppc_sys_spec *cur_ppc_sys_
 /* determine which specific SOC we are */
 extern void identify_ppc_sys_by_id(u32 id) __init;
 extern void identify_ppc_sys_by_name(char *name) __init;
+extern void identify_ppc_sys_by_name_and_id(char *name, u32 id) __init;
 
 /* describes all devices that may exist in a given family of processors */
 extern struct platform_device ppc_sys_platform_devices[];
_