Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (36 commits)
[POWERPC] Generic BUG for powerpc
[PPC] Fix compile failure do to introduction of PHY_POLL
[POWERPC] Only export __mtdcr/__mfdcr if CONFIG_PPC_DCR is set
[POWERPC] Remove old dcr.S
[POWERPC] Fix SPU coredump code for max_fdset removal
[POWERPC] Fix irq routing on some 32-bit PowerMacs
[POWERPC] ps3: Add vuart support
[POWERPC] Support ibm,dynamic-reconfiguration-memory nodes
[POWERPC] dont allow pSeries_probe to succeed without initialising MMU
[POWERPC] micro optimise pSeries_probe
[POWERPC] Add SPURR SPR to sysfs
[POWERPC] Add DSCR SPR to sysfs
[POWERPC] Fix 440SPe CPU table entry
[POWERPC] Add support for FP emulation for the e300c2 core
[POWERPC] of_device_register: propagate device_create_file return code
[POWERPC] Fix mmap of PCI resource with hack for X
[POWERPC] iSeries: head_64.o needs to depend on lparmap.s
[POWERPC] cbe_thermal: Fix initialization of sysfs attribute_group
[POWERPC] Remove QE header files from lite5200.c
[POWERPC] of_platform_make_bus_id(): make `magic' int
...

+1884 -631
+7 -1
arch/powerpc/Kconfig
··· 107 107 bool 108 108 default y 109 109 110 + config GENERIC_BUG 111 + bool 112 + default y 113 + depends on BUG 114 + 110 115 config DEFAULT_UIMAGE 111 116 bool 112 117 help ··· 483 478 select PPC_UDBG_16550 484 479 select PPC_970_NAP 485 480 select PPC_NATIVE 481 + select PPC_RTAS 486 482 default n 487 483 help 488 484 This option enables support for the Maple 970FX Evaluation Board. ··· 720 714 721 715 config MATH_EMULATION 722 716 bool "Math emulation" 723 - depends on 4xx || 8xx || E200 || E500 717 + depends on 4xx || 8xx || E200 || PPC_83xx || E500 724 718 ---help--- 725 719 Some PowerPC chips designed for embedded applications do not have 726 720 a floating-point unit and therefore do not implement the
+1
arch/powerpc/configs/ps3_defconfig
··· 157 157 CONFIG_PS3_HTAB_SIZE=20 158 158 CONFIG_PS3_DYNAMIC_DMA=y 159 159 CONFIG_PS3_USE_LPAR_ADDR=y 160 + CONFIG_PS3_VUART=y 160 161 161 162 # 162 163 # Kernel options
+1
arch/powerpc/kernel/Makefile
··· 77 77 78 78 ifeq ($(CONFIG_PPC_ISERIES),y) 79 79 extra-y += lparmap.s 80 + $(obj)/head_64.o: $(obj)/lparmap.s 80 81 AFLAGS_head_64.o += -I$(obj) 81 82 endif 82 83
+2 -3
arch/powerpc/kernel/cputable.c
··· 833 833 .pvr_mask = 0x7fff0000, 834 834 .pvr_value = 0x00840000, 835 835 .cpu_name = "e300c2", 836 - .cpu_features = CPU_FTRS_E300, 836 + .cpu_features = CPU_FTRS_E300C2, 837 837 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 838 838 .icache_bsize = 32, 839 839 .dcache_bsize = 32, ··· 1136 1136 .pvr_mask = 0xff000fff, 1137 1137 .pvr_value = 0x53000890, 1138 1138 .cpu_name = "440SPe Rev. A", 1139 - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | 1140 - CPU_FTR_USE_TB, 1139 + .cpu_features = CPU_FTRS_44X, 1141 1140 .cpu_user_features = COMMON_USER_BOOKE, 1142 1141 .icache_bsize = 32, 1143 1142 .dcache_bsize = 32,
+7
arch/powerpc/kernel/head_32.S
··· 437 437 /* Floating-point unavailable */ 438 438 . = 0x800 439 439 FPUnavailable: 440 + BEGIN_FTR_SECTION 441 + /* 442 + * Certain Freescale cores don't have a FPU and treat fp instructions 443 + * as a FP Unavailable exception. Redirect to illegal/emulation handling. 444 + */ 445 + b ProgramCheck 446 + END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE) 440 447 EXCEPTION_PROLOG 441 448 bne load_up_fpu /* if from user, just load it up */ 442 449 addi r3,r1,STACK_FRAME_OVERHEAD
+6 -17
arch/powerpc/kernel/module_32.c
··· 23 23 #include <linux/string.h> 24 24 #include <linux/kernel.h> 25 25 #include <linux/cache.h> 26 + #include <linux/bug.h> 26 27 27 28 #include "setup.h" 28 29 ··· 291 290 struct module *me) 292 291 { 293 292 const Elf_Shdr *sect; 293 + int err; 294 294 295 - me->arch.bug_table = NULL; 296 - me->arch.num_bugs = 0; 297 - 298 - /* Find the __bug_table section, if present */ 299 - sect = find_section(hdr, sechdrs, "__bug_table"); 300 - if (sect != NULL) { 301 - me->arch.bug_table = (void *) sect->sh_addr; 302 - me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); 303 - } 304 - 305 - /* 306 - * Strictly speaking this should have a spinlock to protect against 307 - * traversals, but since we only traverse on BUG()s, a spinlock 308 - * could potentially lead to deadlock and thus be counter-productive. 309 - */ 310 - list_add(&me->arch.bug_list, &module_bug_list); 295 + err = module_bug_finalize(hdr, sechdrs, me); 296 + if (err) /* never true, currently */ 297 + return err; 311 298 312 299 /* Apply feature fixups */ 313 300 sect = find_section(hdr, sechdrs, "__ftr_fixup"); ··· 309 320 310 321 void module_arch_cleanup(struct module *mod) 311 322 { 312 - list_del(&mod->arch.bug_list); 323 + module_bug_cleanup(mod); 313 324 } 314 325 315 326 struct bug_entry *module_find_bug(unsigned long bugaddr)
+6 -17
arch/powerpc/kernel/module_64.c
··· 20 20 #include <linux/moduleloader.h> 21 21 #include <linux/err.h> 22 22 #include <linux/vmalloc.h> 23 + #include <linux/bug.h> 23 24 #include <asm/module.h> 24 25 #include <asm/uaccess.h> 25 26 #include <asm/firmware.h> ··· 440 439 const Elf_Shdr *sechdrs, struct module *me) 441 440 { 442 441 const Elf_Shdr *sect; 442 + int err; 443 443 444 - me->arch.bug_table = NULL; 445 - me->arch.num_bugs = 0; 446 - 447 - /* Find the __bug_table section, if present */ 448 - sect = find_section(hdr, sechdrs, "__bug_table"); 449 - if (sect != NULL) { 450 - me->arch.bug_table = (void *) sect->sh_addr; 451 - me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); 452 - } 453 - 454 - /* 455 - * Strictly speaking this should have a spinlock to protect against 456 - * traversals, but since we only traverse on BUG()s, a spinlock 457 - * could potentially lead to deadlock and thus be counter-productive. 458 - */ 459 - list_add(&me->arch.bug_list, &module_bug_list); 444 + err = module_bug_finalize(hdr, sechdrs, me); 445 + if (err) 446 + return err; 460 447 461 448 /* Apply feature fixups */ 462 449 sect = find_section(hdr, sechdrs, "__ftr_fixup"); ··· 464 475 465 476 void module_arch_cleanup(struct module *mod) 466 477 { 467 - list_del(&mod->arch.bug_list); 478 + module_bug_cleanup(mod); 468 479 } 469 480 470 481 struct bug_entry *module_find_bug(unsigned long bugaddr)
+1 -3
arch/powerpc/kernel/of_device.c
··· 109 109 if (rc) 110 110 return rc; 111 111 112 - device_create_file(&ofdev->dev, &dev_attr_devspec); 113 - 114 - return 0; 112 + return device_create_file(&ofdev->dev, &dev_attr_devspec); 115 113 } 116 114 117 115 void of_device_unregister(struct of_device *ofdev)
+1 -1
arch/powerpc/kernel/of_platform.c
··· 169 169 char *name = dev->dev.bus_id; 170 170 const u32 *reg; 171 171 u64 addr; 172 - long magic; 172 + int magic; 173 173 174 174 /* 175 175 * If it's a DCR based device, use 'd' for native DCRs
+85 -58
arch/powerpc/kernel/pci_32.c
··· 736 736 return NULL; 737 737 } 738 738 739 - static int 740 - scan_OF_pci_childs_iterator(struct device_node* node, void* data) 739 + static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, 740 + unsigned int devfn) 741 741 { 742 - const unsigned int *reg; 743 - u8* fdata = (u8*)data; 744 - 745 - reg = get_property(node, "reg", NULL); 746 - if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] 747 - && ((reg[0] >> 16) & 0xff) == fdata[0]) 748 - return 1; 749 - return 0; 742 + struct device_node *np = NULL; 743 + const u32 *reg; 744 + unsigned int psize; 745 + 746 + while ((np = of_get_next_child(parent, np)) != NULL) { 747 + reg = get_property(np, "reg", &psize); 748 + if (reg == NULL || psize < 4) 749 + continue; 750 + if (((reg[0] >> 8) & 0xff) == devfn) 751 + return np; 752 + } 753 + return NULL; 750 754 } 751 755 752 - static struct device_node* 753 - scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) 754 - { 755 - u8 filter_data[2] = {bus, dev_fn}; 756 756 757 - return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data); 757 + static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus) 758 + { 759 + struct device_node *parent, *np; 760 + 761 + /* Are we a root bus ? */ 762 + if (bus->self == NULL || bus->parent == NULL) { 763 + struct pci_controller *hose = pci_bus_to_hose(bus->number); 764 + if (hose == NULL) 765 + return NULL; 766 + return of_node_get(hose->arch_data); 767 + } 768 + 769 + /* not a root bus, we need to get our parent */ 770 + parent = scan_OF_for_pci_bus(bus->parent); 771 + if (parent == NULL) 772 + return NULL; 773 + 774 + /* now iterate for children for a match */ 775 + np = scan_OF_for_pci_dev(parent, bus->self->devfn); 776 + of_node_put(parent); 777 + 778 + /* sanity check */ 779 + if (strcmp(np->type, "pci") != 0) 780 + printk(KERN_WARNING "pci: wrong type \"%s\" for bridge %s\n", 781 + np->type, np->full_name); 782 + 783 + return np; 758 784 } 759 785 760 786 /* ··· 789 763 struct device_node * 790 764 pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) 791 765 { 792 - struct pci_controller *hose; 793 - struct device_node *node; 794 - int busnr; 766 + struct device_node *parent, *np; 795 767 796 768 if (!have_of) 797 769 return NULL; 798 - 799 - /* Lookup the hose */ 800 - busnr = bus->number; 801 - hose = pci_bus_to_hose(busnr); 802 - if (!hose) 803 - return NULL; 804 770 805 - /* Check it has an OF node associated */ 806 - node = (struct device_node *) hose->arch_data; 807 - if (!node) 771 + DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); 772 + parent = scan_OF_for_pci_bus(bus); 773 + if (parent == NULL) 808 774 return NULL; 775 + DBG(" parent is %s\n", parent ? parent->full_name : "<NULL>"); 776 + np = scan_OF_for_pci_dev(parent, devfn); 777 + of_node_put(parent); 778 + DBG(" result is %s\n", np ? np->full_name : "<NULL>"); 809 779 810 - /* Fixup bus number according to what OF think it is. */ 811 - #ifdef CONFIG_PPC_PMAC 812 - /* The G5 need a special case here. Basically, we don't remap all 813 - * busses on it so we don't create the pci-OF-map. However, we do 814 - * remap the AGP bus and so have to deal with it. A future better 815 - * fix has to be done by making the remapping per-host and always 816 - * filling the pci_to_OF map. --BenH 780 + /* XXX most callers don't release the returned node 781 + * mostly because ppc64 doesn't increase the refcount, 782 + * we need to fix that. 817 783 */ 818 - if (machine_is(powermac) && busnr >= 0xf0) 819 - busnr -= 0xf0; 820 - else 821 - #endif 822 - if (pci_to_OF_bus_map) 823 - busnr = pci_to_OF_bus_map[busnr]; 824 - if (busnr == 0xff) 825 - return NULL; 826 - 827 - /* Now, lookup childs of the hose */ 828 - return scan_OF_childs_for_device(node->child, busnr, devfn); 784 + return np; 829 785 } 830 786 EXPORT_SYMBOL(pci_busdev_to_OF_node); 831 787 ··· 1552 1544 1553 1545 1554 1546 static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, 1555 - unsigned long *offset, 1547 + resource_size_t *offset, 1556 1548 enum pci_mmap_state mmap_state) 1557 1549 { 1558 1550 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); ··· 1564 1556 1565 1557 /* If memory, add on the PCI bridge address offset */ 1566 1558 if (mmap_state == pci_mmap_mem) { 1559 + #if 0 /* See comment in pci_resource_to_user() for why this is disabled */ 1567 1560 *offset += hose->pci_mem_offset; 1561 + #endif 1568 1562 res_bit = IORESOURCE_MEM; 1569 1563 } else { 1570 1564 io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE; ··· 1633 1623 prot &= ~_PAGE_GUARDED; 1634 1624 else 1635 1625 prot |= _PAGE_GUARDED; 1636 - 1637 - printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), 1638 - (unsigned long long)rp->start, prot); 1639 1626 1640 1627 return __pgprot(prot); 1641 1628 } ··· 1702 1695 enum pci_mmap_state mmap_state, 1703 1696 int write_combine) 1704 1697 { 1705 - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 1698 + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; 1706 1699 struct resource *rp; 1707 1700 int ret; 1708 1701 ··· 1815 1808 resource_size_t *start, resource_size_t *end) 1816 1809 { 1817 1810 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); 1818 - unsigned long offset = 0; 1811 + resource_size_t offset = 0; 1819 1812 1820 1813 if (hose == NULL) 1821 1814 return; 1822 1815 1823 1816 if (rsrc->flags & IORESOURCE_IO) 1824 - offset = (void __iomem *)_IO_BASE - hose->io_base_virt 1825 - + hose->io_base_phys; 1817 + offset = (unsigned long)hose->io_base_virt - _IO_BASE; 1826 1818 1827 - *start = rsrc->start + offset; 1828 - *end = rsrc->end + offset; 1819 + /* We pass a fully fixed up address to userland for MMIO instead of 1820 + * a BAR value because X is lame and expects to be able to use that 1821 + * to pass to /dev/mem ! 1822 + * 1823 + * That means that we'll have potentially 64 bits values where some 1824 + * userland apps only expect 32 (like X itself since it thinks only 1825 + * Sparc has 64 bits MMIO) but if we don't do that, we break it on 1826 + * 32 bits CHRPs :-( 1827 + * 1828 + * Hopefully, the sysfs insterface is immune to that gunk. Once X 1829 + * has been fixed (and the fix spread enough), we can re-enable the 1830 + * 2 lines below and pass down a BAR value to userland. In that case 1831 + * we'll also have to re-enable the matching code in 1832 + * __pci_mmap_make_offset(). 1833 + * 1834 + * BenH. 1835 + */ 1836 + #if 0 1837 + else if (rsrc->flags & IORESOURCE_MEM) 1838 + offset = hose->pci_mem_offset; 1839 + #endif 1840 + 1841 + *start = rsrc->start - offset; 1842 + *end = rsrc->end - offset; 1829 1843 } 1830 1844 1831 - void __init 1832 - pci_init_resource(struct resource *res, unsigned long start, unsigned long end, 1833 - int flags, char *name) 1845 + void __init pci_init_resource(struct resource *res, resource_size_t start, 1846 + resource_size_t end, int flags, char *name) 1834 1847 { 1835 1848 res->start = start; 1836 1849 res->end = end;
+31 -11
arch/powerpc/kernel/pci_64.c
··· 682 682 * Returns negative error code on failure, zero on success. 683 683 */ 684 684 static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, 685 - unsigned long *offset, 685 + resource_size_t *offset, 686 686 enum pci_mmap_state mmap_state) 687 687 { 688 688 struct pci_controller *hose = pci_bus_to_host(dev->bus); ··· 694 694 695 695 /* If memory, add on the PCI bridge address offset */ 696 696 if (mmap_state == pci_mmap_mem) { 697 + #if 0 /* See comment in pci_resource_to_user() for why this is disabled */ 697 698 *offset += hose->pci_mem_offset; 699 + #endif 698 700 res_bit = IORESOURCE_MEM; 699 701 } else { 700 702 io_offset = (unsigned long)hose->io_base_virt - pci_io_base; ··· 763 761 prot &= ~_PAGE_GUARDED; 764 762 else 765 763 prot |= _PAGE_GUARDED; 766 - 767 - printk(KERN_DEBUG "PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, 768 - prot); 769 764 770 765 return __pgprot(prot); 771 766 } ··· 831 832 int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, 832 833 enum pci_mmap_state mmap_state, int write_combine) 833 834 { 834 - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 835 + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; 835 836 struct resource *rp; 836 837 int ret; 837 838 ··· 1332 1333 1333 1334 void pci_resource_to_user(const struct pci_dev *dev, int bar, 1334 1335 const struct resource *rsrc, 1335 - u64 *start, u64 *end) 1336 + resource_size_t *start, resource_size_t *end) 1336 1337 { 1337 1338 struct pci_controller *hose = pci_bus_to_host(dev->bus); 1338 - unsigned long offset = 0; 1339 + resource_size_t offset = 0; 1339 1340 1340 1341 if (hose == NULL) 1341 1342 return; 1342 1343 1343 1344 if (rsrc->flags & IORESOURCE_IO) 1344 - offset = pci_io_base - (unsigned long)hose->io_base_virt + 1345 - hose->io_base_phys; 1345 + offset = (unsigned long)hose->io_base_virt - pci_io_base; 1346 1346 1347 - *start = rsrc->start + offset; 1348 - *end = rsrc->end + offset; 1347 + /* We pass a fully fixed up address to userland for MMIO instead of 1348 + * a BAR value because X is lame and expects to be able to use that 1349 + * to pass to /dev/mem ! 1350 + * 1351 + * That means that we'll have potentially 64 bits values where some 1352 + * userland apps only expect 32 (like X itself since it thinks only 1353 + * Sparc has 64 bits MMIO) but if we don't do that, we break it on 1354 + * 32 bits CHRPs :-( 1355 + * 1356 + * Hopefully, the sysfs insterface is immune to that gunk. Once X 1357 + * has been fixed (and the fix spread enough), we can re-enable the 1358 + * 2 lines below and pass down a BAR value to userland. In that case 1359 + * we'll also have to re-enable the matching code in 1360 + * __pci_mmap_make_offset(). 1361 + * 1362 + * BenH. 1363 + */ 1364 + #if 0 1365 + else if (rsrc->flags & IORESOURCE_MEM) 1366 + offset = hose->pci_mem_offset; 1367 + #endif 1368 + 1369 + *start = rsrc->start - offset; 1370 + *end = rsrc->end - offset; 1349 1371 } 1350 1372 1351 1373 struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
+1 -1
arch/powerpc/kernel/ppc_ksyms.c
··· 208 208 extern long *intercept_table; 209 209 EXPORT_SYMBOL(intercept_table); 210 210 #endif /* CONFIG_PPC_STD_MMU_32 */ 211 - #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) 211 + #ifdef CONFIG_PPC_DCR_NATIVE 212 212 EXPORT_SYMBOL(__mtdcr); 213 213 EXPORT_SYMBOL(__mfdcr); 214 214 #endif
+55
arch/powerpc/kernel/prom.c
··· 804 804 return of_read_ulong(p, s); 805 805 } 806 806 807 + #ifdef CONFIG_PPC_PSERIES 808 + /* 809 + * Interpret the ibm,dynamic-memory property in the 810 + * /ibm,dynamic-reconfiguration-memory node. 811 + * This contains a list of memory blocks along with NUMA affinity 812 + * information. 813 + */ 814 + static int __init early_init_dt_scan_drconf_memory(unsigned long node) 815 + { 816 + cell_t *dm, *ls; 817 + unsigned long l, n; 818 + unsigned long base, size, lmb_size, flags; 819 + 820 + ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l); 821 + if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t)) 822 + return 0; 823 + lmb_size = dt_mem_next_cell(dt_root_size_cells, &ls); 824 + 825 + dm = (cell_t *)of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l); 826 + if (dm == NULL || l < sizeof(cell_t)) 827 + return 0; 828 + 829 + n = *dm++; /* number of entries */ 830 + if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t)) 831 + return 0; 832 + 833 + for (; n != 0; --n) { 834 + base = dt_mem_next_cell(dt_root_addr_cells, &dm); 835 + flags = dm[3]; 836 + /* skip DRC index, pad, assoc. list index, flags */ 837 + dm += 4; 838 + /* skip this block if the reserved bit is set in flags (0x80) 839 + or if the block is not assigned to this partition (0x8) */ 840 + if ((flags & 0x80) || !(flags & 0x8)) 841 + continue; 842 + size = lmb_size; 843 + if (iommu_is_off) { 844 + if (base >= 0x80000000ul) 845 + continue; 846 + if ((base + size) > 0x80000000ul) 847 + size = 0x80000000ul - base; 848 + } 849 + lmb_add(base, size); 850 + } 851 + lmb_dump_all(); 852 + return 0; 853 + } 854 + #else 855 + #define early_init_dt_scan_drconf_memory(node) 0 856 + #endif /* CONFIG_PPC_PSERIES */ 807 857 808 858 static int __init early_init_dt_scan_memory(unsigned long node, 809 859 const char *uname, int depth, void *data) ··· 861 811 char *type = of_get_flat_dt_prop(node, "device_type", NULL); 862 812 cell_t *reg, *endp; 863 813 unsigned long l; 814 + 815 + /* Look for the ibm,dynamic-reconfiguration-memory node */ 816 + if (depth == 1 && 817 + strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) 818 + return early_init_dt_scan_drconf_memory(node); 864 819 865 820 /* We are scanning "memory" nodes only */ 866 821 if (type == NULL) {
+1 -1
arch/powerpc/kernel/prom_init.c
··· 679 679 /* option vector 5: PAPR/OF options */ 680 680 3 - 2, /* length */ 681 681 0, /* don't ignore, don't halt */ 682 - OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES, 682 + OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY, 683 683 }; 684 684 685 685 /* Old method - ELF header with PT_NOTE sections */
+6 -29
arch/powerpc/kernel/rtas.c
··· 303 303 } 304 304 EXPORT_SYMBOL(rtas_token); 305 305 306 + int rtas_service_present(const char *service) 307 + { 308 + return rtas_token(service) != RTAS_UNKNOWN_SERVICE; 309 + } 310 + EXPORT_SYMBOL(rtas_service_present); 311 + 306 312 #ifdef CONFIG_RTAS_ERROR_LOGGING 307 313 /* 308 314 * Return the firmware-specified size of the error log buffer ··· 816 810 return 0; 817 811 } 818 812 819 - #ifdef CONFIG_HOTPLUG_CPU 820 - /* This version can't take the spinlock, because it never returns */ 821 - static struct rtas_args rtas_stop_self_args = { 822 - /* The token is initialized for real in setup_system() */ 823 - .token = RTAS_UNKNOWN_SERVICE, 824 - .nargs = 0, 825 - .nret = 1, 826 - .rets = &rtas_stop_self_args.args[0], 827 - }; 828 - 829 - void rtas_stop_self(void) 830 - { 831 - struct rtas_args *rtas_args = &rtas_stop_self_args; 832 - 833 - local_irq_disable(); 834 - 835 - BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE); 836 - 837 - printk("cpu %u (hwid %u) Ready to die...\n", 838 - smp_processor_id(), hard_smp_processor_id()); 839 - enter_rtas(__pa(rtas_args)); 840 - 841 - panic("Alas, I survived.\n"); 842 - } 843 - #endif 844 - 845 813 /* 846 814 * Call early during boot, before mem init or bootmem, to retrieve the RTAS 847 815 * informations from the device-tree and allocate the RMO buffer for userland ··· 860 880 #endif 861 881 rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); 862 882 863 - #ifdef CONFIG_HOTPLUG_CPU 864 - rtas_stop_self_args.token = rtas_token("stop-self"); 865 - #endif /* CONFIG_HOTPLUG_CPU */ 866 883 #ifdef CONFIG_RTAS_ERROR_LOGGING 867 884 rtas_last_error_token = rtas_token("rtas-last-error"); 868 885 #endif
+16
arch/powerpc/kernel/sysfs.c
··· 181 181 SYSFS_PMCSETUP(pmc7, SPRN_PMC7); 182 182 SYSFS_PMCSETUP(pmc8, SPRN_PMC8); 183 183 SYSFS_PMCSETUP(purr, SPRN_PURR); 184 + SYSFS_PMCSETUP(spurr, SPRN_SPURR); 185 + SYSFS_PMCSETUP(dscr, SPRN_DSCR); 184 186 185 187 static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); 186 188 static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1); ··· 196 194 static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7); 197 195 static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8); 198 196 static SYSDEV_ATTR(purr, 0600, show_purr, NULL); 197 + static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); 198 + static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); 199 199 200 200 static void register_cpu_online(unsigned int cpu) 201 201 { ··· 235 231 236 232 if (cpu_has_feature(CPU_FTR_PURR)) 237 233 sysdev_create_file(s, &attr_purr); 234 + 235 + if (cpu_has_feature(CPU_FTR_SPURR)) 236 + sysdev_create_file(s, &attr_spurr); 237 + 238 + if (cpu_has_feature(CPU_FTR_DSCR)) 239 + sysdev_create_file(s, &attr_dscr); 238 240 } 239 241 240 242 #ifdef CONFIG_HOTPLUG_CPU ··· 282 272 283 273 if (cpu_has_feature(CPU_FTR_PURR)) 284 274 sysdev_remove_file(s, &attr_purr); 275 + 276 + if (cpu_has_feature(CPU_FTR_SPURR)) 277 + sysdev_remove_file(s, &attr_spurr); 278 + 279 + if (cpu_has_feature(CPU_FTR_DSCR)) 280 + sysdev_remove_file(s, &attr_dscr); 285 281 } 286 282 #endif /* CONFIG_HOTPLUG_CPU */ 287 283
+8 -48
arch/powerpc/kernel/traps.c
··· 32 32 #include <linux/kprobes.h> 33 33 #include <linux/kexec.h> 34 34 #include <linux/backlight.h> 35 + #include <linux/bug.h> 35 36 36 37 #include <asm/kdebug.h> 37 38 #include <asm/pgtable.h> ··· 728 727 return -EINVAL; 729 728 } 730 729 731 - /* 732 - * Look through the list of trap instructions that are used for BUG(), 733 - * BUG_ON() and WARN_ON() and see if we hit one. At this point we know 734 - * that the exception was caused by a trap instruction of some kind. 735 - * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0 736 - * otherwise. 737 - */ 738 - extern struct bug_entry __start___bug_table[], __stop___bug_table[]; 739 - 740 - #ifndef CONFIG_MODULES 741 - #define module_find_bug(x) NULL 742 - #endif 743 - 744 - struct bug_entry *find_bug(unsigned long bugaddr) 730 + int is_valid_bugaddr(unsigned long addr) 745 731 { 746 - struct bug_entry *bug; 747 - 748 - for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) 749 - if (bugaddr == bug->bug_addr) 750 - return bug; 751 - return module_find_bug(bugaddr); 752 - } 753 - 754 - static int check_bug_trap(struct pt_regs *regs) 755 - { 756 - struct bug_entry *bug; 757 - unsigned long addr; 758 - 759 - if (regs->msr & MSR_PR) 760 - return 0; /* not in kernel */ 761 - addr = regs->nip; /* address of trap instruction */ 762 - if (addr < PAGE_OFFSET) 763 - return 0; 764 - bug = find_bug(regs->nip); 765 - if (bug == NULL) 766 - return 0; 767 - if (bug->line & BUG_WARNING_TRAP) { 768 - /* this is a WARN_ON rather than BUG/BUG_ON */ 769 - printk(KERN_ERR "Badness in %s at %s:%ld\n", 770 - bug->function, bug->file, 771 - bug->line & ~BUG_WARNING_TRAP); 772 - dump_stack(); 773 - return 1; 774 - } 775 - printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", 776 - bug->function, bug->file, bug->line); 777 - 778 - return 0; 732 + return is_kernel_addr(addr); 779 733 } 780 734 781 735 void __kprobes program_check_exception(struct pt_regs *regs) ··· 738 782 unsigned int reason = get_reason(regs); 739 783 extern int do_mathemu(struct pt_regs *regs); 740 784 785 + /* We can now get here via a FP Unavailable exception if the core 786 + * has no FPU, in that case no reason flags will be set */ 741 787 #ifdef CONFIG_MATH_EMULATION 742 788 /* (reason & REASON_ILLEGAL) would be the obvious thing here, 743 789 * but there seems to be a hardware bug on the 405GP (RevD) ··· 766 808 return; 767 809 if (debugger_bpt(regs)) 768 810 return; 769 - if (check_bug_trap(regs)) { 811 + 812 + if (!(regs->msr & MSR_PR) && /* not user-mode */ 813 + report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) { 770 814 regs->nip += 4; 771 815 return; 772 816 }
+1 -5
arch/powerpc/kernel/vmlinux.lds.S
··· 62 62 __stop___ex_table = .; 63 63 } 64 64 65 - __bug_table : { 66 - __start___bug_table = .; 67 - *(__bug_table) 68 - __stop___bug_table = .; 69 - } 65 + BUG_TABLE 70 66 71 67 /* 72 68 * Init sections discarded at runtime
+65
arch/powerpc/mm/numa.c
··· 295 295 return lmb_end_of_DRAM() - start; 296 296 } 297 297 298 + /* 299 + * Extract NUMA information from the ibm,dynamic-reconfiguration-memory 300 + * node. This assumes n_mem_{addr,size}_cells have been set. 301 + */ 302 + static void __init parse_drconf_memory(struct device_node *memory) 303 + { 304 + const unsigned int *lm, *dm, *aa; 305 + unsigned int ls, ld, la; 306 + unsigned int n, aam, aalen; 307 + unsigned long lmb_size, size; 308 + int nid, default_nid = 0; 309 + unsigned int start, ai, flags; 310 + 311 + lm = get_property(memory, "ibm,lmb-size", &ls); 312 + dm = get_property(memory, "ibm,dynamic-memory", &ld); 313 + aa = get_property(memory, "ibm,associativity-lookup-arrays", &la); 314 + if (!lm || !dm || !aa || 315 + ls < sizeof(unsigned int) || ld < sizeof(unsigned int) || 316 + la < 2 * sizeof(unsigned int)) 317 + return; 318 + 319 + lmb_size = read_n_cells(n_mem_size_cells, &lm); 320 + n = *dm++; /* number of LMBs */ 321 + aam = *aa++; /* number of associativity lists */ 322 + aalen = *aa++; /* length of each associativity list */ 323 + if (ld < (n * (n_mem_addr_cells + 4) + 1) * sizeof(unsigned int) || 324 + la < (aam * aalen + 2) * sizeof(unsigned int)) 325 + return; 326 + 327 + for (; n != 0; --n) { 328 + start = read_n_cells(n_mem_addr_cells, &dm); 329 + ai = dm[2]; 330 + flags = dm[3]; 331 + dm += 4; 332 + /* 0x80 == reserved, 0x8 = assigned to us */ 333 + if ((flags & 0x80) || !(flags & 0x8)) 334 + continue; 335 + nid = default_nid; 336 + /* flags & 0x40 means associativity index is invalid */ 337 + if (min_common_depth > 0 && min_common_depth <= aalen && 338 + (flags & 0x40) == 0 && ai < aam) { 339 + /* this is like of_node_to_nid_single */ 340 + nid = aa[ai * aalen + min_common_depth - 1]; 341 + if (nid == 0xffff || nid >= MAX_NUMNODES) 342 + nid = default_nid; 343 + } 344 + node_set_online(nid); 345 + 346 + size = numa_enforce_memory_limit(start, lmb_size); 347 + if (!size) 348 + continue; 349 + 350 + add_active_range(nid, start >> PAGE_SHIFT, 351 + (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); 352 + } 353 + } 354 + 298 355 static int __init parse_numa_properties(void) 299 356 { 300 357 struct device_node *cpu = NULL; ··· 441 384 if (--ranges) 442 385 goto new_range; 443 386 } 387 + 388 + /* 389 + * Now do the same thing for each LMB listed in the ibm,dynamic-memory 390 + * property in the ibm,dynamic-reconfiguration-memory node. 391 + */ 392 + memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); 393 + if (memory) 394 + parse_drconf_memory(memory); 444 395 445 396 return 0; 446 397 }
-2
arch/powerpc/platforms/52xx/lite5200.c
··· 40 40 #include <asm/prom.h> 41 41 #include <asm/udbg.h> 42 42 #include <sysdev/fsl_soc.h> 43 - #include <asm/qe.h> 44 - #include <asm/qe_ic.h> 45 43 #include <asm/of_platform.h> 46 44 47 45 #include <asm/mpc52xx.h>
+2
arch/powerpc/platforms/cell/cbe_thermal.c
··· 115 115 116 116 static struct attribute *spu_attributes[] = { 117 117 &attr_spu_temperature.attr, 118 + NULL, 118 119 }; 119 120 120 121 static struct attribute_group spu_attribute_group = { ··· 136 135 static struct attribute *ppe_attributes[] = { 137 136 &attr_ppe_temperature0.attr, 138 137 &attr_ppe_temperature1.attr, 138 + NULL, 139 139 }; 140 140 141 141 static struct attribute_group ppe_attribute_group = {
+4 -1
arch/powerpc/platforms/cell/pmu.c
··· 382 382 return IRQ_HANDLED; 383 383 } 384 384 385 - int __init cbe_init_pm_irq(void) 385 + static int __init cbe_init_pm_irq(void) 386 386 { 387 387 unsigned int irq; 388 388 int rc, node; 389 + 390 + if (!machine_is(cell)) 391 + return 0; 389 392 390 393 for_each_node(node) { 391 394 irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI |
+1 -1
arch/powerpc/platforms/cell/spufs/coredump.c
··· 147 147 struct fdtable *fdt = files_fdtable(current->files); 148 148 int size = 0, fd; 149 149 150 - for (fd = 0; fd < fdt->max_fdset && fd < fdt->max_fds; fd++) { 150 + for (fd = 0; fd < fdt->max_fds; fd++) { 151 151 if (FD_ISSET(fd, fdt->open_fds)) { 152 152 struct file *file = fcheck(fd); 153 153
+1 -1
arch/powerpc/platforms/maple/pci.c
··· 562 562 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { 563 563 if (np->name == NULL) 564 564 continue; 565 - if (strcmp(np->name, "pci") == 0) { 565 + if (!strcmp(np->name, "pci") || !strcmp(np->name, "pcie")) { 566 566 if (add_bridge(np) == 0) 567 567 of_node_get(np); 568 568 }
+12
arch/powerpc/platforms/maple/setup.c
··· 60 60 #include <asm/of_device.h> 61 61 #include <asm/lmb.h> 62 62 #include <asm/mpic.h> 63 + #include <asm/rtas.h> 63 64 #include <asm/udbg.h> 64 65 65 66 #include "maple.h" ··· 167 166 }; 168 167 #endif /* CONFIG_SMP */ 169 168 169 + static void __init maple_use_rtas_reboot_and_halt_if_present(void) 170 + { 171 + if (rtas_service_present("system-reboot") && 172 + rtas_service_present("power-off")) { 173 + ppc_md.restart = rtas_restart; 174 + ppc_md.power_off = rtas_power_off; 175 + ppc_md.halt = rtas_halt; 176 + } 177 + } 178 + 170 179 void __init maple_setup_arch(void) 171 180 { 172 181 /* init to some ~sane value until calibrate_delay() runs */ ··· 192 181 #ifdef CONFIG_DUMMY_CONSOLE 193 182 conswitchp = &dummy_con; 194 183 #endif 184 + maple_use_rtas_reboot_and_halt_if_present(); 195 185 196 186 printk(KERN_DEBUG "Using native/NAP idle loop\n"); 197 187 }
+11
arch/powerpc/platforms/ps3/Kconfig
··· 40 40 41 41 If you have any doubt, choose the default y. 42 42 43 + config PS3_VUART 44 + depends on PPC_PS3 45 + bool "PS3 Virtual UART support" 46 + default y 47 + help 48 + Include support for the PS3 Virtual UART. 49 + 50 + This support is required for several system services 51 + including the System Manager and AV Settings. In 52 + general, all users will say Y. 53 + 43 54 endmenu
+2
arch/powerpc/platforms/pseries/Makefile
··· 10 10 obj-$(CONFIG_SCANLOG) += scanlog.o 11 11 obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o 12 12 13 + obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o 14 + 13 15 obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o 14 16 obj-$(CONFIG_HVCS) += hvcserver.o 15 17 obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
+1
arch/powerpc/platforms/pseries/eeh.c
··· 337 337 printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n", 338 338 pdn->eeh_check_count); 339 339 dump_stack(); 340 + msleep(5000); 340 341 341 342 /* re-read the slot reset state */ 342 343 if (read_slot_reset_state(pdn, rets) != 0)
+10 -3
arch/powerpc/platforms/pseries/eeh_driver.c
··· 170 170 static void eeh_report_resume(struct pci_dev *dev, void *userdata) 171 171 { 172 172 struct pci_driver *driver = dev->driver; 173 + struct device_node *dn = pci_device_to_OF_node(dev); 173 174 174 175 dev->error_state = pci_channel_io_normal; 175 176 176 177 if (!driver) 177 178 return; 178 - if (!driver->err_handler) 179 - return; 180 - if (!driver->err_handler->resume) 179 + 180 + if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) { 181 + PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; 182 + enable_irq(dev->irq); 183 + } 184 + if (!driver->err_handler || 185 + !driver->err_handler->resume) 181 186 return; 182 187 183 188 driver->err_handler->resume(dev); ··· 412 407 413 408 if (rc) 414 409 result = PCI_ERS_RESULT_NEED_RESET; 410 + else 411 + result = PCI_ERS_RESULT_RECOVERED; 415 412 } 416 413 417 414 /* If any device has a hard failure, then shut off everything. */
+275
arch/powerpc/platforms/pseries/hotplug-cpu.c
··· 1 + /* 2 + * pseries CPU Hotplug infrastructure. 3 + * 4 + * Split out from arch/powerpc/platforms/pseries/setup.c 5 + * arch/powerpc/kernel/rtas.c, and arch/powerpc/platforms/pseries/smp.c 6 + * 7 + * Peter Bergner, IBM March 2001. 8 + * Copyright (C) 2001 IBM. 9 + * Dave Engebretsen, Peter Bergner, and 10 + * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com 11 + * Plus various changes from other IBM teams... 12 + * 13 + * Copyright (C) 2006 Michael Ellerman, IBM Corporation 14 + * 15 + * This program is free software; you can redistribute it and/or 16 + * modify it under the terms of the GNU General Public License 17 + * as published by the Free Software Foundation; either version 18 + * 2 of the License, or (at your option) any later version. 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/delay.h> 23 + #include <linux/cpu.h> 24 + #include <asm/system.h> 25 + #include <asm/prom.h> 26 + #include <asm/rtas.h> 27 + #include <asm/firmware.h> 28 + #include <asm/machdep.h> 29 + #include <asm/vdso_datapage.h> 30 + #include <asm/pSeries_reconfig.h> 31 + #include "xics.h" 32 + 33 + /* This version can't take the spinlock, because it never returns */ 34 + static struct rtas_args rtas_stop_self_args = { 35 + .token = RTAS_UNKNOWN_SERVICE, 36 + .nargs = 0, 37 + .nret = 1, 38 + .rets = &rtas_stop_self_args.args[0], 39 + }; 40 + 41 + static void rtas_stop_self(void) 42 + { 43 + struct rtas_args *args = &rtas_stop_self_args; 44 + 45 + local_irq_disable(); 46 + 47 + BUG_ON(args->token == RTAS_UNKNOWN_SERVICE); 48 + 49 + printk("cpu %u (hwid %u) Ready to die...\n", 50 + smp_processor_id(), hard_smp_processor_id()); 51 + enter_rtas(__pa(args)); 52 + 53 + panic("Alas, I survived.\n"); 54 + } 55 + 56 + static void pseries_mach_cpu_die(void) 57 + { 58 + local_irq_disable(); 59 + idle_task_exit(); 60 + xics_teardown_cpu(0); 61 + rtas_stop_self(); 62 + /* Should never get here... */ 63 + BUG(); 64 + for(;;); 65 + } 66 + 67 + static int qcss_tok; /* query-cpu-stopped-state token */ 68 + 69 + /* Get state of physical CPU. 70 + * Return codes: 71 + * 0 - The processor is in the RTAS stopped state 72 + * 1 - stop-self is in progress 73 + * 2 - The processor is not in the RTAS stopped state 74 + * -1 - Hardware Error 75 + * -2 - Hardware Busy, Try again later. 76 + */ 77 + static int query_cpu_stopped(unsigned int pcpu) 78 + { 79 + int cpu_status, status; 80 + 81 + status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); 82 + if (status != 0) { 83 + printk(KERN_ERR 84 + "RTAS query-cpu-stopped-state failed: %i\n", status); 85 + return status; 86 + } 87 + 88 + return cpu_status; 89 + } 90 + 91 + static int pseries_cpu_disable(void) 92 + { 93 + int cpu = smp_processor_id(); 94 + 95 + cpu_clear(cpu, cpu_online_map); 96 + vdso_data->processorCount--; 97 + 98 + /*fix boot_cpuid here*/ 99 + if (cpu == boot_cpuid) 100 + boot_cpuid = any_online_cpu(cpu_online_map); 101 + 102 + /* FIXME: abstract this to not be platform specific later on */ 103 + xics_migrate_irqs_away(); 104 + return 0; 105 + } 106 + 107 + static void pseries_cpu_die(unsigned int cpu) 108 + { 109 + int tries; 110 + int cpu_status; 111 + unsigned int pcpu = get_hard_smp_processor_id(cpu); 112 + 113 + for (tries = 0; tries < 25; tries++) { 114 + cpu_status = query_cpu_stopped(pcpu); 115 + if (cpu_status == 0 || cpu_status == -1) 116 + break; 117 + msleep(200); 118 + } 119 + if (cpu_status != 0) { 120 + printk("Querying DEAD? cpu %i (%i) shows %i\n", 121 + cpu, pcpu, cpu_status); 122 + } 123 + 124 + /* Isolation and deallocation are definatly done by 125 + * drslot_chrp_cpu. If they were not they would be 126 + * done here. Change isolate state to Isolate and 127 + * change allocation-state to Unusable. 128 + */ 129 + paca[cpu].cpu_start = 0; 130 + } 131 + 132 + /* 133 + * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle 134 + * here is that a cpu device node may represent up to two logical cpus 135 + * in the SMT case. We must honor the assumption in other code that 136 + * the logical ids for sibling SMT threads x and y are adjacent, such 137 + * that x^1 == y and y^1 == x. 138 + */ 139 + static int pseries_add_processor(struct device_node *np) 140 + { 141 + unsigned int cpu; 142 + cpumask_t candidate_map, tmp = CPU_MASK_NONE; 143 + int err = -ENOSPC, len, nthreads, i; 144 + const u32 *intserv; 145 + 146 + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); 147 + if (!intserv) 148 + return 0; 149 + 150 + nthreads = len / sizeof(u32); 151 + for (i = 0; i < nthreads; i++) 152 + cpu_set(i, tmp); 153 + 154 + lock_cpu_hotplug(); 155 + 156 + BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); 157 + 158 + /* Get a bitmap of unoccupied slots. */ 159 + cpus_xor(candidate_map, cpu_possible_map, cpu_present_map); 160 + if (cpus_empty(candidate_map)) { 161 + /* If we get here, it most likely means that NR_CPUS is 162 + * less than the partition's max processors setting. 163 + */ 164 + printk(KERN_ERR "Cannot add cpu %s; this system configuration" 165 + " supports %d logical cpus.\n", np->full_name, 166 + cpus_weight(cpu_possible_map)); 167 + goto out_unlock; 168 + } 169 + 170 + while (!cpus_empty(tmp)) 171 + if (cpus_subset(tmp, candidate_map)) 172 + /* Found a range where we can insert the new cpu(s) */ 173 + break; 174 + else 175 + cpus_shift_left(tmp, tmp, nthreads); 176 + 177 + if (cpus_empty(tmp)) { 178 + printk(KERN_ERR "Unable to find space in cpu_present_map for" 179 + " processor %s with %d thread(s)\n", np->name, 180 + nthreads); 181 + goto out_unlock; 182 + } 183 + 184 + for_each_cpu_mask(cpu, tmp) { 185 + BUG_ON(cpu_isset(cpu, cpu_present_map)); 186 + cpu_set(cpu, cpu_present_map); 187 + set_hard_smp_processor_id(cpu, *intserv++); 188 + } 189 + err = 0; 190 + out_unlock: 191 + unlock_cpu_hotplug(); 192 + return err; 193 + } 194 + 195 + /* 196 + * Update the present map for a cpu node which is going away, and set 197 + * the hard id in the paca(s) to -1 to be consistent with boot time 198 + * convention for non-present cpus. 199 + */ 200 + static void pseries_remove_processor(struct device_node *np) 201 + { 202 + unsigned int cpu; 203 + int len, nthreads, i; 204 + const u32 *intserv; 205 + 206 + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); 207 + if (!intserv) 208 + return; 209 + 210 + nthreads = len / sizeof(u32); 211 + 212 + lock_cpu_hotplug(); 213 + for (i = 0; i < nthreads; i++) { 214 + for_each_present_cpu(cpu) { 215 + if (get_hard_smp_processor_id(cpu) != intserv[i]) 216 + continue; 217 + BUG_ON(cpu_online(cpu)); 218 + cpu_clear(cpu, cpu_present_map); 219 + set_hard_smp_processor_id(cpu, -1); 220 + break; 221 + } 222 + if (cpu == NR_CPUS) 223 + printk(KERN_WARNING "Could not find cpu to remove " 224 + "with physical id 0x%x\n", intserv[i]); 225 + } 226 + unlock_cpu_hotplug(); 227 + } 228 + 229 + static int pseries_smp_notifier(struct notifier_block *nb, 230 + unsigned long action, void *node) 231 + { 232 + int err = NOTIFY_OK; 233 + 234 + switch (action) { 235 + case PSERIES_RECONFIG_ADD: 236 + if (pseries_add_processor(node)) 237 + err = NOTIFY_BAD; 238 + break; 239 + case PSERIES_RECONFIG_REMOVE: 240 + pseries_remove_processor(node); 241 + break; 242 + default: 243 + err = NOTIFY_DONE; 244 + break; 245 + } 246 + return err; 247 + } 248 + 249 + static struct notifier_block pseries_smp_nb = { 250 + .notifier_call = pseries_smp_notifier, 251 + }; 252 + 253 + static int __init pseries_cpu_hotplug_init(void) 254 + { 255 + rtas_stop_self_args.token = rtas_token("stop-self"); 256 + qcss_tok = rtas_token("query-cpu-stopped-state"); 257 + 258 + if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE || 259 + qcss_tok == RTAS_UNKNOWN_SERVICE) { 260 + printk(KERN_INFO "CPU Hotplug not supported by firmware " 261 + "- disabling.\n"); 262 + return 0; 263 + } 264 + 265 + ppc_md.cpu_die = pseries_mach_cpu_die; 266 + smp_ops->cpu_disable = pseries_cpu_disable; 267 + smp_ops->cpu_die = pseries_cpu_die; 268 + 269 + /* Processors can be added/removed only on LPAR */ 270 + if (firmware_has_feature(FW_FEATURE_LPAR)) 271 + pSeries_reconfig_notifier_register(&pseries_smp_nb); 272 + 273 + return 0; 274 + } 275 + arch_initcall(pseries_cpu_hotplug_init);
+7 -23
arch/powerpc/platforms/pseries/setup.c
··· 347 347 } 348 348 arch_initcall(pSeries_init_panel); 349 349 350 - #ifdef CONFIG_HOTPLUG_CPU 351 - static void pSeries_mach_cpu_die(void) 352 - { 353 - local_irq_disable(); 354 - idle_task_exit(); 355 - xics_teardown_cpu(0); 356 - rtas_stop_self(); 357 - /* Should never get here... */ 358 - BUG(); 359 - for(;;); 360 - } 361 - #else 362 - #define pSeries_mach_cpu_die NULL 363 - #endif 364 - 365 350 static int pseries_set_dabr(unsigned long dabr) 366 351 { 367 352 return plpar_hcall_norets(H_SET_DABR, dabr); ··· 422 437 if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) 423 438 powerpc_firmware_features |= FW_FEATURE_LPAR; 424 439 425 - if (firmware_has_feature(FW_FEATURE_LPAR)) 426 - hpte_init_lpar(); 427 - else 428 - hpte_init_native(); 429 - 430 440 return 1; 431 441 } 432 442 433 443 static int __init pSeries_probe(void) 434 444 { 435 445 unsigned long root = of_get_flat_dt_root(); 436 - char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), 437 - "device_type", NULL); 446 + char *dtype = of_get_flat_dt_prop(root, "device_type", NULL); 447 + 438 448 if (dtype == NULL) 439 449 return 0; 440 450 if (strcmp(dtype, "chrp")) ··· 446 466 447 467 /* Now try to figure out if we are running on LPAR */ 448 468 of_scan_flat_dt(pSeries_probe_hypertas, NULL); 469 + 470 + if (firmware_has_feature(FW_FEATURE_LPAR)) 471 + hpte_init_lpar(); 472 + else 473 + hpte_init_native(); 449 474 450 475 DBG("Machine is%s LPAR !\n", 451 476 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); ··· 546 561 .power_off = rtas_power_off, 547 562 .halt = rtas_halt, 548 563 .panic = rtas_os_term, 549 - .cpu_die = pSeries_mach_cpu_die, 550 564 .get_boot_time = rtas_get_boot_time, 551 565 .get_rtc_time = rtas_get_rtc_time, 552 566 .set_rtc_time = rtas_set_rtc_time,
-200
arch/powerpc/platforms/pseries/smp.c
··· 64 64 65 65 extern void generic_secondary_smp_init(unsigned long); 66 66 67 - #ifdef CONFIG_HOTPLUG_CPU 68 - 69 - /* Get state of physical CPU. 70 - * Return codes: 71 - * 0 - The processor is in the RTAS stopped state 72 - * 1 - stop-self is in progress 73 - * 2 - The processor is not in the RTAS stopped state 74 - * -1 - Hardware Error 75 - * -2 - Hardware Busy, Try again later. 76 - */ 77 - static int query_cpu_stopped(unsigned int pcpu) 78 - { 79 - int cpu_status; 80 - int status, qcss_tok; 81 - 82 - qcss_tok = rtas_token("query-cpu-stopped-state"); 83 - if (qcss_tok == RTAS_UNKNOWN_SERVICE) 84 - return -1; 85 - status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); 86 - if (status != 0) { 87 - printk(KERN_ERR 88 - "RTAS query-cpu-stopped-state failed: %i\n", status); 89 - return status; 90 - } 91 - 92 - return cpu_status; 93 - } 94 - 95 - static int pSeries_cpu_disable(void) 96 - { 97 - int cpu = smp_processor_id(); 98 - 99 - cpu_clear(cpu, cpu_online_map); 100 - vdso_data->processorCount--; 101 - 102 - /*fix boot_cpuid here*/ 103 - if (cpu == boot_cpuid) 104 - boot_cpuid = any_online_cpu(cpu_online_map); 105 - 106 - /* FIXME: abstract this to not be platform specific later on */ 107 - xics_migrate_irqs_away(); 108 - return 0; 109 - } 110 - 111 - static void pSeries_cpu_die(unsigned int cpu) 112 - { 113 - int tries; 114 - int cpu_status; 115 - unsigned int pcpu = get_hard_smp_processor_id(cpu); 116 - 117 - for (tries = 0; tries < 25; tries++) { 118 - cpu_status = query_cpu_stopped(pcpu); 119 - if (cpu_status == 0 || cpu_status == -1) 120 - break; 121 - msleep(200); 122 - } 123 - if (cpu_status != 0) { 124 - printk("Querying DEAD? cpu %i (%i) shows %i\n", 125 - cpu, pcpu, cpu_status); 126 - } 127 - 128 - /* Isolation and deallocation are definatly done by 129 - * drslot_chrp_cpu. If they were not they would be 130 - * done here. Change isolate state to Isolate and 131 - * change allocation-state to Unusable. 132 - */ 133 - paca[cpu].cpu_start = 0; 134 - } 135 - 136 - /* 137 - * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle 138 - * here is that a cpu device node may represent up to two logical cpus 139 - * in the SMT case. We must honor the assumption in other code that 140 - * the logical ids for sibling SMT threads x and y are adjacent, such 141 - * that x^1 == y and y^1 == x. 142 - */ 143 - static int pSeries_add_processor(struct device_node *np) 144 - { 145 - unsigned int cpu; 146 - cpumask_t candidate_map, tmp = CPU_MASK_NONE; 147 - int err = -ENOSPC, len, nthreads, i; 148 - const u32 *intserv; 149 - 150 - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); 151 - if (!intserv) 152 - return 0; 153 - 154 - nthreads = len / sizeof(u32); 155 - for (i = 0; i < nthreads; i++) 156 - cpu_set(i, tmp); 157 - 158 - lock_cpu_hotplug(); 159 - 160 - BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); 161 - 162 - /* Get a bitmap of unoccupied slots. */ 163 - cpus_xor(candidate_map, cpu_possible_map, cpu_present_map); 164 - if (cpus_empty(candidate_map)) { 165 - /* If we get here, it most likely means that NR_CPUS is 166 - * less than the partition's max processors setting. 167 - */ 168 - printk(KERN_ERR "Cannot add cpu %s; this system configuration" 169 - " supports %d logical cpus.\n", np->full_name, 170 - cpus_weight(cpu_possible_map)); 171 - goto out_unlock; 172 - } 173 - 174 - while (!cpus_empty(tmp)) 175 - if (cpus_subset(tmp, candidate_map)) 176 - /* Found a range where we can insert the new cpu(s) */ 177 - break; 178 - else 179 - cpus_shift_left(tmp, tmp, nthreads); 180 - 181 - if (cpus_empty(tmp)) { 182 - printk(KERN_ERR "Unable to find space in cpu_present_map for" 183 - " processor %s with %d thread(s)\n", np->name, 184 - nthreads); 185 - goto out_unlock; 186 - } 187 - 188 - for_each_cpu_mask(cpu, tmp) { 189 - BUG_ON(cpu_isset(cpu, cpu_present_map)); 190 - cpu_set(cpu, cpu_present_map); 191 - set_hard_smp_processor_id(cpu, *intserv++); 192 - } 193 - err = 0; 194 - out_unlock: 195 - unlock_cpu_hotplug(); 196 - return err; 197 - } 198 - 199 - /* 200 - * Update the present map for a cpu node which is going away, and set 201 - * the hard id in the paca(s) to -1 to be consistent with boot time 202 - * convention for non-present cpus. 203 - */ 204 - static void pSeries_remove_processor(struct device_node *np) 205 - { 206 - unsigned int cpu; 207 - int len, nthreads, i; 208 - const u32 *intserv; 209 - 210 - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); 211 - if (!intserv) 212 - return; 213 - 214 - nthreads = len / sizeof(u32); 215 - 216 - lock_cpu_hotplug(); 217 - for (i = 0; i < nthreads; i++) { 218 - for_each_present_cpu(cpu) { 219 - if (get_hard_smp_processor_id(cpu) != intserv[i]) 220 - continue; 221 - BUG_ON(cpu_online(cpu)); 222 - cpu_clear(cpu, cpu_present_map); 223 - set_hard_smp_processor_id(cpu, -1); 224 - break; 225 - } 226 - if (cpu == NR_CPUS) 227 - printk(KERN_WARNING "Could not find cpu to remove " 228 - "with physical id 0x%x\n", intserv[i]); 229 - } 230 - unlock_cpu_hotplug(); 231 - } 232 - 233 - static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node) 234 - { 235 - int err = NOTIFY_OK; 236 - 237 - switch (action) { 238 - case PSERIES_RECONFIG_ADD: 239 - if (pSeries_add_processor(node)) 240 - err = NOTIFY_BAD; 241 - break; 242 - case PSERIES_RECONFIG_REMOVE: 243 - pSeries_remove_processor(node); 244 - break; 245 - default: 246 - err = NOTIFY_DONE; 247 - break; 248 - } 249 - return err; 250 - } 251 - 252 - static struct notifier_block pSeries_smp_nb = { 253 - .notifier_call = pSeries_smp_notifier, 254 - }; 255 - 256 - #endif /* CONFIG_HOTPLUG_CPU */ 257 - 258 67 /** 259 68 * smp_startup_cpu() - start the given cpu 260 69 * ··· 230 421 int i; 231 422 232 423 DBG(" -> smp_init_pSeries()\n"); 233 - 234 - #ifdef CONFIG_HOTPLUG_CPU 235 - smp_ops->cpu_disable = pSeries_cpu_disable; 236 - smp_ops->cpu_die = pSeries_cpu_die; 237 - 238 - /* Processors can be added/removed only on LPAR */ 239 - if (firmware_has_feature(FW_FEATURE_LPAR)) 240 - pSeries_reconfig_notifier_register(&pSeries_smp_nb); 241 - #endif 242 424 243 425 /* Mark threads which are still spinning in hold loops. */ 244 426 if (cpu_has_feature(CPU_FTR_SMT)) {
+2 -1
arch/powerpc/sysdev/Makefile
··· 5 5 obj-$(CONFIG_MPIC) += mpic.o 6 6 obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o 7 7 obj-$(CONFIG_PPC_MPC106) += grackle.o 8 - obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o 8 + obj-$(CONFIG_PPC_DCR) += dcr.o 9 + obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o 9 10 obj-$(CONFIG_U3_DART) += dart_iommu.o 10 11 obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o 11 12 obj-$(CONFIG_FSL_SOC) += fsl_soc.o
-39
arch/powerpc/sysdev/dcr.S
··· 1 - /* 2 - * "Indirect" DCR access 3 - * 4 - * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net> 5 - * 6 - * This program is free software; you can redistribute it and/or modify it 7 - * under the terms of the GNU General Public License as published by the 8 - * Free Software Foundation; either version 2 of the License, or (at your 9 - * option) any later version. 10 - */ 11 - 12 - #include <asm/ppc_asm.h> 13 - #include <asm/processor.h> 14 - 15 - #define DCR_ACCESS_PROLOG(table) \ 16 - rlwinm r3,r3,4,18,27; \ 17 - lis r5,table@h; \ 18 - ori r5,r5,table@l; \ 19 - add r3,r3,r5; \ 20 - mtctr r3; \ 21 - bctr 22 - 23 - _GLOBAL(__mfdcr) 24 - DCR_ACCESS_PROLOG(__mfdcr_table) 25 - 26 - _GLOBAL(__mtdcr) 27 - DCR_ACCESS_PROLOG(__mtdcr_table) 28 - 29 - __mfdcr_table: 30 - mfdcr r3,0; blr 31 - __mtdcr_table: 32 - mtdcr 0,r4; blr 33 - 34 - dcr = 1 35 - .rept 1023 36 - mfdcr r3,dcr; blr 37 - mtdcr dcr,r4; blr 38 - dcr = dcr + 1 39 - .endr
+10 -30
arch/powerpc/sysdev/qe_lib/qe_ic.c
··· 223 223 qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, 224 224 temp & ~qe_ic_info[src].mask); 225 225 226 - spin_unlock_irqrestore(&qe_ic_lock, flags); 227 - } 228 - 229 - static void qe_ic_mask_irq_and_ack(unsigned int virq) 230 - { 231 - struct qe_ic *qe_ic = qe_ic_from_irq(virq); 232 - unsigned int src = virq_to_hw(virq); 233 - unsigned long flags; 234 - u32 temp; 235 - 236 - spin_lock_irqsave(&qe_ic_lock, flags); 237 - 238 - temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg); 239 - qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, 240 - temp & ~qe_ic_info[src].mask); 241 - 242 - /* There is nothing to do for ack here, ack is handled in ISR */ 226 + /* Flush the above write before enabling interrupts; otherwise, 227 + * spurious interrupts will sometimes happen. To be 100% sure 228 + * that the write has reached the device before interrupts are 229 + * enabled, the mask register would have to be read back; however, 230 + * this is not required for correctness, only to avoid wasting 231 + * time on a large number of spurious interrupts. In testing, 232 + * a sync reduced the observed spurious interrupts to zero. 233 + */ 234 + mb(); 243 235 244 236 spin_unlock_irqrestore(&qe_ic_lock, flags); 245 237 } ··· 240 248 .typename = " QEIC ", 241 249 .unmask = qe_ic_unmask_irq, 242 250 .mask = qe_ic_mask_irq, 243 - .mask_ack = qe_ic_mask_irq_and_ack, 251 + .mask_ack = qe_ic_mask_irq, 244 252 }; 245 253 246 254 static int qe_ic_host_match(struct irq_host *h, struct device_node *node) ··· 323 331 return irq_linear_revmap(qe_ic->irqhost, irq); 324 332 } 325 333 326 - /* FIXME: We mask all the QE Low interrupts while handling. We should 327 - * let other interrupt come in, but BAD interrupts are generated */ 328 334 void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc) 329 335 { 330 336 struct qe_ic *qe_ic = desc->handler_data; 331 - struct irq_chip *chip = irq_desc[irq].chip; 332 - 333 337 unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); 334 338 335 - chip->mask_ack(irq); 336 339 if (cascade_irq != NO_IRQ) 337 340 generic_handle_irq(cascade_irq); 338 - chip->unmask(irq); 339 341 } 340 342 341 - /* FIXME: We mask all the QE High interrupts while handling. We should 342 - * let other interrupt come in, but BAD interrupts are generated */ 343 343 void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc) 344 344 { 345 345 struct qe_ic *qe_ic = desc->handler_data; 346 - struct irq_chip *chip = irq_desc[irq].chip; 347 - 348 346 unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); 349 347 350 - chip->mask_ack(irq); 351 348 if (cascade_irq != NO_IRQ) 352 349 generic_handle_irq(cascade_irq); 353 - chip->unmask(irq); 354 350 } 355 351 356 352 void __init qe_ic_init(struct device_node *node, unsigned int flags)
+1
arch/powerpc/sysdev/rom.c
··· 9 9 10 10 #include <linux/kernel.h> 11 11 #include <asm/of_device.h> 12 + #include <asm/of_platform.h> 12 13 13 14 static int __init powerpc_flash_init(void) 14 15 {
+5 -5
arch/powerpc/xmon/xmon.c
··· 22 22 #include <linux/sysrq.h> 23 23 #include <linux/interrupt.h> 24 24 #include <linux/irq.h> 25 + #include <linux/bug.h> 25 26 26 27 #include <asm/ptrace.h> 27 28 #include <asm/string.h> ··· 36 35 #include <asm/cputable.h> 37 36 #include <asm/rtas.h> 38 37 #include <asm/sstep.h> 39 - #include <asm/bug.h> 40 38 #include <asm/irq_regs.h> 41 39 #include <asm/spu.h> 42 40 #include <asm/spu_priv1.h> ··· 1346 1346 1347 1347 static void print_bug_trap(struct pt_regs *regs) 1348 1348 { 1349 - struct bug_entry *bug; 1349 + const struct bug_entry *bug; 1350 1350 unsigned long addr; 1351 1351 1352 1352 if (regs->msr & MSR_PR) ··· 1357 1357 bug = find_bug(regs->nip); 1358 1358 if (bug == NULL) 1359 1359 return; 1360 - if (bug->line & BUG_WARNING_TRAP) 1360 + if (is_warning_bug(bug)) 1361 1361 return; 1362 1362 1363 - printf("kernel BUG in %s at %s:%d!\n", 1364 - bug->function, bug->file, (unsigned int)bug->line); 1363 + printf("kernel BUG at %s:%u!\n", 1364 + bug->file, bug->line); 1365 1365 } 1366 1366 1367 1367 void excprint(struct pt_regs *fp)
+32 -9
arch/ppc/kernel/pci.c
··· 879 879 880 880 881 881 static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, 882 - unsigned long *offset, 882 + resource_size_t *offset, 883 883 enum pci_mmap_state mmap_state) 884 884 { 885 885 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); ··· 891 891 892 892 /* If memory, add on the PCI bridge address offset */ 893 893 if (mmap_state == pci_mmap_mem) { 894 + #if 0 /* See comment in pci_resource_to_user() for why this is disabled */ 894 895 *offset += hose->pci_mem_offset; 896 + #endif 895 897 res_bit = IORESOURCE_MEM; 896 898 } else { 897 899 io_offset = hose->io_base_virt - ___IO_BASE; ··· 1032 1030 enum pci_mmap_state mmap_state, 1033 1031 int write_combine) 1034 1032 { 1035 - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 1033 + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; 1036 1034 struct resource *rp; 1037 1035 int ret; 1038 1036 ··· 1134 1132 resource_size_t *start, resource_size_t *end) 1135 1133 { 1136 1134 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); 1137 - unsigned long offset = 0; 1135 + resource_size_t offset = 0; 1138 1136 1139 1137 if (hose == NULL) 1140 1138 return; 1141 1139 1142 1140 if (rsrc->flags & IORESOURCE_IO) 1143 - offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; 1141 + offset = (unsigned long)hose->io_base_virt - _IO_BASE; 1144 1142 1145 - *start = rsrc->start + offset; 1146 - *end = rsrc->end + offset; 1143 + /* We pass a fully fixed up address to userland for MMIO instead of 1144 + * a BAR value because X is lame and expects to be able to use that 1145 + * to pass to /dev/mem ! 1146 + * 1147 + * That means that we'll have potentially 64 bits values where some 1148 + * userland apps only expect 32 (like X itself since it thinks only 1149 + * Sparc has 64 bits MMIO) but if we don't do that, we break it on 1150 + * 32 bits CHRPs :-( 1151 + * 1152 + * Hopefully, the sysfs insterface is immune to that gunk. Once X 1153 + * has been fixed (and the fix spread enough), we can re-enable the 1154 + * 2 lines below and pass down a BAR value to userland. In that case 1155 + * we'll also have to re-enable the matching code in 1156 + * __pci_mmap_make_offset(). 1157 + * 1158 + * BenH. 1159 + */ 1160 + #if 0 1161 + else if (rsrc->flags & IORESOURCE_MEM) 1162 + offset = hose->pci_mem_offset; 1163 + #endif 1164 + 1165 + *start = rsrc->start - offset; 1166 + *end = rsrc->end - offset; 1147 1167 } 1148 1168 1149 - void __init 1150 - pci_init_resource(struct resource *res, unsigned long start, unsigned long end, 1151 - int flags, char *name) 1169 + void __init pci_init_resource(struct resource *res, resource_size_t start, 1170 + resource_size_t end, int flags, char *name) 1152 1171 { 1153 1172 res->start = start; 1154 1173 res->end = end;
+1
drivers/ps3/Makefile
··· 1 1 obj-y += system-bus.o 2 + obj-$(CONFIG_PS3_VUART) += vuart.o
+965
drivers/ps3/vuart.c
··· 1 + /* 2 + * PS3 virtual uart 3 + * 4 + * Copyright (C) 2006 Sony Computer Entertainment Inc. 5 + * Copyright 2006 Sony Corp. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; version 2 of the License. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/module.h> 23 + #include <linux/interrupt.h> 24 + #include <asm/ps3.h> 25 + 26 + #include <asm/lv1call.h> 27 + #include <asm/bitops.h> 28 + 29 + #include "vuart.h" 30 + 31 + MODULE_AUTHOR("Sony Corporation"); 32 + MODULE_LICENSE("GPL v2"); 33 + MODULE_DESCRIPTION("ps3 vuart"); 34 + 35 + /** 36 + * vuart - An inter-partition data link service. 37 + * port 0: PS3 AV Settings. 38 + * port 2: PS3 System Manager. 39 + * 40 + * The vuart provides a bi-directional byte stream data link between logical 41 + * partitions. Its primary role is as a communications link between the guest 42 + * OS and the system policy module. The current HV does not support any 43 + * connections other than those listed. 44 + */ 45 + 46 + enum {PORT_COUNT = 3,}; 47 + 48 + enum vuart_param { 49 + PARAM_TX_TRIGGER = 0, 50 + PARAM_RX_TRIGGER = 1, 51 + PARAM_INTERRUPT_MASK = 2, 52 + PARAM_RX_BUF_SIZE = 3, /* read only */ 53 + PARAM_RX_BYTES = 4, /* read only */ 54 + PARAM_TX_BUF_SIZE = 5, /* read only */ 55 + PARAM_TX_BYTES = 6, /* read only */ 56 + PARAM_INTERRUPT_STATUS = 7, /* read only */ 57 + }; 58 + 59 + enum vuart_interrupt_bit { 60 + INTERRUPT_BIT_TX = 0, 61 + INTERRUPT_BIT_RX = 1, 62 + INTERRUPT_BIT_DISCONNECT = 2, 63 + }; 64 + 65 + enum vuart_interrupt_mask { 66 + INTERRUPT_MASK_TX = 1, 67 + INTERRUPT_MASK_RX = 2, 68 + INTERRUPT_MASK_DISCONNECT = 4, 69 + }; 70 + 71 + /** 72 + * struct ports_bmp - bitmap indicating ports needing service. 73 + * 74 + * A 256 bit read only bitmap indicating ports needing service. Do not write 75 + * to these bits. Must not cross a page boundary. 76 + */ 77 + 78 + struct ports_bmp { 79 + u64 status; 80 + u64 unused[3]; 81 + } __attribute__ ((aligned (32))); 82 + 83 + /* redefine dev_dbg to do a syntax check */ 84 + 85 + #if !defined(DEBUG) 86 + #undef dev_dbg 87 + static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( 88 + const struct device *_dev, const char *fmt, ...) {return 0;} 89 + #endif 90 + 91 + #define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__) 92 + static void __attribute__ ((unused)) _dump_ports_bmp( 93 + const struct ports_bmp* bmp, const char* func, int line) 94 + { 95 + pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); 96 + } 97 + 98 + static int ps3_vuart_match_id_to_port(enum ps3_match_id match_id, 99 + unsigned int *port_number) 100 + { 101 + switch(match_id) { 102 + case PS3_MATCH_ID_AV_SETTINGS: 103 + *port_number = 0; 104 + return 0; 105 + case PS3_MATCH_ID_SYSTEM_MANAGER: 106 + *port_number = 2; 107 + return 0; 108 + default: 109 + WARN_ON(1); 110 + *port_number = UINT_MAX; 111 + return -EINVAL; 112 + }; 113 + } 114 + 115 + #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) 116 + static void __attribute__ ((unused)) _dump_port_params(unsigned int port_number, 117 + const char* func, int line) 118 + { 119 + #if defined(DEBUG) 120 + static const char *strings[] = { 121 + "tx_trigger ", 122 + "rx_trigger ", 123 + "interrupt_mask ", 124 + "rx_buf_size ", 125 + "rx_bytes ", 126 + "tx_buf_size ", 127 + "tx_bytes ", 128 + "interrupt_status", 129 + }; 130 + int result; 131 + unsigned int i; 132 + u64 value; 133 + 134 + for (i = 0; i < ARRAY_SIZE(strings); i++) { 135 + result = lv1_get_virtual_uart_param(port_number, i, &value); 136 + 137 + if (result) { 138 + pr_debug("%s:%d: port_%u: %s failed: %s\n", func, line, 139 + port_number, strings[i], ps3_result(result)); 140 + continue; 141 + } 142 + pr_debug("%s:%d: port_%u: %s = %lxh\n", 143 + func, line, port_number, strings[i], value); 144 + } 145 + #endif 146 + } 147 + 148 + struct vuart_triggers { 149 + unsigned long rx; 150 + unsigned long tx; 151 + }; 152 + 153 + int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev, 154 + struct vuart_triggers *trig) 155 + { 156 + int result; 157 + unsigned long size; 158 + unsigned long val; 159 + 160 + result = lv1_get_virtual_uart_param(dev->port_number, 161 + PARAM_TX_TRIGGER, &trig->tx); 162 + 163 + if (result) { 164 + dev_dbg(&dev->core, "%s:%d: tx_trigger failed: %s\n", 165 + __func__, __LINE__, ps3_result(result)); 166 + return result; 167 + } 168 + 169 + result = lv1_get_virtual_uart_param(dev->port_number, 170 + PARAM_RX_BUF_SIZE, &size); 171 + 172 + if (result) { 173 + dev_dbg(&dev->core, "%s:%d: tx_buf_size failed: %s\n", 174 + __func__, __LINE__, ps3_result(result)); 175 + return result; 176 + } 177 + 178 + result = lv1_get_virtual_uart_param(dev->port_number, 179 + PARAM_RX_TRIGGER, &val); 180 + 181 + if (result) { 182 + dev_dbg(&dev->core, "%s:%d: rx_trigger failed: %s\n", 183 + __func__, __LINE__, ps3_result(result)); 184 + return result; 185 + } 186 + 187 + trig->rx = size - val; 188 + 189 + dev_dbg(&dev->core, "%s:%d: tx %lxh, rx %lxh\n", __func__, __LINE__, 190 + trig->tx, trig->rx); 191 + 192 + return result; 193 + } 194 + 195 + int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx, 196 + unsigned int rx) 197 + { 198 + int result; 199 + unsigned long size; 200 + 201 + result = lv1_set_virtual_uart_param(dev->port_number, 202 + PARAM_TX_TRIGGER, tx); 203 + 204 + if (result) { 205 + dev_dbg(&dev->core, "%s:%d: tx_trigger failed: %s\n", 206 + __func__, __LINE__, ps3_result(result)); 207 + return result; 208 + } 209 + 210 + result = lv1_get_virtual_uart_param(dev->port_number, 211 + PARAM_RX_BUF_SIZE, &size); 212 + 213 + if (result) { 214 + dev_dbg(&dev->core, "%s:%d: tx_buf_size failed: %s\n", 215 + __func__, __LINE__, ps3_result(result)); 216 + return result; 217 + } 218 + 219 + result = lv1_set_virtual_uart_param(dev->port_number, 220 + PARAM_RX_TRIGGER, size - rx); 221 + 222 + if (result) { 223 + dev_dbg(&dev->core, "%s:%d: rx_trigger failed: %s\n", 224 + __func__, __LINE__, ps3_result(result)); 225 + return result; 226 + } 227 + 228 + dev_dbg(&dev->core, "%s:%d: tx %xh, rx %xh\n", __func__, __LINE__, 229 + tx, rx); 230 + 231 + return result; 232 + } 233 + 234 + static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev, 235 + unsigned long *bytes_waiting) 236 + { 237 + int result = lv1_get_virtual_uart_param(dev->port_number, 238 + PARAM_RX_BYTES, bytes_waiting); 239 + 240 + if (result) 241 + dev_dbg(&dev->core, "%s:%d: rx_bytes failed: %s\n", 242 + __func__, __LINE__, ps3_result(result)); 243 + 244 + dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, 245 + *bytes_waiting); 246 + return result; 247 + } 248 + 249 + static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev, 250 + unsigned long mask) 251 + { 252 + int result; 253 + 254 + dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask); 255 + 256 + dev->interrupt_mask = mask; 257 + 258 + result = lv1_set_virtual_uart_param(dev->port_number, 259 + PARAM_INTERRUPT_MASK, dev->interrupt_mask); 260 + 261 + if (result) 262 + dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n", 263 + __func__, __LINE__, ps3_result(result)); 264 + 265 + return result; 266 + } 267 + 268 + static int ps3_vuart_get_interrupt_mask(struct ps3_vuart_port_device *dev, 269 + unsigned long *status) 270 + { 271 + int result = lv1_get_virtual_uart_param(dev->port_number, 272 + PARAM_INTERRUPT_STATUS, status); 273 + 274 + if (result) 275 + dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n", 276 + __func__, __LINE__, ps3_result(result)); 277 + 278 + dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n", 279 + __func__, __LINE__, dev->interrupt_mask, *status, 280 + dev->interrupt_mask & *status); 281 + 282 + return result; 283 + } 284 + 285 + int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev) 286 + { 287 + return (dev->interrupt_mask & INTERRUPT_MASK_TX) ? 0 288 + : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 289 + | INTERRUPT_MASK_TX); 290 + } 291 + 292 + int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev) 293 + { 294 + return (dev->interrupt_mask & INTERRUPT_MASK_RX) ? 0 295 + : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 296 + | INTERRUPT_MASK_RX); 297 + } 298 + 299 + int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 300 + { 301 + return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0 302 + : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 303 + | INTERRUPT_MASK_DISCONNECT); 304 + } 305 + 306 + int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev) 307 + { 308 + return (dev->interrupt_mask & INTERRUPT_MASK_TX) 309 + ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 310 + & ~INTERRUPT_MASK_TX) : 0; 311 + } 312 + 313 + int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev) 314 + { 315 + return (dev->interrupt_mask & INTERRUPT_MASK_RX) 316 + ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 317 + & ~INTERRUPT_MASK_RX) : 0; 318 + } 319 + 320 + int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 321 + { 322 + return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) 323 + ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 324 + & ~INTERRUPT_MASK_DISCONNECT) : 0; 325 + } 326 + 327 + /** 328 + * ps3_vuart_raw_write - Low level write helper. 329 + * 330 + * Do not call ps3_vuart_raw_write directly, use ps3_vuart_write. 331 + */ 332 + 333 + static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev, 334 + const void* buf, unsigned int bytes, unsigned long *bytes_written) 335 + { 336 + int result; 337 + 338 + dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 339 + 340 + result = lv1_write_virtual_uart(dev->port_number, 341 + ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written); 342 + 343 + if (result) { 344 + dev_dbg(&dev->core, "%s:%d: lv1_write_virtual_uart failed: " 345 + "%s\n", __func__, __LINE__, ps3_result(result)); 346 + return result; 347 + } 348 + 349 + dev->stats.bytes_written += *bytes_written; 350 + 351 + dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, 352 + __LINE__, *bytes_written, bytes, dev->stats.bytes_written); 353 + 354 + return result; 355 + } 356 + 357 + /** 358 + * ps3_vuart_raw_read - Low level read helper. 359 + * 360 + * Do not call ps3_vuart_raw_read directly, use ps3_vuart_read. 361 + */ 362 + 363 + static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf, 364 + unsigned int bytes, unsigned long *bytes_read) 365 + { 366 + int result; 367 + 368 + dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 369 + 370 + result = lv1_read_virtual_uart(dev->port_number, 371 + ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read); 372 + 373 + if (result) { 374 + dev_dbg(&dev->core, "%s:%d: lv1_read_virtual_uart failed: %s\n", 375 + __func__, __LINE__, ps3_result(result)); 376 + return result; 377 + } 378 + 379 + dev->stats.bytes_read += *bytes_read; 380 + 381 + dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__, 382 + *bytes_read, bytes, dev->stats.bytes_read); 383 + 384 + return result; 385 + } 386 + 387 + /** 388 + * struct list_buffer - An element for a port device fifo buffer list. 389 + */ 390 + 391 + struct list_buffer { 392 + struct list_head link; 393 + const unsigned char *head; 394 + const unsigned char *tail; 395 + unsigned long dbg_number; 396 + unsigned char data[]; 397 + }; 398 + 399 + /** 400 + * ps3_vuart_write - the entry point for writing data to a port 401 + * 402 + * If the port is idle on entry as much of the incoming data is written to 403 + * the port as the port will accept. Otherwise a list buffer is created 404 + * and any remaning incoming data is copied to that buffer. The buffer is 405 + * then enqueued for transmision via the transmit interrupt. 406 + */ 407 + 408 + int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf, 409 + unsigned int bytes) 410 + { 411 + static unsigned long dbg_number; 412 + int result; 413 + unsigned long flags; 414 + struct list_buffer *lb; 415 + 416 + dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, 417 + bytes, bytes); 418 + 419 + spin_lock_irqsave(&dev->tx_list.lock, flags); 420 + 421 + if (list_empty(&dev->tx_list.head)) { 422 + unsigned long bytes_written; 423 + 424 + result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written); 425 + 426 + spin_unlock_irqrestore(&dev->tx_list.lock, flags); 427 + 428 + if (result) { 429 + dev_dbg(&dev->core, 430 + "%s:%d: ps3_vuart_raw_write failed\n", 431 + __func__, __LINE__); 432 + return result; 433 + } 434 + 435 + if (bytes_written == bytes) { 436 + dev_dbg(&dev->core, "%s:%d: wrote %xh bytes\n", 437 + __func__, __LINE__, bytes); 438 + return 0; 439 + } 440 + 441 + bytes -= bytes_written; 442 + buf += bytes_written; 443 + } else 444 + spin_unlock_irqrestore(&dev->tx_list.lock, flags); 445 + 446 + lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); 447 + 448 + if (!lb) { 449 + return -ENOMEM; 450 + } 451 + 452 + memcpy(lb->data, buf, bytes); 453 + lb->head = lb->data; 454 + lb->tail = lb->data + bytes; 455 + lb->dbg_number = ++dbg_number; 456 + 457 + spin_lock_irqsave(&dev->tx_list.lock, flags); 458 + list_add_tail(&lb->link, &dev->tx_list.head); 459 + ps3_vuart_enable_interrupt_tx(dev); 460 + spin_unlock_irqrestore(&dev->tx_list.lock, flags); 461 + 462 + dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n", 463 + __func__, __LINE__, lb->dbg_number, bytes); 464 + 465 + return 0; 466 + } 467 + 468 + /** 469 + * ps3_vuart_read - the entry point for reading data from a port 470 + * 471 + * If enough bytes to satisfy the request are held in the buffer list those 472 + * bytes are dequeued and copied to the caller's buffer. Emptied list buffers 473 + * are retiered. If the request cannot be statified by bytes held in the list 474 + * buffers -EAGAIN is returned. 475 + */ 476 + 477 + int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf, 478 + unsigned int bytes) 479 + { 480 + unsigned long flags; 481 + struct list_buffer *lb, *n; 482 + unsigned long bytes_read; 483 + 484 + dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, 485 + bytes, bytes); 486 + 487 + spin_lock_irqsave(&dev->rx_list.lock, flags); 488 + 489 + if (dev->rx_list.bytes_held < bytes) { 490 + spin_unlock_irqrestore(&dev->rx_list.lock, flags); 491 + dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n", 492 + __func__, __LINE__, bytes - dev->rx_list.bytes_held); 493 + return -EAGAIN; 494 + } 495 + 496 + list_for_each_entry_safe(lb, n, &dev->rx_list.head, link) { 497 + bytes_read = min((unsigned int)(lb->tail - lb->head), bytes); 498 + 499 + memcpy(buf, lb->head, bytes_read); 500 + buf += bytes_read; 501 + bytes -= bytes_read; 502 + dev->rx_list.bytes_held -= bytes_read; 503 + 504 + if (bytes_read < lb->tail - lb->head) { 505 + lb->head += bytes_read; 506 + spin_unlock_irqrestore(&dev->rx_list.lock, flags); 507 + 508 + dev_dbg(&dev->core, 509 + "%s:%d: dequeued buf_%lu, %lxh bytes\n", 510 + __func__, __LINE__, lb->dbg_number, bytes_read); 511 + return 0; 512 + } 513 + 514 + dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__, 515 + lb->dbg_number); 516 + 517 + list_del(&lb->link); 518 + kfree(lb); 519 + } 520 + spin_unlock_irqrestore(&dev->rx_list.lock, flags); 521 + 522 + dev_dbg(&dev->core, "%s:%d: dequeued buf_%lu, %xh bytes\n", 523 + __func__, __LINE__, lb->dbg_number, bytes); 524 + 525 + return 0; 526 + } 527 + 528 + /** 529 + * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler 530 + * 531 + * Services the transmit interrupt for the port. Writes as much data from the 532 + * buffer list as the port will accept. Retires any emptied list buffers and 533 + * adjusts the final list buffer state for a partial write. 534 + */ 535 + 536 + static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev) 537 + { 538 + int result = 0; 539 + unsigned long flags; 540 + struct list_buffer *lb, *n; 541 + unsigned long bytes_total = 0; 542 + 543 + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 544 + 545 + spin_lock_irqsave(&dev->tx_list.lock, flags); 546 + 547 + list_for_each_entry_safe(lb, n, &dev->tx_list.head, link) { 548 + 549 + unsigned long bytes_written; 550 + 551 + result = ps3_vuart_raw_write(dev, lb->head, lb->tail - lb->head, 552 + &bytes_written); 553 + 554 + if (result) { 555 + dev_dbg(&dev->core, 556 + "%s:%d: ps3_vuart_raw_write failed\n", 557 + __func__, __LINE__); 558 + break; 559 + } 560 + 561 + bytes_total += bytes_written; 562 + 563 + if (bytes_written < lb->tail - lb->head) { 564 + lb->head += bytes_written; 565 + dev_dbg(&dev->core, 566 + "%s:%d cleared buf_%lu, %lxh bytes\n", 567 + __func__, __LINE__, lb->dbg_number, 568 + bytes_written); 569 + goto port_full; 570 + } 571 + 572 + dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__, 573 + lb->dbg_number); 574 + 575 + list_del(&lb->link); 576 + kfree(lb); 577 + } 578 + 579 + ps3_vuart_disable_interrupt_tx(dev); 580 + port_full: 581 + spin_unlock_irqrestore(&dev->tx_list.lock, flags); 582 + dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n", 583 + __func__, __LINE__, bytes_total); 584 + return result; 585 + } 586 + 587 + /** 588 + * ps3_vuart_handle_interrupt_rx - third stage receive interrupt handler 589 + * 590 + * Services the receive interrupt for the port. Creates a list buffer and 591 + * copies all waiting port data to that buffer and enqueues the buffer in the 592 + * buffer list. Buffer list data is dequeued via ps3_vuart_read. 593 + */ 594 + 595 + static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev) 596 + { 597 + static unsigned long dbg_number; 598 + int result = 0; 599 + unsigned long flags; 600 + struct list_buffer *lb; 601 + unsigned long bytes; 602 + 603 + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 604 + 605 + result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes); 606 + 607 + if (result) 608 + return -EIO; 609 + 610 + BUG_ON(!bytes); 611 + 612 + /* add some extra space for recently arrived data */ 613 + 614 + bytes += 128; 615 + 616 + lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_ATOMIC); 617 + 618 + if (!lb) 619 + return -ENOMEM; 620 + 621 + ps3_vuart_raw_read(dev, lb->data, bytes, &bytes); 622 + 623 + lb->head = lb->data; 624 + lb->tail = lb->data + bytes; 625 + lb->dbg_number = ++dbg_number; 626 + 627 + spin_lock_irqsave(&dev->rx_list.lock, flags); 628 + list_add_tail(&lb->link, &dev->rx_list.head); 629 + dev->rx_list.bytes_held += bytes; 630 + spin_unlock_irqrestore(&dev->rx_list.lock, flags); 631 + 632 + dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %lxh bytes\n", 633 + __func__, __LINE__, lb->dbg_number, bytes); 634 + 635 + return 0; 636 + } 637 + 638 + static int ps3_vuart_handle_interrupt_disconnect( 639 + struct ps3_vuart_port_device *dev) 640 + { 641 + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 642 + BUG_ON("no support"); 643 + return -1; 644 + } 645 + 646 + /** 647 + * ps3_vuart_handle_port_interrupt - second stage interrupt handler 648 + * 649 + * Services any pending interrupt types for the port. Passes control to the 650 + * third stage type specific interrupt handler. Returns control to the first 651 + * stage handler after one iteration. 652 + */ 653 + 654 + static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev) 655 + { 656 + int result; 657 + unsigned long status; 658 + 659 + result = ps3_vuart_get_interrupt_mask(dev, &status); 660 + 661 + if (result) 662 + return result; 663 + 664 + dev_dbg(&dev->core, "%s:%d: status: %lxh\n", __func__, __LINE__, 665 + status); 666 + 667 + if (status & INTERRUPT_MASK_DISCONNECT) { 668 + dev->stats.disconnect_interrupts++; 669 + result = ps3_vuart_handle_interrupt_disconnect(dev); 670 + if (result) 671 + ps3_vuart_disable_interrupt_disconnect(dev); 672 + } 673 + 674 + if (status & INTERRUPT_MASK_TX) { 675 + dev->stats.tx_interrupts++; 676 + result = ps3_vuart_handle_interrupt_tx(dev); 677 + if (result) 678 + ps3_vuart_disable_interrupt_tx(dev); 679 + } 680 + 681 + if (status & INTERRUPT_MASK_RX) { 682 + dev->stats.rx_interrupts++; 683 + result = ps3_vuart_handle_interrupt_rx(dev); 684 + if (result) 685 + ps3_vuart_disable_interrupt_rx(dev); 686 + } 687 + 688 + return 0; 689 + } 690 + 691 + struct vuart_private { 692 + unsigned int in_use; 693 + unsigned int virq; 694 + struct ps3_vuart_port_device *devices[PORT_COUNT]; 695 + const struct ports_bmp bmp; 696 + }; 697 + 698 + /** 699 + * ps3_vuart_irq_handler - first stage interrupt handler 700 + * 701 + * Loops finding any interrupting port and its associated instance data. 702 + * Passes control to the second stage port specific interrupt handler. Loops 703 + * until all outstanding interrupts are serviced. 704 + */ 705 + 706 + static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private) 707 + { 708 + struct vuart_private *private; 709 + 710 + BUG_ON(!_private); 711 + private = (struct vuart_private *)_private; 712 + 713 + while (1) { 714 + unsigned int port; 715 + 716 + dump_ports_bmp(&private->bmp); 717 + 718 + port = (BITS_PER_LONG - 1) - __ilog2(private->bmp.status); 719 + 720 + if (port == BITS_PER_LONG) 721 + break; 722 + 723 + BUG_ON(port >= PORT_COUNT); 724 + BUG_ON(!private->devices[port]); 725 + 726 + ps3_vuart_handle_port_interrupt(private->devices[port]); 727 + } 728 + 729 + return IRQ_HANDLED; 730 + } 731 + 732 + static int ps3_vuart_match(struct device *_dev, struct device_driver *_drv) 733 + { 734 + int result; 735 + struct ps3_vuart_port_driver *drv = to_ps3_vuart_port_driver(_drv); 736 + struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 737 + 738 + result = dev->match_id == drv->match_id; 739 + 740 + dev_info(&dev->core, "%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, 741 + __LINE__, dev->match_id, dev->core.bus_id, drv->match_id, 742 + drv->core.name, (result ? "match" : "miss")); 743 + 744 + return result; 745 + } 746 + 747 + static struct vuart_private vuart_private; 748 + 749 + static int ps3_vuart_probe(struct device *_dev) 750 + { 751 + int result; 752 + unsigned long tmp; 753 + struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 754 + struct ps3_vuart_port_driver *drv = 755 + to_ps3_vuart_port_driver(_dev->driver); 756 + 757 + dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 758 + 759 + BUG_ON(!drv); 760 + 761 + result = ps3_vuart_match_id_to_port(dev->match_id, &dev->port_number); 762 + 763 + if (result) { 764 + dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n", 765 + __func__, __LINE__, dev->match_id); 766 + result = -EINVAL; 767 + goto fail_match; 768 + } 769 + 770 + if (vuart_private.devices[dev->port_number]) { 771 + dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__, 772 + __LINE__, dev->port_number); 773 + result = -EBUSY; 774 + goto fail_match; 775 + } 776 + 777 + vuart_private.devices[dev->port_number] = dev; 778 + 779 + INIT_LIST_HEAD(&dev->tx_list.head); 780 + spin_lock_init(&dev->tx_list.lock); 781 + INIT_LIST_HEAD(&dev->rx_list.head); 782 + spin_lock_init(&dev->rx_list.lock); 783 + 784 + vuart_private.in_use++; 785 + if (vuart_private.in_use == 1) { 786 + result = ps3_alloc_vuart_irq((void*)&vuart_private.bmp.status, 787 + &vuart_private.virq); 788 + 789 + if (result) { 790 + dev_dbg(&dev->core, 791 + "%s:%d: ps3_alloc_vuart_irq failed (%d)\n", 792 + __func__, __LINE__, result); 793 + result = -EPERM; 794 + goto fail_alloc_irq; 795 + } 796 + 797 + result = request_irq(vuart_private.virq, ps3_vuart_irq_handler, 798 + IRQF_DISABLED, "vuart", &vuart_private); 799 + 800 + if (result) { 801 + dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n", 802 + __func__, __LINE__, result); 803 + goto fail_request_irq; 804 + } 805 + } 806 + 807 + ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX); 808 + 809 + /* clear stale pending interrupts */ 810 + ps3_vuart_get_interrupt_mask(dev, &tmp); 811 + 812 + ps3_vuart_set_triggers(dev, 1, 1); 813 + 814 + if (drv->probe) 815 + result = drv->probe(dev); 816 + else { 817 + result = 0; 818 + dev_info(&dev->core, "%s:%d: no probe method\n", __func__, 819 + __LINE__); 820 + } 821 + 822 + if (result) { 823 + dev_dbg(&dev->core, "%s:%d: drv->probe failed\n", 824 + __func__, __LINE__); 825 + goto fail_probe; 826 + } 827 + 828 + return result; 829 + 830 + fail_probe: 831 + fail_request_irq: 832 + vuart_private.in_use--; 833 + if (!vuart_private.in_use) { 834 + ps3_free_vuart_irq(vuart_private.virq); 835 + vuart_private.virq = NO_IRQ; 836 + } 837 + fail_alloc_irq: 838 + fail_match: 839 + dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__); 840 + return result; 841 + } 842 + 843 + static int ps3_vuart_remove(struct device *_dev) 844 + { 845 + struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 846 + struct ps3_vuart_port_driver *drv = 847 + to_ps3_vuart_port_driver(_dev->driver); 848 + 849 + dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__, 850 + dev->core.bus_id); 851 + 852 + BUG_ON(vuart_private.in_use < 1); 853 + 854 + if (drv->remove) 855 + drv->remove(dev); 856 + else 857 + dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__, 858 + __LINE__, dev->core.bus_id); 859 + 860 + vuart_private.in_use--; 861 + 862 + if (!vuart_private.in_use) { 863 + free_irq(vuart_private.virq, &vuart_private); 864 + ps3_free_vuart_irq(vuart_private.virq); 865 + vuart_private.virq = NO_IRQ; 866 + } 867 + return 0; 868 + } 869 + 870 + /** 871 + * ps3_vuart - The vuart instance. 872 + * 873 + * The vuart is managed as a bus that port devices connect to. 874 + */ 875 + 876 + struct bus_type ps3_vuart = { 877 + .name = "ps3_vuart", 878 + .match = ps3_vuart_match, 879 + .probe = ps3_vuart_probe, 880 + .remove = ps3_vuart_remove, 881 + }; 882 + 883 + int __init ps3_vuart_init(void) 884 + { 885 + int result; 886 + 887 + pr_debug("%s:%d:\n", __func__, __LINE__); 888 + result = bus_register(&ps3_vuart); 889 + BUG_ON(result); 890 + return result; 891 + } 892 + 893 + void __exit ps3_vuart_exit(void) 894 + { 895 + pr_debug("%s:%d:\n", __func__, __LINE__); 896 + bus_unregister(&ps3_vuart); 897 + } 898 + 899 + core_initcall(ps3_vuart_init); 900 + module_exit(ps3_vuart_exit); 901 + 902 + /** 903 + * ps3_vuart_port_release_device - Remove a vuart port device. 904 + */ 905 + 906 + static void ps3_vuart_port_release_device(struct device *_dev) 907 + { 908 + struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 909 + #if defined(DEBUG) 910 + memset(dev, 0xad, sizeof(struct ps3_vuart_port_device)); 911 + #endif 912 + kfree(dev); 913 + } 914 + 915 + /** 916 + * ps3_vuart_port_device_register - Add a vuart port device. 917 + */ 918 + 919 + int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev) 920 + { 921 + int result; 922 + static unsigned int dev_count = 1; 923 + 924 + dev->core.parent = NULL; 925 + dev->core.bus = &ps3_vuart; 926 + dev->core.release = ps3_vuart_port_release_device; 927 + 928 + snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x", 929 + dev_count++); 930 + 931 + dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__); 932 + 933 + result = device_register(&dev->core); 934 + 935 + return result; 936 + } 937 + 938 + EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register); 939 + 940 + /** 941 + * ps3_vuart_port_driver_register - Add a vuart port device driver. 942 + */ 943 + 944 + int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv) 945 + { 946 + int result; 947 + 948 + pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name); 949 + drv->core.bus = &ps3_vuart; 950 + result = driver_register(&drv->core); 951 + return result; 952 + } 953 + 954 + EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register); 955 + 956 + /** 957 + * ps3_vuart_port_driver_unregister - Remove a vuart port device driver. 958 + */ 959 + 960 + void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv) 961 + { 962 + driver_unregister(&drv->core); 963 + } 964 + 965 + EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_unregister);
+94
drivers/ps3/vuart.h
··· 1 + /* 2 + * PS3 virtual uart 3 + * 4 + * Copyright (C) 2006 Sony Computer Entertainment Inc. 5 + * Copyright 2006 Sony Corp. 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; version 2 of the License. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #if !defined(_PS3_VUART_H) 22 + #define _PS3_VUART_H 23 + 24 + struct ps3_vuart_stats { 25 + unsigned long bytes_written; 26 + unsigned long bytes_read; 27 + unsigned long tx_interrupts; 28 + unsigned long rx_interrupts; 29 + unsigned long disconnect_interrupts; 30 + }; 31 + 32 + /** 33 + * struct ps3_vuart_port_device - a device on a vuart port 34 + */ 35 + 36 + struct ps3_vuart_port_device { 37 + enum ps3_match_id match_id; 38 + struct device core; 39 + 40 + /* private driver variables */ 41 + unsigned int port_number; 42 + unsigned long interrupt_mask; 43 + struct { 44 + spinlock_t lock; 45 + struct list_head head; 46 + } tx_list; 47 + struct { 48 + unsigned long bytes_held; 49 + spinlock_t lock; 50 + struct list_head head; 51 + } rx_list; 52 + struct ps3_vuart_stats stats; 53 + }; 54 + 55 + /** 56 + * struct ps3_vuart_port_driver - a driver for a device on a vuart port 57 + */ 58 + 59 + struct ps3_vuart_port_driver { 60 + enum ps3_match_id match_id; 61 + struct device_driver core; 62 + int (*probe)(struct ps3_vuart_port_device *); 63 + int (*remove)(struct ps3_vuart_port_device *); 64 + int (*tx_event)(struct ps3_vuart_port_device *dev); 65 + int (*rx_event)(struct ps3_vuart_port_device *dev); 66 + int (*disconnect_event)(struct ps3_vuart_port_device *dev); 67 + /* int (*suspend)(struct ps3_vuart_port_device *, pm_message_t); */ 68 + /* int (*resume)(struct ps3_vuart_port_device *); */ 69 + }; 70 + 71 + int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev); 72 + int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv); 73 + void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv); 74 + int ps3_vuart_write(struct ps3_vuart_port_device *dev, 75 + const void* buf, unsigned int bytes); 76 + int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf, 77 + unsigned int bytes); 78 + static inline struct ps3_vuart_port_driver *to_ps3_vuart_port_driver( 79 + struct device_driver *_drv) 80 + { 81 + return container_of(_drv, struct ps3_vuart_port_driver, core); 82 + } 83 + static inline struct ps3_vuart_port_device *to_ps3_vuart_port_device( 84 + struct device *_dev) 85 + { 86 + return container_of(_dev, struct ps3_vuart_port_device, core); 87 + } 88 + 89 + int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf, 90 + unsigned int bytes); 91 + int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf, 92 + unsigned int bytes); 93 + 94 + #endif
+1 -1
include/asm-powerpc/Kbuild
··· 17 17 header-y += poll.h 18 18 header-y += shmparam.h 19 19 header-y += sockios.h 20 - header-y += spu_info.h 21 20 header-y += ucontext.h 22 21 header-y += ioctl.h 23 22 header-y += linkage.h ··· 36 37 unifdef-y += ptrace.h 37 38 unifdef-y += seccomp.h 38 39 unifdef-y += signal.h 40 + unifdef-y += spu_info.h 39 41 unifdef-y += termios.h 40 42 unifdef-y += types.h 41 43 unifdef-y += unistd.h
+40 -40
include/asm-powerpc/bug.h
··· 13 13 14 14 #ifndef __ASSEMBLY__ 15 15 16 - struct bug_entry { 17 - unsigned long bug_addr; 18 - long line; 19 - const char *file; 20 - const char *function; 21 - }; 22 - 23 - struct bug_entry *find_bug(unsigned long bugaddr); 24 - 25 - /* 26 - * If this bit is set in the line number it means that the trap 27 - * is for WARN_ON rather than BUG or BUG_ON. 28 - */ 29 - #define BUG_WARNING_TRAP 0x1000000 30 - 31 16 #ifdef CONFIG_BUG 17 + 18 + /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and 19 + sizeof(struct bug_entry), respectively */ 20 + #ifdef CONFIG_DEBUG_BUGVERBOSE 21 + #define _EMIT_BUG_ENTRY \ 22 + ".section __bug_table,\"a\"\n" \ 23 + "2:\t" PPC_LONG "1b, %0\n" \ 24 + "\t.short %1, %2\n" \ 25 + ".org 2b+%3\n" \ 26 + ".previous\n" 27 + #else 28 + #define _EMIT_BUG_ENTRY \ 29 + ".section __bug_table,\"a\"\n" \ 30 + "2:\t" PPC_LONG "1b\n" \ 31 + "\t.short %2\n" \ 32 + ".org 2b+%3\n" \ 33 + ".previous\n" 34 + #endif 32 35 33 36 /* 34 37 * BUG_ON() and WARN_ON() do their best to cooperate with compile-time ··· 39 36 * some compiler versions may not produce optimal results. 40 37 */ 41 38 42 - #define BUG() do { \ 43 - __asm__ __volatile__( \ 44 - "1: twi 31,0,0\n" \ 45 - ".section __bug_table,\"a\"\n" \ 46 - "\t"PPC_LONG" 1b,%0,%1,%2\n" \ 47 - ".previous" \ 48 - : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ 39 + #define BUG() do { \ 40 + __asm__ __volatile__( \ 41 + "1: twi 31,0,0\n" \ 42 + _EMIT_BUG_ENTRY \ 43 + : : "i" (__FILE__), "i" (__LINE__), \ 44 + "i" (0), "i" (sizeof(struct bug_entry))); \ 45 + for(;;) ; \ 49 46 } while (0) 50 47 51 48 #define BUG_ON(x) do { \ ··· 54 51 BUG(); \ 55 52 } else { \ 56 53 __asm__ __volatile__( \ 57 - "1: "PPC_TLNEI" %0,0\n" \ 58 - ".section __bug_table,\"a\"\n" \ 59 - "\t"PPC_LONG" 1b,%1,%2,%3\n" \ 60 - ".previous" \ 61 - : : "r" ((long)(x)), "i" (__LINE__), \ 62 - "i" (__FILE__), "i" (__FUNCTION__)); \ 54 + "1: "PPC_TLNEI" %4,0\n" \ 55 + _EMIT_BUG_ENTRY \ 56 + : : "i" (__FILE__), "i" (__LINE__), "i" (0), \ 57 + "i" (sizeof(struct bug_entry)), \ 58 + "r" ((long)(x))); \ 63 59 } \ 64 60 } while (0) 65 61 66 62 #define __WARN() do { \ 67 63 __asm__ __volatile__( \ 68 64 "1: twi 31,0,0\n" \ 69 - ".section __bug_table,\"a\"\n" \ 70 - "\t"PPC_LONG" 1b,%0,%1,%2\n" \ 71 - ".previous" \ 72 - : : "i" (__LINE__ + BUG_WARNING_TRAP), \ 73 - "i" (__FILE__), "i" (__FUNCTION__)); \ 65 + _EMIT_BUG_ENTRY \ 66 + : : "i" (__FILE__), "i" (__LINE__), \ 67 + "i" (BUGFLAG_WARNING), \ 68 + "i" (sizeof(struct bug_entry))); \ 74 69 } while (0) 75 70 76 71 #define WARN_ON(x) ({ \ ··· 78 77 __WARN(); \ 79 78 } else { \ 80 79 __asm__ __volatile__( \ 81 - "1: "PPC_TLNEI" %0,0\n" \ 82 - ".section __bug_table,\"a\"\n" \ 83 - "\t"PPC_LONG" 1b,%1,%2,%3\n" \ 84 - ".previous" \ 85 - : : "r" (__ret_warn_on), \ 86 - "i" (__LINE__ + BUG_WARNING_TRAP), \ 87 - "i" (__FILE__), "i" (__FUNCTION__)); \ 80 + "1: "PPC_TLNEI" %4,0\n" \ 81 + _EMIT_BUG_ENTRY \ 82 + : : "i" (__FILE__), "i" (__LINE__), \ 83 + "i" (BUGFLAG_WARNING), \ 84 + "i" (sizeof(struct bug_entry)), \ 85 + "r" (__ret_warn_on)); \ 88 86 } \ 89 87 unlikely(__ret_warn_on); \ 90 88 })
+12 -4
include/asm-powerpc/cputable.h
··· 126 126 #define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000) 127 127 #define CPU_FTR_PPC_LE ASM_CONST(0x0000000000200000) 128 128 #define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000) 129 + #define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x0000000000800000) 129 130 130 131 /* 131 132 * Add the 64-bit processor unique features in the top half of the word; ··· 153 152 #define CPU_FTR_PURR LONG_ASM_CONST(0x0000400000000000) 154 153 #define CPU_FTR_CELL_TB_BUG LONG_ASM_CONST(0x0000800000000000) 155 154 #define CPU_FTR_SPURR LONG_ASM_CONST(0x0001000000000000) 155 + #define CPU_FTR_DSCR LONG_ASM_CONST(0x0002000000000000) 156 156 157 157 #ifndef __ASSEMBLY__ 158 158 ··· 297 295 #define CPU_FTRS_E300 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \ 298 296 CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \ 299 297 CPU_FTR_COMMON) 298 + #define CPU_FTRS_E300C2 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \ 299 + CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \ 300 + CPU_FTR_COMMON | CPU_FTR_FPU_UNAVAILABLE) 300 301 #define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ 301 302 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE) 302 303 #define CPU_FTRS_8XX (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB) ··· 335 330 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 336 331 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 337 332 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 338 - CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE) 333 + CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ 334 + CPU_FTR_DSCR) 339 335 #define CPU_FTRS_POWER6X (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 340 336 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 341 337 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 342 338 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 343 339 CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE | \ 344 - CPU_FTR_SPURR | CPU_FTR_REAL_LE) 340 + CPU_FTR_SPURR | CPU_FTR_REAL_LE | CPU_FTR_DSCR) 345 341 #define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 346 342 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 347 343 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ ··· 370 364 CPU_FTRS_7450_21 | CPU_FTRS_7450_23 | CPU_FTRS_7455_1 | 371 365 CPU_FTRS_7455_20 | CPU_FTRS_7455 | CPU_FTRS_7447_10 | 372 366 CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX | 373 - CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_CLASSIC32 | 367 + CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_E300C2 | 368 + CPU_FTRS_CLASSIC32 | 374 369 #else 375 370 CPU_FTRS_GENERIC_32 | 376 371 #endif ··· 410 403 CPU_FTRS_7450_21 & CPU_FTRS_7450_23 & CPU_FTRS_7455_1 & 411 404 CPU_FTRS_7455_20 & CPU_FTRS_7455 & CPU_FTRS_7447_10 & 412 405 CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX & 413 - CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_CLASSIC32 & 406 + CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_E300C2 & 407 + CPU_FTRS_CLASSIC32 & 414 408 #else 415 409 CPU_FTRS_GENERIC_32 & 416 410 #endif
+35 -2
include/asm-powerpc/dcr-native.h
··· 20 20 #ifndef _ASM_POWERPC_DCR_NATIVE_H 21 21 #define _ASM_POWERPC_DCR_NATIVE_H 22 22 #ifdef __KERNEL__ 23 - 24 - #include <asm/reg.h> 23 + #ifndef __ASSEMBLY__ 25 24 26 25 typedef struct {} dcr_host_t; 27 26 ··· 31 32 #define dcr_read(host, dcr_n) mfdcr(dcr_n) 32 33 #define dcr_write(host, dcr_n, value) mtdcr(dcr_n, value) 33 34 35 + /* Device Control Registers */ 36 + void __mtdcr(int reg, unsigned int val); 37 + unsigned int __mfdcr(int reg); 38 + #define mfdcr(rn) \ 39 + ({unsigned int rval; \ 40 + if (__builtin_constant_p(rn)) \ 41 + asm volatile("mfdcr %0," __stringify(rn) \ 42 + : "=r" (rval)); \ 43 + else \ 44 + rval = __mfdcr(rn); \ 45 + rval;}) 34 46 47 + #define mtdcr(rn, v) \ 48 + do { \ 49 + if (__builtin_constant_p(rn)) \ 50 + asm volatile("mtdcr " __stringify(rn) ",%0" \ 51 + : : "r" (v)); \ 52 + else \ 53 + __mtdcr(rn, v); \ 54 + } while (0) 55 + 56 + /* R/W of indirect DCRs make use of standard naming conventions for DCRs */ 57 + #define mfdcri(base, reg) \ 58 + ({ \ 59 + mtdcr(base ## _CFGADDR, base ## _ ## reg); \ 60 + mfdcr(base ## _CFGDATA); \ 61 + }) 62 + 63 + #define mtdcri(base, reg, data) \ 64 + do { \ 65 + mtdcr(base ## _CFGADDR, base ## _ ## reg); \ 66 + mtdcr(base ## _CFGDATA, data); \ 67 + } while (0) 68 + 69 + #endif /* __ASSEMBLY__ */ 35 70 #endif /* __KERNEL__ */ 36 71 #endif /* _ASM_POWERPC_DCR_NATIVE_H */ 37 72
+2
include/asm-powerpc/dcr.h
··· 20 20 #ifndef _ASM_POWERPC_DCR_H 21 21 #define _ASM_POWERPC_DCR_H 22 22 #ifdef __KERNEL__ 23 + #ifdef CONFIG_PPC_DCR 23 24 24 25 #ifdef CONFIG_PPC_DCR_NATIVE 25 26 #include <asm/dcr-native.h> ··· 39 38 unsigned int index); 40 39 #endif /* CONFIG_PPC_MERGE */ 41 40 41 + #endif /* CONFIG_PPC_DCR */ 42 42 #endif /* __KERNEL__ */ 43 43 #endif /* _ASM_POWERPC_DCR_H */
-19
include/asm-powerpc/hw_irq.h
··· 107 107 108 108 #endif /* CONFIG_PPC64 */ 109 109 110 - #define mask_irq(irq) \ 111 - ({ \ 112 - irq_desc_t *desc = get_irq_desc(irq); \ 113 - if (desc->chip && desc->chip->disable) \ 114 - desc->chip->disable(irq); \ 115 - }) 116 - #define unmask_irq(irq) \ 117 - ({ \ 118 - irq_desc_t *desc = get_irq_desc(irq); \ 119 - if (desc->chip && desc->chip->enable) \ 120 - desc->chip->enable(irq); \ 121 - }) 122 - #define ack_irq(irq) \ 123 - ({ \ 124 - irq_desc_t *desc = get_irq_desc(irq); \ 125 - if (desc->chip && desc->chip->ack) \ 126 - desc->chip->ack(irq); \ 127 - }) 128 - 129 110 /* 130 111 * interrupt-retrigger: should we handle this via lost interrupts and IPIs 131 112 * or should we not care like we do now ? --BenH.
-2
include/asm-powerpc/module.h
··· 46 46 unsigned int num_bugs; 47 47 }; 48 48 49 - extern struct bug_entry *module_find_bug(unsigned long bugaddr); 50 - 51 49 /* 52 50 * Select ELF headers. 53 51 * Make empty section for module_frob_arch_sections to expand.
+2 -2
include/asm-powerpc/pci-bridge.h
··· 31 31 int last_busno; 32 32 33 33 void __iomem *io_base_virt; 34 - unsigned long io_base_phys; 34 + resource_size_t io_base_phys; 35 35 36 36 /* Some machines have a non 1:1 mapping of 37 37 * the PCI memory space in the CPU bus space 38 38 */ 39 - unsigned long pci_mem_offset; 39 + resource_size_t pci_mem_offset; 40 40 unsigned long pci_io_size; 41 41 42 42 struct pci_ops *ops;
+22 -11
include/asm-powerpc/pci.h
··· 143 143 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ 144 144 #define HAVE_PCI_MMAP 1 145 145 146 - #ifdef CONFIG_PPC64 147 - /* pci_unmap_{single,page} is not a nop, thus... */ 146 + #if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE) 147 + /* 148 + * For 64-bit kernels, pci_unmap_{single,page} is not a nop. 149 + * For 32-bit non-coherent kernels, pci_dma_sync_single_for_cpu() and 150 + * so on are not nops. 151 + * and thus... 152 + */ 148 153 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ 149 154 dma_addr_t ADDR_NAME; 150 155 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ ··· 162 157 ((PTR)->LEN_NAME) 163 158 #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ 164 159 (((PTR)->LEN_NAME) = (VAL)) 160 + 161 + #else /* 32-bit && coherent */ 162 + 163 + /* pci_unmap_{page,single} is a nop so... */ 164 + #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) 165 + #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) 166 + #define pci_unmap_addr(PTR, ADDR_NAME) (0) 167 + #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) 168 + #define pci_unmap_len(PTR, LEN_NAME) (0) 169 + #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) 170 + 171 + #endif /* CONFIG_PPC64 || CONFIG_NOT_COHERENT_CACHE */ 172 + 173 + #ifdef CONFIG_PPC64 165 174 166 175 /* The PCI address space does not equal the physical memory address 167 176 * space (we have an IOMMU). The IDE and SCSI device layers use ··· 191 172 */ 192 173 #define PCI_DMA_BUS_IS_PHYS (1) 193 174 194 - /* pci_unmap_{page,single} is a nop so... */ 195 - #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) 196 - #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) 197 - #define pci_unmap_addr(PTR, ADDR_NAME) (0) 198 - #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) 199 - #define pci_unmap_len(PTR, LEN_NAME) (0) 200 - #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) 201 - 202 175 #endif /* CONFIG_PPC64 */ 203 - 176 + 204 177 extern void pcibios_resource_to_bus(struct pci_dev *dev, 205 178 struct pci_bus_region *region, 206 179 struct resource *res);
+2
include/asm-powerpc/reg.h
··· 143 143 144 144 /* Special Purpose Registers (SPRNs)*/ 145 145 #define SPRN_CTR 0x009 /* Count Register */ 146 + #define SPRN_DSCR 0x11 146 147 #define SPRN_CTRLF 0x088 147 148 #define SPRN_CTRLT 0x098 148 149 #define CTRL_CT 0xc0000000 /* current thread */ ··· 164 163 #define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ 165 164 #define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */ 166 165 #define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ 166 + #define SPRN_SPURR 0x134 /* Scaled PURR */ 167 167 #define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ 168 168 #define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */ 169 169 #define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */
+1 -2
include/asm-powerpc/rtas.h
··· 159 159 160 160 extern void enter_rtas(unsigned long); 161 161 extern int rtas_token(const char *service); 162 + extern int rtas_service_present(const char *service); 162 163 extern int rtas_call(int token, int, int, int *, ...); 163 164 extern void rtas_restart(char *cmd); 164 165 extern void rtas_power_off(void); ··· 221 220 #define RTAS_DATA_BUF_SIZE 4096 222 221 extern spinlock_t rtas_data_buf_lock; 223 222 extern char rtas_data_buf[RTAS_DATA_BUF_SIZE]; 224 - 225 - extern void rtas_stop_self(void); 226 223 227 224 /* RMO buffer reserved for user-space RTAS use */ 228 225 extern unsigned long rtas_rmo_buf;
+4 -4
include/asm-ppc/pci-bridge.h
··· 20 20 extern struct pci_controller* pcibios_alloc_controller(void); 21 21 22 22 /* Helper function for setting up resources */ 23 - extern void pci_init_resource(struct resource *res, unsigned long start, 24 - unsigned long end, int flags, char *name); 23 + extern void pci_init_resource(struct resource *res, resource_size_t start, 24 + resource_size_t end, int flags, char *name); 25 25 26 26 /* Get the PCI host controller for a bus */ 27 27 extern struct pci_controller* pci_bus_to_hose(int bus); ··· 50 50 int bus_offset; 51 51 52 52 void __iomem *io_base_virt; 53 - unsigned long io_base_phys; 53 + resource_size_t io_base_phys; 54 54 55 55 /* Some machines (PReP) have a non 1:1 mapping of 56 56 * the PCI memory space in the CPU bus space 57 57 */ 58 - unsigned long pci_mem_offset; 58 + resource_size_t pci_mem_offset; 59 59 60 60 struct pci_ops *ops; 61 61 volatile unsigned int __iomem *cfg_addr;
+23
include/asm-ppc/pci.h
··· 61 61 */ 62 62 #define PCI_DMA_BUS_IS_PHYS (1) 63 63 64 + #ifdef CONFIG_NOT_COHERENT_CACHE 65 + /* 66 + * pci_unmap_{page,single} are NOPs but pci_dma_sync_single_for_cpu() 67 + * and so on are not, so... 68 + */ 69 + 70 + #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ 71 + dma_addr_t ADDR_NAME; 72 + #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ 73 + __u32 LEN_NAME; 74 + #define pci_unmap_addr(PTR, ADDR_NAME) \ 75 + ((PTR)->ADDR_NAME) 76 + #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ 77 + (((PTR)->ADDR_NAME) = (VAL)) 78 + #define pci_unmap_len(PTR, LEN_NAME) \ 79 + ((PTR)->LEN_NAME) 80 + #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ 81 + (((PTR)->LEN_NAME) = (VAL)) 82 + 83 + #else /* coherent */ 84 + 64 85 /* pci_unmap_{page,single} is a nop so... */ 65 86 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) 66 87 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) ··· 89 68 #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) 90 69 #define pci_unmap_len(PTR, LEN_NAME) (0) 91 70 #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) 71 + 72 + #endif /* CONFIG_NOT_COHERENT_CACHE */ 92 73 93 74 #ifdef CONFIG_PCI 94 75 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+2 -34
include/asm-ppc/reg_booke.h
··· 9 9 #ifndef __ASM_PPC_REG_BOOKE_H__ 10 10 #define __ASM_PPC_REG_BOOKE_H__ 11 11 12 + #include <asm/dcr.h> 13 + 12 14 #ifndef __ASSEMBLY__ 13 - /* Device Control Registers */ 14 - void __mtdcr(int reg, unsigned int val); 15 - unsigned int __mfdcr(int reg); 16 - #define mfdcr(rn) \ 17 - ({unsigned int rval; \ 18 - if (__builtin_constant_p(rn)) \ 19 - asm volatile("mfdcr %0," __stringify(rn) \ 20 - : "=r" (rval)); \ 21 - else \ 22 - rval = __mfdcr(rn); \ 23 - rval;}) 24 - 25 - #define mtdcr(rn, v) \ 26 - do { \ 27 - if (__builtin_constant_p(rn)) \ 28 - asm volatile("mtdcr " __stringify(rn) ",%0" \ 29 - : : "r" (v)); \ 30 - else \ 31 - __mtdcr(rn, v); \ 32 - } while (0) 33 - 34 - /* R/W of indirect DCRs make use of standard naming conventions for DCRs */ 35 - #define mfdcri(base, reg) \ 36 - ({ \ 37 - mtdcr(base ## _CFGADDR, base ## _ ## reg); \ 38 - mfdcr(base ## _CFGDATA); \ 39 - }) 40 - 41 - #define mtdcri(base, reg, data) \ 42 - do { \ 43 - mtdcr(base ## _CFGADDR, base ## _ ## reg); \ 44 - mtdcr(base ## _CFGDATA, data); \ 45 - } while (0) 46 - 47 15 /* Performance Monitor Registers */ 48 16 #define mfpmr(rn) ({unsigned int rval; \ 49 17 asm volatile("mfpmr %0," __stringify(rn) \
+1
include/linux/fsl_devices.h
··· 19 19 #define _FSL_DEVICE_H_ 20 20 21 21 #include <linux/types.h> 22 + #include <linux/phy.h> 22 23 23 24 /* 24 25 * Some conventions on how we handle peripherals on Freescale chips