aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/prom_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/prom_init.c')
-rw-r--r--arch/ppc64/kernel/prom_init.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index 35ec42de962e..3de950de3671 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -1566,7 +1566,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1566{ 1566{
1567 int l, align; 1567 int l, align;
1568 phandle child; 1568 phandle child;
1569 char *namep, *prev_name, *sstart; 1569 char *namep, *prev_name, *sstart, *p, *ep;
1570 unsigned long soff; 1570 unsigned long soff;
1571 unsigned char *valp; 1571 unsigned char *valp;
1572 unsigned long offset = reloc_offset(); 1572 unsigned long offset = reloc_offset();
@@ -1588,6 +1588,14 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1588 call_prom("package-to-path", 3, 1, node, namep, l); 1588 call_prom("package-to-path", 3, 1, node, namep, l);
1589 } 1589 }
1590 namep[l] = '\0'; 1590 namep[l] = '\0';
1591 /* Fixup an Apple bug where they have bogus \0 chars in the
1592 * middle of the path in some properties
1593 */
1594 for (p = namep, ep = namep + l; p < ep; p++)
1595 if (*p == '\0') {
1596 memmove(p, p+1, ep - p);
1597 ep--; l--;
1598 }
1591 *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4); 1599 *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4);
1592 } 1600 }
1593 1601
@@ -1750,7 +1758,44 @@ static void __init flatten_device_tree(void)
1750 prom_printf("Device tree struct 0x%x -> 0x%x\n", 1758 prom_printf("Device tree struct 0x%x -> 0x%x\n",
1751 RELOC(dt_struct_start), RELOC(dt_struct_end)); 1759 RELOC(dt_struct_start), RELOC(dt_struct_end));
1752 1760
1753 } 1761}
1762
1763
1764static void __init fixup_device_tree(void)
1765{
1766 unsigned long offset = reloc_offset();
1767 phandle u3, i2c, mpic;
1768 u32 u3_rev;
1769 u32 interrupts[2];
1770 u32 parent;
1771
1772 /* Some G5s have a missing interrupt definition, fix it up here */
1773 u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
1774 if ((long)u3 <= 0)
1775 return;
1776 i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
1777 if ((long)i2c <= 0)
1778 return;
1779 mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
1780 if ((long)mpic <= 0)
1781 return;
1782
1783 /* check if proper rev of u3 */
1784 if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0)
1785 return;
1786 if (u3_rev != 0x35)
1787 return;
1788 /* does it need fixup ? */
1789 if (prom_getproplen(i2c, "interrupts") > 0)
1790 return;
1791 /* interrupt on this revision of u3 is number 0 and level */
1792 interrupts[0] = 0;
1793 interrupts[1] = 1;
1794 prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
1795 parent = (u32)mpic;
1796 prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
1797}
1798
1754 1799
1755static void __init prom_find_boot_cpu(void) 1800static void __init prom_find_boot_cpu(void)
1756{ 1801{
@@ -1844,6 +1889,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
1844 &getprop_rval, sizeof(getprop_rval)); 1889 &getprop_rval, sizeof(getprop_rval));
1845 1890
1846 /* 1891 /*
1892 * On pSeries, inform the firmware about our capabilities
1893 */
1894 if (RELOC(of_platform) & PLATFORM_PSERIES)
1895 prom_send_capabilities();
1896
1897 /*
1847 * On pSeries, copy the CPU hold code 1898 * On pSeries, copy the CPU hold code
1848 */ 1899 */
1849 if (RELOC(of_platform) & PLATFORM_PSERIES) 1900 if (RELOC(of_platform) & PLATFORM_PSERIES)
@@ -1920,6 +1971,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
1920 } 1971 }
1921 1972
1922 /* 1973 /*
1974 * Fixup any known bugs in the device-tree
1975 */
1976 fixup_device_tree();
1977
1978 /*
1923 * Now finally create the flattened device-tree 1979 * Now finally create the flattened device-tree
1924 */ 1980 */
1925 prom_printf("copying OF device tree ...\n"); 1981 prom_printf("copying OF device tree ...\n");