From 1433fa7d8da608f59df1f6f381da00958bf5a0b7 Mon Sep 17 00:00:00 2001 From: Jason Jin Date: Thu, 4 Dec 2008 19:14:28 +0800 Subject: powerpc: Fix the ide suspend function in uli1575 The general pci resume code can only restore part of the configuration registers. We need to reconfigure those registers in the FIXUP_RESUME. Signed-off-by: Jason Jin Signed-off-by: Kumar Gala --- arch/powerpc/platforms/fsl_uli1575.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c index 8c619963bec..1db6b9e037f 100644 --- a/arch/powerpc/platforms/fsl_uli1575.c +++ b/arch/powerpc/platforms/fsl_uli1575.c @@ -249,6 +249,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x5249, quirk_final_uli5249); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x1575, quirk_final_uli1575); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); static void __devinit hpcd_quirk_uli1575(struct pci_dev *dev) { -- cgit v1.2.3 From be122d6d8b836fec329d740e75bfbdffa96ff6ff Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 6 Jan 2009 10:23:37 -0600 Subject: powerpc/85xx: Fix PCIe error interrupts The PCIe interrupts for 8544ds and 8572ds were incorrect. The 8572 case was found by Liu Yu. Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8544ds.dts | 4 ++-- arch/powerpc/boot/dts/mpc8572ds.dts | 4 ++-- arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts | 2 +- arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts index b9da4210506..0668d104877 100644 --- a/arch/powerpc/boot/dts/mpc8544ds.dts +++ b/arch/powerpc/boot/dts/mpc8544ds.dts @@ -313,7 +313,7 @@ 0x1000000 0x0 0x0 0xe1010000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <26 2>; + interrupts = <25 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ @@ -350,7 +350,7 @@ 0x1000000 0x0 0x0 0xe1020000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <25 2>; + interrupts = <26 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts index 21459e161d0..3dcc001b8ed 100644 --- a/arch/powerpc/boot/dts/mpc8572ds.dts +++ b/arch/powerpc/boot/dts/mpc8572ds.dts @@ -724,7 +724,7 @@ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <26 2>; + interrupts = <25 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ @@ -761,7 +761,7 @@ 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <27 2>; + interrupts = <26 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts index c114c4ee993..fd462efa9e6 100644 --- a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts +++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts @@ -457,7 +457,7 @@ 0x1000000 0x0 0x0 0xffc10000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <26 2>; + interrupts = <25 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts index 04ecda18d20..e35230f2ac9 100644 --- a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts +++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts @@ -208,7 +208,7 @@ 0x1000000 0x0 0x0 0xffc20000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; - interrupts = <27 2>; + interrupts = <26 2>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0 */ -- cgit v1.2.3 From fdd4e8152f5f0d6d500b35515265e425acdfd203 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 6 Jan 2009 17:12:23 -0600 Subject: powerpc/qe: add Ethernet UPSMR definitions to QE library Add the UCC_GETH_UPSMR_xxx definitions to qe.h. The ucc_geth driver will eventually use these instead of the UPSMR_ macros it currently defines. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/include/asm/qe.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h index a0a15311d0d..2701753d993 100644 --- a/arch/powerpc/include/asm/qe.h +++ b/arch/powerpc/include/asm/qe.h @@ -624,7 +624,7 @@ struct ucc_slow_pram { #define UCC_GETH_UCCE_RXF1 0x00000002 #define UCC_GETH_UCCE_RXF0 0x00000001 -/* UPSMR, when used as a UART */ +/* UCC Protocol Specific Mode Register (UPSMR), when used for UART */ #define UCC_UART_UPSMR_FLC 0x8000 #define UCC_UART_UPSMR_SL 0x4000 #define UCC_UART_UPSMR_CL_MASK 0x3000 @@ -652,6 +652,23 @@ struct ucc_slow_pram { #define UCC_UART_UPSMR_TPM_EVEN 0x0002 #define UCC_UART_UPSMR_TPM_HIGH 0x0003 +/* UCC Protocol Specific Mode Register (UPSMR), when used for Ethernet */ +#define UCC_GETH_UPSMR_FTFE 0x80000000 +#define UCC_GETH_UPSMR_PTPE 0x40000000 +#define UCC_GETH_UPSMR_ECM 0x04000000 +#define UCC_GETH_UPSMR_HSE 0x02000000 +#define UCC_GETH_UPSMR_PRO 0x00400000 +#define UCC_GETH_UPSMR_CAP 0x00200000 +#define UCC_GETH_UPSMR_RSH 0x00100000 +#define UCC_GETH_UPSMR_RPM 0x00080000 +#define UCC_GETH_UPSMR_R10M 0x00040000 +#define UCC_GETH_UPSMR_RLPB 0x00020000 +#define UCC_GETH_UPSMR_TBIM 0x00010000 +#define UCC_GETH_UPSMR_RES1 0x00002000 +#define UCC_GETH_UPSMR_RMM 0x00001000 +#define UCC_GETH_UPSMR_CAM 0x00000400 +#define UCC_GETH_UPSMR_BRO 0x00000200 + /* UCC Transmit On Demand Register (UTODR) */ #define UCC_SLOW_TOD 0x8000 #define UCC_FAST_TOD 0x8000 -- cgit v1.2.3 From a097a78c1e6e4030fcef3bcab6351b6001662335 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 6 Jan 2009 22:37:53 -0600 Subject: powerpc/fsl-pci: Better ATMU setup for 85xx/86xx The code that sets up the outbound ATMU windows, which is used to map CPU physical addresses into PCI bus addresses where BARs will be mapped, didn't work so well. For one, it leaked the ioremap() of the ATMU registers. Another small bug was the high 20 bits of the PCI bus address were left as zero. It's legal for prefetchable memory regions to be above 32 bits, so the high 20 bits might not be zero. Mainly, it couldn't handle ranges that were not a power of two in size or were not naturally aligned. The ATMU windows have these requirements (size & alignment), but the code didn't bother to check if the ranges it was programming met them. If they didn't, the windows would silently be programmed incorrectly. This new code can handle ranges which are not power of two sized nor naturally aligned. It simply splits the ranges into multiple valid ATMU windows. As there are only four windows, pooly aligned or sized ranges (which didn't even work before) may run out of windows. In this case an error is printed and an effort is made to disable the unmapped resources. An improvement that could be made would be to make use of the default outbound window. Iff hose->pci_mem_offset is zero, then it's possible that some or all of the ranges might not need an outbound window and could just use the default window. The default ATMU window can support a pci_mem_offset less than zero too, but pci_mem_offset is unsigned. One could say the abilities allowed a powerpc pci_controller is neither subset nor a superset of the abilities of a Freescale PCIe controller. Thankfully, the most useful bits are in the intersection of the two abilities. Signed-off-by: Trent Piepho Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_pci.c | 104 ++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index f611d0369cc..44bc903ead7 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -28,63 +28,101 @@ #include #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx) +static int __init setup_one_atmu(struct ccsr_pci __iomem *pci, + unsigned int index, const struct resource *res, + resource_size_t offset) +{ + resource_size_t pci_addr = res->start - offset; + resource_size_t phys_addr = res->start; + resource_size_t size = res->end - res->start + 1; + u32 flags = 0x80044000; /* enable & mem R/W */ + unsigned int i; + + pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", + (u64)res->start, (u64)size); + + for (i = 0; size > 0; i++) { + unsigned int bits = min(__ilog2(size), + __ffs(pci_addr | phys_addr)); + + if (index + i >= 5) + return -1; + + out_be32(&pci->pow[index + i].potar, pci_addr >> 12); + out_be32(&pci->pow[index + i].potear, (u64)pci_addr >> 44); + out_be32(&pci->pow[index + i].powbar, phys_addr >> 12); + out_be32(&pci->pow[index + i].powar, flags | (bits - 1)); + + pci_addr += (resource_size_t)1U << bits; + phys_addr += (resource_size_t)1U << bits; + size -= (resource_size_t)1U << bits; + } + + return i; +} + /* atmu setup for fsl pci/pcie controller */ static void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc) { struct ccsr_pci __iomem *pci; - int i; + int i, j, n; pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1); pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); + if (!pci) { + dev_err(hose->parent, "Unable to map ATMU registers\n"); + return; + } - /* Disable all windows (except powar0 since its ignored) */ + /* Disable all windows (except powar0 since it's ignored) */ for(i = 1; i < 5; i++) out_be32(&pci->pow[i].powar, 0); for(i = 0; i < 3; i++) out_be32(&pci->piw[i].piwar, 0); /* Setup outbound MEM window */ - for(i = 0; i < 3; i++) - if (hose->mem_resources[i].flags & IORESOURCE_MEM){ - resource_size_t pci_addr_start = - hose->mem_resources[i].start - - hose->pci_mem_offset; - pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", - (u64)hose->mem_resources[i].start, - (u64)hose->mem_resources[i].end - - (u64)hose->mem_resources[i].start + 1); - out_be32(&pci->pow[i+1].potar, (pci_addr_start >> 12)); - out_be32(&pci->pow[i+1].potear, 0); - out_be32(&pci->pow[i+1].powbar, - (hose->mem_resources[i].start >> 12)); - /* Enable, Mem R/W */ - out_be32(&pci->pow[i+1].powar, 0x80044000 - | (__ilog2(hose->mem_resources[i].end - - hose->mem_resources[i].start + 1) - 1)); - } + for(i = 0, j = 1; i < 3; i++) { + if (!(hose->mem_resources[i].flags & IORESOURCE_MEM)) + continue; + + n = setup_one_atmu(pci, j, &hose->mem_resources[i], + hose->pci_mem_offset); + + if (n < 0 || j >= 5) { + pr_err("Ran out of outbound PCI ATMUs for resource %d!\n", i); + hose->mem_resources[i].flags |= IORESOURCE_DISABLED; + } else + j += n; + } /* Setup outbound IO window */ - if (hose->io_resource.flags & IORESOURCE_IO){ - pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, " - "phy base 0x%016llx.\n", - (u64)hose->io_resource.start, - (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1, - (u64)hose->io_base_phys); - out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12)); - out_be32(&pci->pow[i+1].potear, 0); - out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12)); - /* Enable, IO R/W */ - out_be32(&pci->pow[i+1].powar, 0x80088000 - | (__ilog2(hose->io_resource.end - - hose->io_resource.start + 1) - 1)); + if (hose->io_resource.flags & IORESOURCE_IO) { + if (j >= 5) { + pr_err("Ran out of outbound PCI ATMUs for IO resource\n"); + } else { + pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, " + "phy base 0x%016llx.\n", + (u64)hose->io_resource.start, + (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1, + (u64)hose->io_base_phys); + out_be32(&pci->pow[j].potar, (hose->io_resource.start >> 12)); + out_be32(&pci->pow[j].potear, 0); + out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12)); + /* Enable, IO R/W */ + out_be32(&pci->pow[j].powar, 0x80088000 + | (__ilog2(hose->io_resource.end + - hose->io_resource.start + 1) - 1)); + } } /* Setup 2G inbound Memory Window @ 1 */ out_be32(&pci->piw[2].pitar, 0x00000000); out_be32(&pci->piw[2].piwbar,0x00000000); out_be32(&pci->piw[2].piwar, PIWAR_2G); + + iounmap(pci); } static void __init setup_pci_cmd(struct pci_controller *hose) -- cgit v1.2.3 From 565f37642c78754a85efe6c20a4a15e18ed21f07 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 17 Dec 2008 11:43:26 -0800 Subject: powerpc/fsl-pci: Set relaxed ordering on prefetchable ranges Provides a small speedup when accessing pefetchable ranges. To indicate that a memory range is prefetchable, mark it in the dts file with 42000000 instead of 02000000. A powepc pci_controller is allowed three memory ranges, any of which may be prefetchable. However, the PCI-PCI bridge configuration space only has one field for "non-prefetchable memory behind bridge", which has a 32 bit address, and one field for "prefetchable memory behind bridge", which may have a 64 bit address. These are PCI bus addresses, not CPU physical addresses. So really you're only allowed one memory range of each type. And if you want the range at a PCI address above 32 bits you must make it prefetchable. Signed-off-by: Trent Piepho Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_pci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 44bc903ead7..9817f63723d 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -41,6 +41,9 @@ static int __init setup_one_atmu(struct ccsr_pci __iomem *pci, pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", (u64)res->start, (u64)size); + if (res->flags & IORESOURCE_PREFETCH) + flags |= 0x10000000; /* enable relaxed ordering */ + for (i = 0; size > 0; i++) { unsigned int bits = min(__ilog2(size), __ffs(pci_addr | phys_addr)); -- cgit v1.2.3 From 19f5465e823858a2f0b0e9a92e52816ba3ee70bb Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 8 Dec 2008 19:34:55 -0800 Subject: powerpc/fsl-booke: Don't hard-code size of struct tlbcam Some assembly code in head_fsl_booke.S hard-coded the size of struct tlbcam to 20 when it indexed the TLBCAM table. Anyone changing the size of struct tlbcam would not know to expect that. The kernel already has a system to get the size of C structures into assembly language files, asm-offsets, so let's use it. The definition of the struct gets moved to a header, so that asm-offsets.c can include it. Signed-off-by: Trent Piepho Signed-off-by: Kumar Gala --- arch/powerpc/kernel/asm-offsets.c | 7 +++++++ arch/powerpc/kernel/head_fsl_booke.S | 2 +- arch/powerpc/mm/fsl_booke_mmu.c | 8 +------- arch/powerpc/mm/mmu_decl.h | 9 +++++++++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 661d07d2146..06958da94f1 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -56,6 +56,10 @@ #include "head_booke.h" #endif +#if defined(CONFIG_FSL_BOOKE) +#include "../mm/mmu_decl.h" +#endif + int main(void) { DEFINE(THREAD, offsetof(struct task_struct, thread)); @@ -384,6 +388,9 @@ int main(void) DEFINE(PGD_T_LOG2, PGD_T_LOG2); DEFINE(PTE_T_LOG2, PTE_T_LOG2); #endif +#ifdef CONFIG_FSL_BOOKE + DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam)); +#endif return 0; } diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 11b549acc03..805f28d30e4 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -909,7 +909,7 @@ KernelSPE: _GLOBAL(loadcam_entry) lis r4,TLBCAM@ha addi r4,r4,TLBCAM@l - mulli r5,r3,20 + mulli r5,r3,TLBCAM_SIZE add r3,r5,r4 lwz r4,0(r3) mtspr SPRN_MAS0,r4 diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index 23cee39534f..c9ee59af100 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -61,13 +61,7 @@ static unsigned long __cam0, __cam1, __cam2; #define NUM_TLBCAMS (16) -struct tlbcam { - u32 MAS0; - u32 MAS1; - u32 MAS2; - u32 MAS3; - u32 MAS7; -} TLBCAM[NUM_TLBCAMS]; +struct tlbcam TLBCAM[NUM_TLBCAMS]; struct tlbcamrange { unsigned long start; diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 4314b39b6fa..6f6ee62c2a0 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -75,6 +75,15 @@ extern void _tlbia(void); #endif /* CONFIG_PPC_MMU_NOHASH */ #ifdef CONFIG_PPC32 + +struct tlbcam { + u32 MAS0; + u32 MAS1; + u32 MAS2; + u32 MAS3; + u32 MAS7; +}; + extern void mapin_ram(void); extern int map_page(unsigned long va, phys_addr_t pa, int flags); extern void setbat(int index, unsigned long virt, phys_addr_t phys, -- cgit v1.2.3 From 6fd8be4bf72879b3039654388e985cabf8449af5 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 8 Dec 2008 19:34:56 -0800 Subject: powerpc/fsl-booke: Remove num_tlbcam_entries This is a global variable defined in fsl_booke_mmu.c with a value that gets initialized in assembly code in head_fsl_booke.S. It's never used. If some code ever does want to know the number of entries in TLB1, then "numcams = mfspr(SPRN_TLB1CFG) & 0xfff", is a whole lot simpler than a global initialized during kernel boot from assembly. Signed-off-by: Trent Piepho Signed-off-by: Kumar Gala --- arch/powerpc/kernel/head_fsl_booke.S | 4 ---- arch/powerpc/mm/fsl_booke_mmu.c | 1 - arch/powerpc/mm/mmu_decl.h | 2 -- 3 files changed, 7 deletions(-) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 805f28d30e4..2f32720a44a 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -389,10 +389,6 @@ skpinv: addi r6,r6,1 /* Increment */ #endif #endif - mfspr r3,SPRN_TLB1CFG - andi. r3,r3,0xfff - lis r4,num_tlbcam_entries@ha - stw r3,num_tlbcam_entries@l(r4) /* * Decide what sort of machine this is and initialize the MMU. */ diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index c9ee59af100..1971e4ee3d6 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -56,7 +56,6 @@ extern void loadcam_entry(unsigned int index); unsigned int tlbcam_index; -unsigned int num_tlbcam_entries; static unsigned long __cam0, __cam1, __cam2; #define NUM_TLBCAMS (16) diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 6f6ee62c2a0..d0bb69dc627 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -99,8 +99,6 @@ extern unsigned int rtas_data, rtas_size; struct hash_pte; extern struct hash_pte *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; - -extern unsigned int num_tlbcam_entries; #endif extern unsigned long ioremap_bot; -- cgit v1.2.3 From 23faf63123e306b4a134f6d6c501813f6c8599dc Mon Sep 17 00:00:00 2001 From: roel kluin Date: Fri, 9 Jan 2009 15:49:04 -0700 Subject: powerpc/mpc5121: fix NULL test in mpc5121_clk_get utility function. strcmp on NULL results in a segmentation fault, also, remove the second, redundant test on dev Signed-off-by: Roel Kluin Signed-off-by: Grant Likely --- arch/powerpc/platforms/512x/clock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index f416014ee72..1bcff94eb92 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c @@ -56,12 +56,12 @@ static struct clk *mpc5121_clk_get(struct device *dev, const char *id) int dev_match = 0; int id_match = 0; - if (dev == NULL && id == NULL) + if (dev == NULL || id == NULL) return NULL; mutex_lock(&clocks_mutex); list_for_each_entry(p, &clocks, node) { - if (dev && dev == p->dev) + if (dev == p->dev) dev_match++; if (strcmp(id, p->name) == 0) id_match++; -- cgit v1.2.3 From d30239a0ef2000cfae6c60f8e870da2d8dba4d22 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 9 Jan 2009 15:49:05 -0700 Subject: powerpc/mpc52xx: Properly update irq_desc when set_type() is called. The MPC5200 PIC driver doesn't correctly update the .status field of the irq_desc structure when the set_type hook is called. This patch adds the required code. Also cleans up the external IRQ typename field to be something easier to read (very minor). Signed-off-by: Grant Likely --- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 72865e8e4b5..0a093f03c75 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -196,6 +196,7 @@ static void mpc52xx_extirq_ack(unsigned int virq) static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type) { + struct irq_desc *desc = get_irq_desc(virq); u32 ctrl_reg, type; int irq; int l2irq; @@ -222,6 +223,11 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type) type = 0; } + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) + desc->status |= IRQ_LEVEL; + ctrl_reg = in_be32(&intr->ctrl); ctrl_reg &= ~(0x3 << (22 - (l2irq * 2))); ctrl_reg |= (type << (22 - (l2irq * 2))); @@ -231,7 +237,7 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type) } static struct irq_chip mpc52xx_extirq_irqchip = { - .typename = " MPC52xx IRQ[0-3] ", + .typename = "MPC52xx External", .mask = mpc52xx_extirq_mask, .unmask = mpc52xx_extirq_unmask, .ack = mpc52xx_extirq_ack, -- cgit v1.2.3 From ddd527d56a0e635abdc7ffeb688cdde7593ad2d3 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 9 Jan 2009 15:49:05 -0700 Subject: powerpc/mpc52xx: remove dead code from GPIO driver Eliminate duplicate return statements Signed-off-by: Wolfram Sang Signed-off-by: Grant Likely --- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 8a455ebce98..07f89ae46d0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -363,11 +363,8 @@ static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct mpc52xx_gpt __iomem *regs = mm_gc->regs; - unsigned int ret; return (in_be32(®s->status) & (1 << (31 - 23))) ? 1 : 0; - - return ret; } static void -- cgit v1.2.3 From f5020384e4fa8ab9397aa6fa176e61e9bf7947f7 Mon Sep 17 00:00:00 2001 From: Yuri Tikhonov Date: Fri, 9 Jan 2009 15:49:06 -0700 Subject: powerpc/xsysace: add compatible string for non-ipcore instance Add "xlnx,sysace" compatible string to the of_platform binding table. Platforms which have the SysACE chip on board (e.g. Katmai) instead of via a Xilinx generated IP core will use this value in their device tree. Signed-off-by: Yuri Tikhonov Signed-off-by: Grant Likely --- drivers/block/xsysace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 29e1dfafb7c..381d686fc1a 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1206,6 +1206,7 @@ static struct of_device_id ace_of_match[] __devinitdata = { { .compatible = "xlnx,opb-sysace-1.00.b", }, { .compatible = "xlnx,opb-sysace-1.00.c", }, { .compatible = "xlnx,xps-sysace-1.00.a", }, + { .compatible = "xlnx,sysace", }, {}, }; MODULE_DEVICE_TABLE(of, ace_of_match); -- cgit v1.2.3 From 2526c151c31358aec66b63921dd712bbec5ee0cb Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Fri, 9 Jan 2009 15:49:06 -0700 Subject: drivers/of: Add the of_find_i2c_device_by_node function. The of_find_i2c_device_by_node function allows you to follow a reference in the device tree to an i2c device node and then locate the linux device instantiated by the device tree. Example use: an I2S bus driver finding the i2c_device instance for a codec described by a device tree node. This was waiting for Anton's i2c patches that were just added. Signed-off-by: Jon Smirl Signed-off-by: Grant Likely --- drivers/of/of_i2c.c | 19 +++++++++++++++++++ include/linux/of_i2c.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index e1b0ad6e918..fa65a2b2ae2 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -66,4 +66,23 @@ void of_register_i2c_devices(struct i2c_adapter *adap, } EXPORT_SYMBOL(of_register_i2c_devices); +static int of_dev_node_match(struct device *dev, void *data) +{ + return dev_archdata_get_node(&dev->archdata) == data; +} + +/* must call put_device() when done with returned i2c_client device */ +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) +{ + struct device *dev; + + dev = bus_find_device(&i2c_bus_type, NULL, node, + of_dev_node_match); + if (!dev) + return NULL; + + return to_i2c_client(dev); +} +EXPORT_SYMBOL(of_find_i2c_device_by_node); + MODULE_LICENSE("GPL"); diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h index bd2a870ec29..34974b5a76f 100644 --- a/include/linux/of_i2c.h +++ b/include/linux/of_i2c.h @@ -17,4 +17,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node); +/* must call put_device() when done with returned i2c_client device */ +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); + #endif /* __LINUX_OF_I2C_H */ -- cgit v1.2.3 From ff82c587a9a4cb8796e7e04377155deba15ae18b Mon Sep 17 00:00:00 2001 From: John Linn Date: Fri, 9 Jan 2009 16:01:53 -0700 Subject: Xilinx: SPI: updated driver for device tree The driver was updated to use the device tree rather than the platform data. Signed-off-by: John Linn --- drivers/spi/xilinx_spi.c | 137 ++++++++++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 56 deletions(-) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 68d6f4988fb..fe7e5f35e5d 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -15,12 +15,15 @@ #include #include #include + +#include +#include +#include + #include #include #include -#include - #define XILINX_SPI_NAME "xilinx_spi" /* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e) @@ -144,23 +147,14 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { u8 bits_per_word; - u32 hz; - struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; - hz = (t) ? t->speed_hz : spi->max_speed_hz; if (bits_per_word != 8) { dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", __func__, bits_per_word); return -EINVAL; } - if (hz && xspi->speed_hz > hz) { - dev_err(&spi->dev, "%s, unsupported clock rate %uHz\n", - __func__, hz); - return -EINVAL; - } - return 0; } @@ -304,32 +298,38 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int __init xilinx_spi_probe(struct platform_device *dev) +static int __init xilinx_spi_of_probe(struct of_device *ofdev, + const struct of_device_id *match) { - int ret = 0; struct spi_master *master; struct xilinx_spi *xspi; - struct xspi_platform_data *pdata; - struct resource *r; + struct resource r_irq_struct; + struct resource r_mem_struct; + + struct resource *r_irq = &r_irq_struct; + struct resource *r_mem = &r_mem_struct; + int rc = 0; + const u32 *prop; + int len; /* Get resources(memory, IRQ) associated with the device */ - master = spi_alloc_master(&dev->dev, sizeof(struct xilinx_spi)); + master = spi_alloc_master(&ofdev->dev, sizeof(struct xilinx_spi)); if (master == NULL) { return -ENOMEM; } - platform_set_drvdata(dev, master); - pdata = dev->dev.platform_data; + dev_set_drvdata(&ofdev->dev, master); - if (pdata == NULL) { - ret = -ENODEV; + rc = of_address_to_resource(ofdev->node, 0, r_mem); + if (rc) { + dev_warn(&ofdev->dev, "invalid address\n"); goto put_master; } - r = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (r == NULL) { - ret = -ENODEV; + rc = of_irq_to_resource(ofdev->node, 0, r_irq); + if (rc == NO_IRQ) { + dev_warn(&ofdev->dev, "no IRQ found\n"); goto put_master; } @@ -341,47 +341,57 @@ static int __init xilinx_spi_probe(struct platform_device *dev) xspi->bitbang.master->setup = xilinx_spi_setup; init_completion(&xspi->done); - if (!request_mem_region(r->start, - r->end - r->start + 1, XILINX_SPI_NAME)) { - ret = -ENXIO; + xspi->irq = r_irq->start; + + if (!request_mem_region(r_mem->start, + r_mem->end - r_mem->start + 1, XILINX_SPI_NAME)) { + rc = -ENXIO; + dev_warn(&ofdev->dev, "memory request failure\n"); goto put_master; } - xspi->regs = ioremap(r->start, r->end - r->start + 1); + xspi->regs = ioremap(r_mem->start, r_mem->end - r_mem->start + 1); if (xspi->regs == NULL) { - ret = -ENOMEM; + rc = -ENOMEM; + dev_warn(&ofdev->dev, "ioremap failure\n"); goto put_master; } + xspi->irq = r_irq->start; - ret = platform_get_irq(dev, 0); - if (ret < 0) { - ret = -ENXIO; - goto unmap_io; - } - xspi->irq = ret; + /* dynamic bus assignment */ + master->bus_num = -1; - master->bus_num = pdata->bus_num; - master->num_chipselect = pdata->num_chipselect; - xspi->speed_hz = pdata->speed_hz; + /* number of slave select bits is required */ + prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len); + if (!prop || len < sizeof(*prop)) { + dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n"); + goto put_master; + } + master->num_chipselect = *prop; /* SPI controller initializations */ xspi_init_hw(xspi->regs); /* Register for SPI Interrupt */ - ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); - if (ret != 0) + rc = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); + if (rc != 0) { + dev_warn(&ofdev->dev, "irq request failure: %d\n", xspi->irq); goto unmap_io; + } - ret = spi_bitbang_start(&xspi->bitbang); - if (ret != 0) { - dev_err(&dev->dev, "spi_bitbang_start FAILED\n"); + rc = spi_bitbang_start(&xspi->bitbang); + if (rc != 0) { + dev_err(&ofdev->dev, "spi_bitbang_start FAILED\n"); goto free_irq; } - dev_info(&dev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n", - r->start, (u32)xspi->regs, xspi->irq); + dev_info(&ofdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n", + (unsigned int)r_mem->start, (u32)xspi->regs, xspi->irq); - return ret; + /* Add any subnodes on the SPI bus */ + of_register_spi_devices(master, ofdev->node); + + return rc; free_irq: free_irq(xspi->irq, xspi); @@ -389,21 +399,21 @@ unmap_io: iounmap(xspi->regs); put_master: spi_master_put(master); - return ret; + return rc; } -static int __devexit xilinx_spi_remove(struct platform_device *dev) +static int __devexit xilinx_spi_remove(struct of_device *ofdev) { struct xilinx_spi *xspi; struct spi_master *master; - master = platform_get_drvdata(dev); + master = platform_get_drvdata(ofdev); xspi = spi_master_get_devdata(master); spi_bitbang_stop(&xspi->bitbang); free_irq(xspi->irq, xspi); iounmap(xspi->regs); - platform_set_drvdata(dev, 0); + dev_set_drvdata(&ofdev->dev, 0); spi_master_put(xspi->bitbang.master); return 0; @@ -412,27 +422,42 @@ static int __devexit xilinx_spi_remove(struct platform_device *dev) /* work with hotplug and coldplug */ MODULE_ALIAS("platform:" XILINX_SPI_NAME); -static struct platform_driver xilinx_spi_driver = { - .probe = xilinx_spi_probe, - .remove = __devexit_p(xilinx_spi_remove), +static int __exit xilinx_spi_of_remove(struct of_device *op) +{ + return xilinx_spi_remove(op); +} + +static struct of_device_id xilinx_spi_of_match[] = { + { .compatible = "xlnx,xps-spi-2.00.a", }, + { .compatible = "xlnx,xps-spi-2.00.b", }, + {} +}; + +MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); + +static struct of_platform_driver xilinx_spi_of_driver = { + .owner = THIS_MODULE, + .name = "xilinx-xps-spi", + .match_table = xilinx_spi_of_match, + .probe = xilinx_spi_of_probe, + .remove = __exit_p(xilinx_spi_of_remove), .driver = { - .name = XILINX_SPI_NAME, + .name = "xilinx-xps-spi", .owner = THIS_MODULE, }, }; static int __init xilinx_spi_init(void) { - return platform_driver_register(&xilinx_spi_driver); + return of_register_platform_driver(&xilinx_spi_of_driver); } module_init(xilinx_spi_init); static void __exit xilinx_spi_exit(void) { - platform_driver_unregister(&xilinx_spi_driver); + of_unregister_platform_driver(&xilinx_spi_of_driver); } module_exit(xilinx_spi_exit); - MODULE_AUTHOR("MontaVista Software, Inc. "); MODULE_DESCRIPTION("Xilinx SPI driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From e16459c6b7e9c1390020a3e2a033b5383d1c4f3b Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 2 Jan 2009 10:46:04 +0000 Subject: powerpc: Make dummy section a valid note header We are declaring the dummy section (used to work around a binutils bug) as PT_NOTE, but we don't have enough bytes for it to be a valid note header, and kexec userspace complains: Warning: Elf Note name is not null terminated Warning: append= option is not passed. Using the first kernel root partition Warning: Elf Note name is not null terminated Instead of using the arbitray value 0xf177 (aka "fill"), declare a no-name no-description note of type 0. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vmlinux.lds.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 47bf15cd2c9..161b9b9691f 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -87,7 +87,9 @@ SECTIONS /* The dummy segment contents for the bug workaround mentioned above near PHDRS. */ .dummy : AT(ADDR(.dummy) - LOAD_OFFSET) { - LONG(0xf177) + LONG(0) + LONG(0) + LONG(0) } :kernel :dummy /* -- cgit v1.2.3 From 66c721e184e594d5761c5db804ade08fab81930d Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 2 Jan 2009 10:46:15 +0000 Subject: powerpc/kexec: Check crash_base for relocatable kernel Enforce that the crash kernel region never overlaps the current kernel, as it will be written directly on kexec load. Also, default to the previous KDUMP_KERNELBASE if the start is 0. Other architectures (x86, ia64) state that specifying the start address 0 (or omitting it) will result in the kernel allocating it. Before the relocatable patch in 2.6.28, powerpc would adjust any other start value to the hardcoded KDUMP_KERNELBASE of 32M. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/machine_kexec.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index b3abebb7ee6..d59e2b1bdcb 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -93,10 +93,35 @@ void __init reserve_crashkernel(void) KDUMP_KERNELBASE); crashk_res.start = KDUMP_KERNELBASE; +#else + if (!crashk_res.start) { + /* + * unspecified address, choose a region of specified size + * can overlap with initrd (ignoring corruption when retained) + * ppc64 requires kernel and some stacks to be in first segemnt + */ + crashk_res.start = KDUMP_KERNELBASE; + } + + crash_base = PAGE_ALIGN(crashk_res.start); + if (crash_base != crashk_res.start) { + printk("Crash kernel base must be aligned to 0x%lx\n", + PAGE_SIZE); + crashk_res.start = crash_base; + } + #endif crash_size = PAGE_ALIGN(crash_size); crashk_res.end = crashk_res.start + crash_size - 1; + /* The crash region must not overlap the current kernel */ + if (overlaps_crashkernel(__pa(_stext), _end - _stext)) { + printk(KERN_WARNING + "Crash kernel can not overlap current kernel\n"); + crashk_res.start = crashk_res.end = 0; + return; + } + /* Crash kernel trumps memory limit */ if (memory_limit && memory_limit <= crashk_res.end) { memory_limit = crashk_res.end + 1; -- cgit v1.2.3 From fe333321e2a71f706b794d55b6a3dcb5ab240f65 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 6 Jan 2009 14:26:03 +0000 Subject: powerpc: Change u64/s64 to a long long integer type Convert arch/powerpc/ over to long long based u64: -#ifdef __powerpc64__ -# include -#else -# include -#endif +#include This will avoid reoccuring spurious warnings in core kernel code that comes when people test on their own hardware. (i.e. x86 in ~98% of the cases) This is what x86 uses and it generally helps keep 64-bit code 32-bit clean too. [Adjusted to not impact user mode (from paulus) - sfr] Signed-off-by: Ingo Molnar Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/rtas.h | 2 +- arch/powerpc/include/asm/types.h | 7 +++++- arch/powerpc/kernel/dma-iommu.c | 4 +-- arch/powerpc/kernel/iommu.c | 12 ++++----- arch/powerpc/kernel/lparcfg.c | 10 ++++---- arch/powerpc/kernel/setup_64.c | 6 ++--- arch/powerpc/mm/stab.c | 4 +-- arch/powerpc/oprofile/op_model_pa6t.c | 6 ++--- arch/powerpc/platforms/cell/beat_interrupt.c | 2 +- arch/powerpc/platforms/cell/celleb_scc_epci.c | 4 +-- arch/powerpc/platforms/cell/iommu.c | 4 +-- arch/powerpc/platforms/cell/ras.c | 8 +++--- arch/powerpc/platforms/cell/spu_base.c | 4 +-- arch/powerpc/platforms/cell/spu_callbacks.c | 2 +- arch/powerpc/platforms/iseries/iommu.c | 4 +-- arch/powerpc/platforms/pseries/iommu.c | 35 +++++++++++++-------------- arch/powerpc/sysdev/mpic.c | 2 +- drivers/net/pasemi_mac.c | 6 ++--- drivers/pcmcia/electra_cf.c | 2 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 12 ++++----- 20 files changed, 70 insertions(+), 66 deletions(-) diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index e0175beb446..0aa0315fb7e 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -18,7 +18,7 @@ */ #define RTAS_UNKNOWN_SERVICE (-1) -#define RTAS_INSTANTIATE_MAX (1UL<<30) /* Don't instantiate rtas at/above this value */ +#define RTAS_INSTANTIATE_MAX (1ULL<<30) /* Don't instantiate rtas at/above this value */ /* Buffer size for ppc_rtas system call. */ #define RTAS_RMOBUF_MAX (64 * 1024) diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h index c004c13f291..7ce27a52bb3 100644 --- a/arch/powerpc/include/asm/types.h +++ b/arch/powerpc/include/asm/types.h @@ -1,7 +1,12 @@ #ifndef _ASM_POWERPC_TYPES_H #define _ASM_POWERPC_TYPES_H -#ifdef __powerpc64__ +/* + * This is here because we used to use l64 for 64bit powerpc + * and we don't want to impact user mode with our change to ll64 + * in the kernel. + */ +#if defined(__powerpc64__) && !defined(__KERNEL__) # include #else # include diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 14183af1b3f..2983adac8cc 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -79,10 +79,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask) "Warning: IOMMU offset too big for device mask\n"); if (tbl) printk(KERN_INFO - "mask: 0x%08lx, table offset: 0x%08lx\n", + "mask: 0x%08llx, table offset: 0x%08lx\n", mask, tbl->it_offset); else - printk(KERN_INFO "mask: 0x%08lx, table unavailable\n", + printk(KERN_INFO "mask: 0x%08llx, table unavailable\n", mask); return 0; } else diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 1bfa706b96e..fd51578e29d 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -239,12 +239,12 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, if (printk_ratelimit()) { printk(KERN_INFO "iommu_free: invalid entry\n"); printk(KERN_INFO "\tentry = 0x%lx\n", entry); - printk(KERN_INFO "\tdma_addr = 0x%lx\n", (u64)dma_addr); - printk(KERN_INFO "\tTable = 0x%lx\n", (u64)tbl); - printk(KERN_INFO "\tbus# = 0x%lx\n", (u64)tbl->it_busno); - printk(KERN_INFO "\tsize = 0x%lx\n", (u64)tbl->it_size); - printk(KERN_INFO "\tstartOff = 0x%lx\n", (u64)tbl->it_offset); - printk(KERN_INFO "\tindex = 0x%lx\n", (u64)tbl->it_index); + printk(KERN_INFO "\tdma_addr = 0x%llx\n", (u64)dma_addr); + printk(KERN_INFO "\tTable = 0x%llx\n", (u64)tbl); + printk(KERN_INFO "\tbus# = 0x%llx\n", (u64)tbl->it_busno); + printk(KERN_INFO "\tsize = 0x%llx\n", (u64)tbl->it_size); + printk(KERN_INFO "\tstartOff = 0x%llx\n", (u64)tbl->it_offset); + printk(KERN_INFO "\tindex = 0x%llx\n", (u64)tbl->it_index); WARN_ON(1); } return; diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index d051e8cbcd0..182e0f642f3 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -240,7 +240,7 @@ static void parse_ppp_data(struct seq_file *m) if (rc) return; - seq_printf(m, "partition_entitled_capacity=%ld\n", + seq_printf(m, "partition_entitled_capacity=%lld\n", ppp_data.entitlement); seq_printf(m, "group=%d\n", ppp_data.group_num); seq_printf(m, "system_active_processors=%d\n", @@ -265,7 +265,7 @@ static void parse_ppp_data(struct seq_file *m) ppp_data.unallocated_weight); seq_printf(m, "capacity_weight=%d\n", ppp_data.weight); seq_printf(m, "capped=%d\n", ppp_data.capped); - seq_printf(m, "unallocated_capacity=%ld\n", + seq_printf(m, "unallocated_capacity=%lld\n", ppp_data.unallocated_entitlement); } @@ -509,10 +509,10 @@ static ssize_t update_ppp(u64 *entitlement, u8 *weight) } else return -EINVAL; - pr_debug("%s: current_entitled = %lu, current_weight = %u\n", + pr_debug("%s: current_entitled = %llu, current_weight = %u\n", __func__, ppp_data.entitlement, ppp_data.weight); - pr_debug("%s: new_entitled = %lu, new_weight = %u\n", + pr_debug("%s: new_entitled = %llu, new_weight = %u\n", __func__, new_entitled, new_weight); retval = plpar_hcall_norets(H_SET_PPP, new_entitled, new_weight); @@ -558,7 +558,7 @@ static ssize_t update_mpp(u64 *entitlement, u8 *weight) pr_debug("%s: current_entitled = %lu, current_weight = %u\n", __func__, mpp_data.entitled_mem, mpp_data.mem_weight); - pr_debug("%s: new_entitled = %lu, new_weight = %u\n", + pr_debug("%s: new_entitled = %llu, new_weight = %u\n", __func__, new_entitled, new_weight); rc = plpar_hcall_norets(H_SET_MPP, new_entitled, new_weight); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index d8bd2161e73..2d34196bba8 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -434,8 +434,8 @@ void __init setup_system(void) printk("Starting Linux PPC64 %s\n", init_utsname()->version); printk("-----------------------------------------------------\n"); - printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); - printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size()); + printk("ppc64_pft_size = 0x%llx\n", ppc64_pft_size); + printk("physicalMemorySize = 0x%llx\n", lmb_phys_mem_size()); if (ppc64_caches.dline_size != 0x80) printk("ppc64_caches.dcache_line_size = 0x%x\n", ppc64_caches.dline_size); @@ -493,7 +493,7 @@ static void __init emergency_stack_init(void) * bringup, we need to get at them in real mode. This means they * must also be within the RMO region. */ - limit = min(0x10000000UL, lmb.rmo_size); + limit = min(0x10000000ULL, lmb.rmo_size); for_each_possible_cpu(i) { unsigned long sp; diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c index 60e6032a808..98cd1dc2ae7 100644 --- a/arch/powerpc/mm/stab.c +++ b/arch/powerpc/mm/stab.c @@ -251,8 +251,8 @@ void __init stabs_alloc(void) paca[cpu].stab_addr = newstab; paca[cpu].stab_real = virt_to_abs(newstab); - printk(KERN_INFO "Segment table for CPU %d at 0x%lx " - "virtual, 0x%lx absolute\n", + printk(KERN_INFO "Segment table for CPU %d at 0x%llx " + "virtual, 0x%llx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real); } } diff --git a/arch/powerpc/oprofile/op_model_pa6t.c b/arch/powerpc/oprofile/op_model_pa6t.c index c40de461fd4..42f778dff91 100644 --- a/arch/powerpc/oprofile/op_model_pa6t.c +++ b/arch/powerpc/oprofile/op_model_pa6t.c @@ -132,7 +132,7 @@ static int pa6t_reg_setup(struct op_counter_config *ctr, for (pmc = 0; pmc < cur_cpu_spec->num_pmcs; pmc++) { /* counters are 40 bit. Move to cputable at some point? */ reset_value[pmc] = (0x1UL << 39) - ctr[pmc].count; - pr_debug("reset_value for pmc%u inited to 0x%lx\n", + pr_debug("reset_value for pmc%u inited to 0x%llx\n", pmc, reset_value[pmc]); } @@ -177,7 +177,7 @@ static int pa6t_start(struct op_counter_config *ctr) oprofile_running = 1; - pr_debug("start on cpu %d, mmcr0 %lx\n", smp_processor_id(), mmcr0); + pr_debug("start on cpu %d, mmcr0 %llx\n", smp_processor_id(), mmcr0); return 0; } @@ -193,7 +193,7 @@ static void pa6t_stop(void) oprofile_running = 0; - pr_debug("stop on cpu %d, mmcr0 %lx\n", smp_processor_id(), mmcr0); + pr_debug("stop on cpu %d, mmcr0 %llx\n", smp_processor_id(), mmcr0); } /* handle the perfmon overflow vector */ diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c index 192a9350937..72254848a22 100644 --- a/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/arch/powerpc/platforms/cell/beat_interrupt.c @@ -99,7 +99,7 @@ static void beatic_end_irq(unsigned int irq_plug) err = beat_downcount_of_interrupt(irq_plug); if (err != 0) { if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */ - panic("Failed to downcount IRQ! Error = %16lx", err); + panic("Failed to downcount IRQ! Error = %16llx", err); printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug); } diff --git a/arch/powerpc/platforms/cell/celleb_scc_epci.c b/arch/powerpc/platforms/cell/celleb_scc_epci.c index 08c285b10e3..48ec88a38a1 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_epci.c +++ b/arch/powerpc/platforms/cell/celleb_scc_epci.c @@ -405,7 +405,7 @@ static int __init celleb_setup_epci(struct device_node *node, hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1)); if (!hose->cfg_addr) goto error; - pr_debug("EPCI: cfg_addr map 0x%016lx->0x%016lx + 0x%016lx\n", + pr_debug("EPCI: cfg_addr map 0x%016llx->0x%016lx + 0x%016llx\n", r.start, (unsigned long)hose->cfg_addr, (r.end - r.start + 1)); if (of_address_to_resource(node, 2, &r)) @@ -413,7 +413,7 @@ static int __init celleb_setup_epci(struct device_node *node, hose->cfg_data = ioremap(r.start, (r.end - r.start + 1)); if (!hose->cfg_data) goto error; - pr_debug("EPCI: cfg_data map 0x%016lx->0x%016lx + 0x%016lx\n", + pr_debug("EPCI: cfg_data map 0x%016llx->0x%016lx + 0x%016llx\n", r.start, (unsigned long)hose->cfg_data, (r.end - r.start + 1)); hose->ops = &celleb_epci_ops; diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 88d94b59a7c..ee5033eddf0 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -855,7 +855,7 @@ static int __init cell_iommu_init_disabled(void) */ if (np && size < lmb_end_of_DRAM()) { printk(KERN_WARNING "iommu: force-enabled, dma window" - " (%ldMB) smaller than total memory (%ldMB)\n", + " (%ldMB) smaller than total memory (%lldMB)\n", size >> 20, lmb_end_of_DRAM() >> 20); return -ENODEV; } @@ -985,7 +985,7 @@ static void cell_dma_dev_setup_fixed(struct device *dev) addr = cell_iommu_get_fixed_address(dev) + dma_iommu_fixed_base; archdata->dma_data = (void *)addr; - dev_dbg(dev, "iommu: fixed addr = %lx\n", addr); + dev_dbg(dev, "iommu: fixed addr = %llx\n", addr); } static void insert_16M_pte(unsigned long addr, unsigned long *ptab, diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 7b4cefa2199..5f961c464cc 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -38,16 +38,16 @@ static void dump_fir(int cpu) /* Todo: do some nicer parsing of bits and based on them go down * to other sub-units FIRs and not only IIC */ - printk(KERN_ERR "Global Checkstop FIR : 0x%016lx\n", + printk(KERN_ERR "Global Checkstop FIR : 0x%016llx\n", in_be64(&pregs->checkstop_fir)); - printk(KERN_ERR "Global Recoverable FIR : 0x%016lx\n", + printk(KERN_ERR "Global Recoverable FIR : 0x%016llx\n", in_be64(&pregs->checkstop_fir)); - printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n", + printk(KERN_ERR "Global MachineCheck FIR : 0x%016llx\n", in_be64(&pregs->spec_att_mchk_fir)); if (iregs == NULL) return; - printk(KERN_ERR "IOC FIR : 0x%016lx\n", + printk(KERN_ERR "IOC FIR : 0x%016llx\n", in_be64(&iregs->ioc_fir)); } diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index a5bdb89a17c..e487ad68ac1 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -151,7 +151,7 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) { struct spu_priv2 __iomem *priv2 = spu->priv2; - pr_debug("%s: adding SLB[%d] 0x%016lx 0x%016lx\n", + pr_debug("%s: adding SLB[%d] 0x%016llx 0x%016llx\n", __func__, slbe, slb->vsid, slb->esid); out_be64(&priv2->slb_index_W, slbe); @@ -221,7 +221,7 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) { int ret; - pr_debug("%s, %lx, %lx\n", __func__, dsisr, ea); + pr_debug("%s, %llx, %lx\n", __func__, dsisr, ea); /* * Handle kernel space hash faults immediately. User hash diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c index 19f6bfdbb93..fec1495e6b1 100644 --- a/arch/powerpc/platforms/cell/spu_callbacks.c +++ b/arch/powerpc/platforms/cell/spu_callbacks.c @@ -54,7 +54,7 @@ long spu_sys_callback(struct spu_syscall_block *s) long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6); if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) { - pr_debug("%s: invalid syscall #%ld", __func__, s->nr_ret); + pr_debug("%s: invalid syscall #%lld", __func__, s->nr_ret); return -ENOSYS; } diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index bbe828f1b88..6ed75bffc8a 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -66,7 +66,7 @@ static int tce_build_iSeries(struct iommu_table *tbl, long index, long npages, rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce); if (rc) - panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", + panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%llx\n", rc); index++; uaddr += TCE_PAGE_SIZE; @@ -81,7 +81,7 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) while (npages--) { rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); if (rc) - panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", + panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%llx\n", rc); index++; } diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index c90817acb47..3ee01b4f425 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -127,10 +127,10 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, } if (rc && printk_ratelimit()) { - printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\ttcenum = 0x%lx\n", (u64)tcenum); - printk("\ttce val = 0x%lx\n", tce ); + printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%llx\n", (u64)tcenum); + printk("\ttce val = 0x%llx\n", tce ); show_stack(current, (unsigned long *)__get_SP()); } @@ -210,10 +210,10 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, } if (rc && printk_ratelimit()) { - printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\tnpages = 0x%lx\n", (u64)npages); - printk("\ttce[0] val = 0x%lx\n", tcep[0]); + printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\tnpages = 0x%llx\n", (u64)npages); + printk("\ttce[0] val = 0x%llx\n", tcep[0]); show_stack(current, (unsigned long *)__get_SP()); } return ret; @@ -227,9 +227,9 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); if (rc && printk_ratelimit()) { - printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\ttcenum = 0x%lx\n", (u64)tcenum); + printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%llx\n", (u64)tcenum); show_stack(current, (unsigned long *)__get_SP()); } @@ -246,9 +246,9 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n if (rc && printk_ratelimit()) { printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n"); - printk("\trc = %ld\n", rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\tnpages = 0x%lx\n", (u64)npages); + printk("\trc = %lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\tnpages = 0x%llx\n", (u64)npages); show_stack(current, (unsigned long *)__get_SP()); } } @@ -261,10 +261,9 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); if (rc && printk_ratelimit()) { - printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%ld\n", - rc); - printk("\tindex = 0x%lx\n", (u64)tbl->it_index); - printk("\ttcenum = 0x%lx\n", (u64)tcenum); + printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%lld\n", rc); + printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%llx\n", (u64)tcenum); show_stack(current, (unsigned long *)__get_SP()); } diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 3e0d89dcdba..a35297dbac2 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -435,7 +435,7 @@ static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase, addr = addr | ((u64)readl(base + HT_MSI_ADDR_HI) << 32); } - printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%lx\n", + printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%llx\n", PCI_SLOT(devfn), PCI_FUNC(devfn), flags & HT_MSI_FLAGS_ENABLE ? "enabled" : "disabled", addr); diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 5b7a574ce57..d0349e7d73e 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -712,7 +712,7 @@ static inline void pasemi_mac_rx_error(const struct pasemi_mac *mac, rcmdsta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); ccmdsta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno)); - printk(KERN_ERR "pasemi_mac: rx error. macrx %016lx, rx status %lx\n", + printk(KERN_ERR "pasemi_mac: rx error. macrx %016llx, rx status %llx\n", macrx, *chan->status); printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n", @@ -730,8 +730,8 @@ static inline void pasemi_mac_tx_error(const struct pasemi_mac *mac, cmdsta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno)); - printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016lx, "\ - "tx status 0x%016lx\n", mactx, *chan->status); + printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016llx, "\ + "tx status 0x%016llx\n", mactx, *chan->status); printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta); } diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index a34284b1482..d187ba4c5e0 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -297,7 +297,7 @@ static int __devinit electra_cf_probe(struct of_device *ofdev, goto fail3; } - dev_info(device, "at mem 0x%lx io 0x%lx irq %d\n", + dev_info(device, "at mem 0x%lx io 0x%llx irq %d\n", cf->mem_phys, io.start, cf->irq); cf->active = 1; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5c541f7850f..74d07d137da 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1061,7 +1061,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) } sdev_printk(KERN_INFO, cmd->device, - "aborting command. lun 0x%lx, tag 0x%lx\n", + "aborting command. lun 0x%llx, tag 0x%llx\n", (((u64) lun) << 48), (u64) found_evt); wait_for_completion(&evt->comp); @@ -1082,7 +1082,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) if (rsp_rc) { if (printk_ratelimit()) sdev_printk(KERN_WARNING, cmd->device, - "abort code %d for task tag 0x%lx\n", + "abort code %d for task tag 0x%llx\n", rsp_rc, tsk_mgmt->task_tag); return FAILED; } @@ -1102,12 +1102,12 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) if (found_evt == NULL) { spin_unlock_irqrestore(hostdata->host->host_lock, flags); - sdev_printk(KERN_INFO, cmd->device, "aborted task tag 0x%lx completed\n", + sdev_printk(KERN_INFO, cmd->device, "aborted task tag 0x%llx completed\n", tsk_mgmt->task_tag); return SUCCESS; } - sdev_printk(KERN_INFO, cmd->device, "successfully aborted task tag 0x%lx\n", + sdev_printk(KERN_INFO, cmd->device, "successfully aborted task tag 0x%llx\n", tsk_mgmt->task_tag); cmd->result = (DID_ABORT << 16); @@ -1182,7 +1182,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) return FAILED; } - sdev_printk(KERN_INFO, cmd->device, "resetting device. lun 0x%lx\n", + sdev_printk(KERN_INFO, cmd->device, "resetting device. lun 0x%llx\n", (((u64) lun) << 48)); wait_for_completion(&evt->comp); @@ -1203,7 +1203,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) if (rsp_rc) { if (printk_ratelimit()) sdev_printk(KERN_WARNING, cmd->device, - "reset code %d for task tag 0x%lx\n", + "reset code %d for task tag 0x%llx\n", rsp_rc, tsk_mgmt->task_tag); return FAILED; } -- cgit v1.2.3 From 9477e455b4b3ded3e7add8c96d8293105947eaac Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 14:27:38 +0000 Subject: powerpc: Cleanup from l64 to ll64 change: arch code Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/pci_64.c | 6 +++--- arch/powerpc/platforms/cell/spufs/coredump.c | 2 +- arch/powerpc/platforms/cell/spufs/fault.c | 2 +- arch/powerpc/platforms/cell/spufs/file.c | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 586962f65c2..ea8eda8c87c 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -470,7 +470,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) if (bus->self) { pr_debug("IO mapping for PCI-PCI bridge %s\n", pci_name(bus->self)); - pr_debug(" virt=0x%016lx...0x%016lx\n", + pr_debug(" virt=0x%016llx...0x%016llx\n", bus->resource[0]->start + _IO_BASE, bus->resource[0]->end + _IO_BASE); return 0; @@ -502,7 +502,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) hose->io_base_phys - phys_page); pr_debug("IO mapping for PHB %s\n", hose->dn->full_name); - pr_debug(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", + pr_debug(" phys=0x%016llx, virt=0x%p (alloc=0x%p)\n", hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); pr_debug(" size=0x%016lx (alloc=0x%016lx)\n", hose->pci_io_size, size_page); @@ -517,7 +517,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) hose->io_resource.start += io_virt_offset; hose->io_resource.end += io_virt_offset; - pr_debug(" hose->io_resource=0x%016lx...0x%016lx\n", + pr_debug(" hose->io_resource=0x%016llx...0x%016llx\n", hose->io_resource.start, hose->io_resource.end); return 0; diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index af116aadba1..c4d4a19235e 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c @@ -42,7 +42,7 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer, return spufs_coredump_read[num].read(ctx, buffer, size, off); data = spufs_coredump_read[num].get(ctx); - ret = snprintf(buffer, size, "0x%.16lx", data); + ret = snprintf(buffer, size, "0x%.16llx", data); if (ret >= size) return size; return ++ret; /* count trailing NULL */ diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c index f093a581ac7..a4dd3ae7223 100644 --- a/arch/powerpc/platforms/cell/spufs/fault.c +++ b/arch/powerpc/platforms/cell/spufs/fault.c @@ -132,7 +132,7 @@ int spufs_handle_class1(struct spu_context *ctx) spuctx_switch_state(ctx, SPU_UTIL_IOWAIT); - pr_debug("ctx %p: ea %016lx, dsisr %016lx state %d\n", ctx, ea, + pr_debug("ctx %p: ea %016llx, dsisr %016llx state %d\n", ctx, ea, dsisr, ctx->state); ctx->stats.hash_flt++; diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 7106b63d401..0da7f2bf5ee 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1654,7 +1654,7 @@ out: static int spufs_check_valid_dma(struct mfc_dma_command *cmd) { - pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa, + pr_debug("queueing DMA %x %llx %x %x %x\n", cmd->lsa, cmd->ea, cmd->size, cmd->tag, cmd->cmd); switch (cmd->cmd) { @@ -1671,7 +1671,7 @@ static int spufs_check_valid_dma(struct mfc_dma_command *cmd) } if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) { - pr_debug("invalid DMA alignment, ea %lx lsa %x\n", + pr_debug("invalid DMA alignment, ea %llx lsa %x\n", cmd->ea, cmd->lsa); return -EIO; } @@ -2633,7 +2633,7 @@ static int spufs_show_ctx(struct seq_file *s, void *private) } seq_printf(s, "%c flgs(%lx) sflgs(%lx) pri(%d) ts(%d) spu(%02d)" - " %c %lx %lx %lx %lx %x %x\n", + " %c %llx %llx %llx %llx %x %x\n", ctx->state == SPU_STATE_SAVED ? 'S' : 'R', ctx->flags, ctx->sched_flags, -- cgit v1.2.3 From 1901515c79f13d9a1913d246b6c0711318dadb4c Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 14:28:48 +0000 Subject: powerpc: Cleanup from l64 to ll64 change: drivers/char This is a powerpc specific driver. Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- drivers/char/bsr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 977dfb1096a..f6094ae0ef3 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -103,7 +103,7 @@ static ssize_t bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf) { struct bsr_dev *bsr_dev = dev_get_drvdata(dev); - return sprintf(buf, "%lu\n", bsr_dev->bsr_len); + return sprintf(buf, "%llu\n", bsr_dev->bsr_len); } static struct device_attribute bsr_dev_attrs[] = { -- cgit v1.2.3 From a1c5a8932bbb75b550deb156d890027827fc9d6e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 6 Jan 2009 14:40:06 +0000 Subject: powerpc: Cleanup from l64 to ll64 change: drivers/net These are powerpc specific drivers. Signed-off-by: Stephen Rothwell Acked-by: David S. Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/net/ehea/ehea_main.c | 8 ++++---- drivers/net/ehea/ehea_qmr.c | 18 +++++++++--------- drivers/net/ibmveth.c | 16 ++++++++-------- drivers/net/iseries_veth.c | 2 +- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index e3131ea629c..dfe92264e82 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -132,7 +132,7 @@ void ehea_dump(void *adr, int len, char *msg) int x; unsigned char *deb = adr; for (x = 0; x < len; x += 16) { - printk(DRV_NAME " %s adr=%p ofs=%04x %016lx %016lx\n", msg, + printk(DRV_NAME " %s adr=%p ofs=%04x %016llx %016llx\n", msg, deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); deb += 16; } @@ -883,7 +883,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) while (eqe) { qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); - ehea_error("QP aff_err: entry=0x%lx, token=0x%x", + ehea_error("QP aff_err: entry=0x%llx, token=0x%x", eqe->entry, qp_token); qp = port->port_res[qp_token].qp; @@ -1159,7 +1159,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) netif_stop_queue(port->netdev); break; default: - ehea_error("unknown event code %x, eqe=0x%lX", ec, eqe); + ehea_error("unknown event code %x, eqe=0x%llX", ec, eqe); break; } } @@ -1971,7 +1971,7 @@ static void ehea_set_multicast_list(struct net_device *dev) } if (dev->mc_count > port->adapter->max_mc_mac) { - ehea_info("Mcast registration limit reached (0x%lx). " + ehea_info("Mcast registration limit reached (0x%llx). " "Use ALLMULTI!", port->adapter->max_mc_mac); goto out; diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 225c692b5d9..49d766ebbcf 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -168,7 +168,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, cq->fw_handle, rpage, 1); if (hret < H_SUCCESS) { ehea_error("register_rpage_cq failed ehea_cq=%p " - "hret=%lx counter=%i act_pages=%i", + "hret=%llx counter=%i act_pages=%i", cq, hret, counter, cq->attr.nr_pages); goto out_kill_hwq; } @@ -178,13 +178,13 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, if ((hret != H_SUCCESS) || (vpage)) { ehea_error("registration of pages not " - "complete hret=%lx\n", hret); + "complete hret=%llx\n", hret); goto out_kill_hwq; } } else { if (hret != H_PAGE_REGISTERED) { ehea_error("CQ: registration of page failed " - "hret=%lx\n", hret); + "hret=%llx\n", hret); goto out_kill_hwq; } } @@ -986,15 +986,15 @@ void print_error_data(u64 *data) length = EHEA_PAGESIZE; if (type == 0x8) /* Queue Pair */ - ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, " - "port=%lX", resource, data[6], data[12], data[22]); + ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, " + "port=%llX", resource, data[6], data[12], data[22]); if (type == 0x4) /* Completion Queue */ - ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource, + ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource, data[6]); if (type == 0x3) /* Event Queue */ - ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource, + ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource, data[6]); ehea_dump(data, length, "error data"); @@ -1016,11 +1016,11 @@ void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle) rblock); if (ret == H_R_STATE) - ehea_error("No error data is available: %lX.", res_handle); + ehea_error("No error data is available: %llX.", res_handle); else if (ret == H_SUCCESS) print_error_data(rblock); else - ehea_error("Error data could not be fetched: %lX", res_handle); + ehea_error("Error data could not be fetched: %llX", res_handle); kfree(rblock); } diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index ca3bb9f7321..dfa6348ac1d 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -602,7 +602,7 @@ static int ibmveth_open(struct net_device *netdev) if(lpar_rc != H_SUCCESS) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); - ibmveth_error_printk("buffer TCE:0x%lx filter TCE:0x%lx rxq desc:0x%lx MAC:0x%lx\n", + ibmveth_error_printk("buffer TCE:0x%llx filter TCE:0x%llx rxq desc:0x%llx MAC:0x%llx\n", adapter->buffer_list_dma, adapter->filter_list_dma, rxq_desc.desc, @@ -1378,13 +1378,13 @@ static int ibmveth_show(struct seq_file *seq, void *v) seq_printf(seq, "Firmware MAC: %pM\n", firmware_mac); seq_printf(seq, "\nAdapter Statistics:\n"); - seq_printf(seq, " TX: vio_map_single failres: %ld\n", adapter->tx_map_failed); - seq_printf(seq, " send failures: %ld\n", adapter->tx_send_failed); - seq_printf(seq, " RX: replenish task cycles: %ld\n", adapter->replenish_task_cycles); - seq_printf(seq, " alloc_skb_failures: %ld\n", adapter->replenish_no_mem); - seq_printf(seq, " add buffer failures: %ld\n", adapter->replenish_add_buff_failure); - seq_printf(seq, " invalid buffers: %ld\n", adapter->rx_invalid_buffer); - seq_printf(seq, " no buffers: %ld\n", adapter->rx_no_buffer); + seq_printf(seq, " TX: vio_map_single failres: %lld\n", adapter->tx_map_failed); + seq_printf(seq, " send failures: %lld\n", adapter->tx_send_failed); + seq_printf(seq, " RX: replenish task cycles: %lld\n", adapter->replenish_task_cycles); + seq_printf(seq, " alloc_skb_failures: %lld\n", adapter->replenish_no_mem); + seq_printf(seq, " add buffer failures: %lld\n", adapter->replenish_add_buff_failure); + seq_printf(seq, " invalid buffers: %lld\n", adapter->rx_invalid_buffer); + seq_printf(seq, " no buffers: %lld\n", adapter->rx_no_buffer); return 0; } diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index c7457f97259..cb793c2bade 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -429,7 +429,7 @@ SIMPLE_PORT_ATTR(promiscuous); SIMPLE_PORT_ATTR(num_mcast); CUSTOM_PORT_ATTR(lpar_map, "0x%X\n", port->lpar_map); CUSTOM_PORT_ATTR(stopped_map, "0x%X\n", port->stopped_map); -CUSTOM_PORT_ATTR(mac_addr, "0x%lX\n", port->mac_addr); +CUSTOM_PORT_ATTR(mac_addr, "0x%llX\n", port->mac_addr); #define GET_PORT_ATTR(_name) (&veth_port_attr_##_name.attr) static struct attribute *veth_port_default_attrs[] = { -- cgit v1.2.3 From 9fef3d2d15ae8ca24e4a145f2e189eea145d18c2 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 8 Jan 2009 02:14:18 +0000 Subject: hvc_console: Change an mb() to smp_mb() and add some comments I remember some history on this barrier. There was a race between open via /dev/console and the tty being fully setup. Its also why there is a temporary variable and the global is assigned at the end of the function. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 5a8a4c28c86..f2685b747fb 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -876,8 +876,11 @@ static int hvc_init(void) goto stop_thread; } - /* FIXME: This mb() seems completely random. Remove it. */ - mb(); + /* + * Make sure tty is fully registered before allowing it to be + * found by hvc_console_device. + */ + smp_mb(); hvc_driver = drv; return 0; -- cgit v1.2.3 From c21f7a527f7757a0e246cea521a5dd3b8e1224d5 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 8 Jan 2009 02:14:21 +0000 Subject: hvc_console: Call free_irq() only if request_irq() was successful Only call free_irq if we marked the request_irq has having succeeded instead of whenever the the sub-driver identified the interrupt to use. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/hvc_irq.c b/drivers/char/hvc_irq.c index d09e5688d44..2623e177e8d 100644 --- a/drivers/char/hvc_irq.c +++ b/drivers/char/hvc_irq.c @@ -37,7 +37,7 @@ int notifier_add_irq(struct hvc_struct *hp, int irq) void notifier_del_irq(struct hvc_struct *hp, int irq) { - if (!irq) + if (!hp->irq_requested) return; free_irq(irq, hp); hp->irq_requested = 0; -- cgit v1.2.3 From da9dc13289fa58dced12f2baff51dfb87c339ba3 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 8 Jan 2009 02:14:24 +0000 Subject: hvc_console: Do not set low_latency when using interrupts hvc_console is setting low_latency unconditionally, but some clients are interrupt driven and will call hvc_poll from irq context. This will cause tty_flip_buffer_push to be called from irq context, and it very clearly states it must not be called from IRQ when low_latency is specified. Looking back through history: v2.6.16-rc1 via 33f0f88f1c51ae5c2d593d26960c760ea154c2e2 [PATCH] TTY layer buffering revamp added this new api. v2.6.16-rc3 via 8977d929e49021d9a6e031310aab01fa72f849c2 [PATCH] tty buffering stall fix claims to fix a stall discovered with hvc_console v2.6.16-rc5 via fb5c594c2acc441f0d2d8f457484a0e0e9285db3 [PATCH] Fix race condition in hvc console. said set this flag to avoid a stall problem, and was merged through the powerpc arch tree. Without searching for email discussions, it would appear to be an overlapping "fix", but one that did not consider all users. Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index f2685b747fb..0e18fdb9ddd 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -318,7 +318,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) } /* else count == 0 */ tty->driver_data = hp; - tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ + if (!hp->irq_requested) + tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ hp->tty = tty; -- cgit v1.2.3 From 2da7582f7cf5ef5e6adcf42537b6b8be06312152 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 8 Jan 2009 02:14:28 +0000 Subject: hvc_console: Use kzalloc() instead of kmalloc() + memset() Replace kmalloc() + memset() with kzalloc(). Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 0e18fdb9ddd..09676b4e5d8 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -765,13 +765,11 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data, return ERR_PTR(err); } - hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size, + hp = kzalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size, GFP_KERNEL); if (!hp) return ERR_PTR(-ENOMEM); - memset(hp, 0x00, sizeof(*hp)); - hp->vtermno = vtermno; hp->data = data; hp->ops = ops; -- cgit v1.2.3 From fc7a9feb9c9df50ed6d115514b48c49e8511a4de Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 9 Jan 2009 13:12:44 +0000 Subject: powerpc/cacheinfo: Rename cache_dir per-cpu variable The per_cpu__ prefix on DECLARE_PER_CPU'd variables is going away; rename cache_dir to cache_dir_pcpu. Signed-off-by: Nathan Lynch Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/cacheinfo.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index b33f0417a4b..bb37b1d19a5 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -113,7 +113,7 @@ struct cache { struct cache *next_local; /* next cache of >= level */ }; -static DEFINE_PER_CPU(struct cache_dir *, cache_dir); +static DEFINE_PER_CPU(struct cache_dir *, cache_dir_pcpu); /* traversal/modification of this list occurs only at cpu hotplug time; * access is serialized by cpu hotplug locking @@ -468,9 +468,9 @@ static struct cache_dir *__cpuinit cacheinfo_create_cache_dir(unsigned int cpu_i cache_dir->kobj = kobj; - WARN_ON_ONCE(per_cpu(cache_dir, cpu_id) != NULL); + WARN_ON_ONCE(per_cpu(cache_dir_pcpu, cpu_id) != NULL); - per_cpu(cache_dir, cpu_id) = cache_dir; + per_cpu(cache_dir_pcpu, cpu_id) = cache_dir; return cache_dir; err: @@ -820,13 +820,13 @@ void cacheinfo_cpu_offline(unsigned int cpu_id) /* Prevent userspace from seeing inconsistent state - remove * the sysfs hierarchy first */ - cache_dir = per_cpu(cache_dir, cpu_id); + cache_dir = per_cpu(cache_dir_pcpu, cpu_id); /* careful, sysfs population may have failed */ if (cache_dir) remove_cache_dir(cache_dir); - per_cpu(cache_dir, cpu_id) = NULL; + per_cpu(cache_dir_pcpu, cpu_id) = NULL; /* clear the CPU's bit in its cache chain, possibly freeing * cache objects */ -- cgit v1.2.3 From c478b58135e6c9b49c8b80bff8ef910f2ba9b313 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 11 Jan 2009 19:03:45 +0000 Subject: powerpc/powermac: Fix occasional SMP boot failure The PowerMac kernel occasionally fails to bring up the secondary CPUs on SMP, the trigger factor seem to be fairly random and related to location of code and data. This appears to be due to the initial loading of the TOC value by the secondary processor which now happens before we clear HID4:RM_CI (Real Mode Cache Invalidate). This bit should really be cleared before we do any load or store other than fetching code. This fix works based on the assumption that all SMP 64-bit PowerMacs use variants of the 970, which fortunately is true, by explicitely clearing that bit, adding an slbia for good measure as RM_CI mode is known to create bogus ERAT entries. I also removed some spurrious debug output that was left enabled by mistake while at it. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_64.S | 9 +++++++++ arch/powerpc/platforms/powermac/smp.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index b4bcf5a930f..ebaedafc8e6 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1518,6 +1518,15 @@ _GLOBAL(pmac_secondary_start) /* turn on 64-bit mode */ bl .enable_64b_mode + li r0,0 + mfspr r3,SPRN_HID4 + rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ + sync + mtspr SPRN_HID4,r3 + isync + sync + slbia + /* get TOC pointer (real address) */ bl .relative_toc diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 6b0711c15ec..bd8817b00fa 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -53,7 +53,7 @@ #include #include -#define DEBUG +#undef DEBUG #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) -- cgit v1.2.3 From 061b908cf888c1bfd3dd1b91ce6f676e3bc42633 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 12 Jan 2009 16:30:00 +0000 Subject: powerpc: Enable PS3 options and QPACE in ppc64_defconfig To increase the amount of code that's built for a defconfig build. Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/configs/ppc64_defconfig | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 069ae1bbac2..d4685d1c0be 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -211,11 +211,28 @@ CONFIG_PPC_PASEMI=y CONFIG_PPC_PASEMI_IOMMU=y # CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set CONFIG_PPC_PASEMI_MDIO=y -# CONFIG_PPC_PS3 is not set +CONFIG_PPC_PS3=y + +# +# PS3 Platform Options +# +# CONFIG_PS3_ADVANCED is not set +CONFIG_PS3_HTAB_SIZE=20 +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_VUART=y +CONFIG_PS3_PS3AV=y +CONFIG_PS3_SYS_MANAGER=y +CONFIG_PS3_STORAGE=m +CONFIG_PS3_DISK=m +CONFIG_PS3_ROM=m +CONFIG_PS3_FLASH=m +CONFIG_PS3_LPM=m CONFIG_PPC_CELL=y +CONFIG_PPC_CELL_COMMON=y CONFIG_PPC_CELL_NATIVE=y CONFIG_PPC_IBM_CELL_BLADE=y CONFIG_PPC_CELLEB=y +CONFIG_PPC_CELL_QPACE=y # # Cell Broadband Engine options @@ -981,6 +998,9 @@ CONFIG_E1000=y CONFIG_TIGON3=y # CONFIG_BNX2 is not set CONFIG_SPIDER_NET=m +CONFIG_GELIC_NET=m +CONFIG_GELIC_WIRELESS=y +# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set # CONFIG_ATL1E is not set @@ -1370,6 +1390,8 @@ CONFIG_FB_RADEON_BACKLIGHT=y # CONFIG_FB_PM3 is not set # CONFIG_FB_CARMINE is not set CONFIG_FB_IBM_GXT4500=y +CONFIG_FB_PS3=m +CONFIG_FB_PS3_DEFAULT_SIZE_M=9 # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y @@ -1492,6 +1514,8 @@ CONFIG_SND_PCI=y CONFIG_SND_PPC=y CONFIG_SND_POWERMAC=m CONFIG_SND_POWERMAC_AUTO_DRC=y +CONFIG_SND_PS3=m +CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 CONFIG_SND_AOA=m CONFIG_SND_AOA_FABRIC_LAYOUT=m CONFIG_SND_AOA_ONYX=m -- cgit v1.2.3 From 5597b25c300eeaf43392f399990d3f3027a9b779 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 8 Jan 2009 18:11:56 -0600 Subject: powerpc/e500mc: Doorbells need to be taken w/exceptions disabled We use Doorbell interrupts for IPIs and thus we need to make sure we aren't interrupted in the process of processing the IPI. Signed-off-by: Kumar Gala Acked-by: Dave Liu --- arch/powerpc/kernel/head_fsl_booke.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 2f32720a44a..36ffb3504a4 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -707,7 +707,7 @@ interrupt_base: EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) #ifdef CONFIG_PPC_E500MC - EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_STD) #endif /* Debug Interrupt */ -- cgit v1.2.3 From 6c9789de2a02755101f757789ffcb17312f3fa9b Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sun, 11 Jan 2009 18:30:13 +0300 Subject: powerpc/83xx: Make serial ports work on MPC8315E-RDB w/ FSL U-Boots FSL U-Boots use /soc8315@e0000000 node to search and fixup serial nodes' clock-frequency properties. Though in upstream kernels we use new naming convention -- for IMMR address space dts files specify /immr@e0000000 nodes. This makes FSL U-Boots fail to fixup the clock frequencies, and that leads to serial ports misbehaviour. We can workaround the issue by filling the clock frequency values manually. p.s. For the same reason FSL U-Boots fail to fixup MAC addresses for ethernet nodes, so users should either change the .dts file locally or set MAC address via `ifconfig hw ether' command. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8315erdb.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 072c9b0f8c8..71784165b77 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -255,7 +255,7 @@ device_type = "serial"; compatible = "ns16550"; reg = <0x4500 0x100>; - clock-frequency = <0>; + clock-frequency = <133333333>; interrupts = <9 0x8>; interrupt-parent = <&ipic>; }; @@ -265,7 +265,7 @@ device_type = "serial"; compatible = "ns16550"; reg = <0x4600 0x100>; - clock-frequency = <0>; + clock-frequency = <133333333>; interrupts = <10 0x8>; interrupt-parent = <&ipic>; }; -- cgit v1.2.3 From ea0105ea3881b409e362451690184af494bce6e3 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sun, 11 Jan 2009 19:55:39 +0300 Subject: powerpc/83xx: Move mcu_mpc8349emitx driver out of drivers/i2c/chips/ This patch is used to help Jean Delvare to get rid of drivers/i2c/chips/ directory. The new location suggested by Kumar Gala: as the driver is 83xx specific it's placed into arch/powerpc/platforms/83xx/. Signed-off-by: Anton Vorontsov Acked-by: Jean Delvare Signed-off-by: Kumar Gala --- arch/powerpc/platforms/83xx/Makefile | 1 + arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | 209 +++++++++++++++++++++++++ arch/powerpc/platforms/Kconfig | 11 ++ drivers/i2c/chips/Kconfig | 11 -- drivers/i2c/chips/Makefile | 1 - drivers/i2c/chips/mcu_mpc8349emitx.c | 209 ------------------------- 6 files changed, 221 insertions(+), 221 deletions(-) create mode 100644 arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c delete mode 100644 drivers/i2c/chips/mcu_mpc8349emitx.c diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index ba5028e2989..051777c542c 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile @@ -3,6 +3,7 @@ # obj-y := misc.o usb.o obj-$(CONFIG_SUSPEND) += suspend.o suspend-asm.o +obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o obj-$(CONFIG_MPC831x_RDB) += mpc831x_rdb.o obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c new file mode 100644 index 00000000000..82a9bcb858b --- /dev/null +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -0,0 +1,209 @@ +/* + * Power Management and GPIO expander driver for MPC8349E-mITX-compatible MCU + * + * Copyright (c) 2008 MontaVista Software, Inc. + * + * Author: Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I don't have specifications for the MCU firmware, I found this register + * and bits positions by the trial&error method. + */ +#define MCU_REG_CTRL 0x20 +#define MCU_CTRL_POFF 0x40 + +#define MCU_NUM_GPIO 2 + +struct mcu { + struct mutex lock; + struct device_node *np; + struct i2c_client *client; + struct of_gpio_chip of_gc; + u8 reg_ctrl; +}; + +static struct mcu *glob_mcu; + +static void mcu_power_off(void) +{ + struct mcu *mcu = glob_mcu; + + pr_info("Sending power-off request to the MCU...\n"); + mutex_lock(&mcu->lock); + i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, + mcu->reg_ctrl | MCU_CTRL_POFF); + mutex_unlock(&mcu->lock); +} + +static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); + struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); + u8 bit = 1 << (4 + gpio); + + mutex_lock(&mcu->lock); + if (val) + mcu->reg_ctrl &= ~bit; + else + mcu->reg_ctrl |= bit; + + i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl); + mutex_unlock(&mcu->lock); +} + +static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + mcu_gpio_set(gc, gpio, val); + return 0; +} + +static int mcu_gpiochip_add(struct mcu *mcu) +{ + struct device_node *np; + struct of_gpio_chip *of_gc = &mcu->of_gc; + struct gpio_chip *gc = &of_gc->gc; + int ret; + + np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); + if (!np) + return -ENODEV; + + gc->owner = THIS_MODULE; + gc->label = np->full_name; + gc->can_sleep = 1; + gc->ngpio = MCU_NUM_GPIO; + gc->base = -1; + gc->set = mcu_gpio_set; + gc->direction_output = mcu_gpio_dir_out; + of_gc->gpio_cells = 2; + of_gc->xlate = of_gpio_simple_xlate; + + np->data = of_gc; + mcu->np = np; + + /* + * We don't want to lose the node, its ->data and ->full_name... + * So, if succeeded, we don't put the node here. + */ + ret = gpiochip_add(gc); + if (ret) + of_node_put(np); + return ret; +} + +static int mcu_gpiochip_remove(struct mcu *mcu) +{ + int ret; + + ret = gpiochip_remove(&mcu->of_gc.gc); + if (ret) + return ret; + of_node_put(mcu->np); + + return 0; +} + +static int __devinit mcu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct mcu *mcu; + int ret; + + mcu = kzalloc(sizeof(*mcu), GFP_KERNEL); + if (!mcu) + return -ENOMEM; + + mutex_init(&mcu->lock); + mcu->client = client; + i2c_set_clientdata(client, mcu); + + ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); + if (ret < 0) + goto err; + mcu->reg_ctrl = ret; + + ret = mcu_gpiochip_add(mcu); + if (ret) + goto err; + + /* XXX: this is potentially racy, but there is no lock for ppc_md */ + if (!ppc_md.power_off) { + glob_mcu = mcu; + ppc_md.power_off = mcu_power_off; + dev_info(&client->dev, "will provide power-off service\n"); + } + + return 0; +err: + kfree(mcu); + return ret; +} + +static int __devexit mcu_remove(struct i2c_client *client) +{ + struct mcu *mcu = i2c_get_clientdata(client); + int ret; + + if (glob_mcu == mcu) { + ppc_md.power_off = NULL; + glob_mcu = NULL; + } + + ret = mcu_gpiochip_remove(mcu); + if (ret) + return ret; + i2c_set_clientdata(client, NULL); + kfree(mcu); + return 0; +} + +static const struct i2c_device_id mcu_ids[] = { + { "mcu-mpc8349emitx", }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, mcu_ids); + +static struct i2c_driver mcu_driver = { + .driver = { + .name = "mcu-mpc8349emitx", + .owner = THIS_MODULE, + }, + .probe = mcu_probe, + .remove = __devexit_p(mcu_remove), + .id_table = mcu_ids, +}; + +static int __init mcu_init(void) +{ + return i2c_add_driver(&mcu_driver); +} +module_init(mcu_init); + +static void __exit mcu_exit(void) +{ + i2c_del_driver(&mcu_driver); +} +module_exit(mcu_exit); + +MODULE_DESCRIPTION("Power Management and GPIO expander driver for " + "MPC8349E-mITX-compatible MCU"); +MODULE_AUTHOR("Anton Vorontsov "); +MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 47fe2bea986..200b9cb900e 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -323,4 +323,15 @@ config SIMPLE_GPIO chip-selects, Ethernet/USB PHY's power and various other small on-board peripherals. +config MCU_MPC8349EMITX + tristate "MPC8349E-mITX MCU driver" + depends on I2C && PPC_83xx + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + help + Say Y here to enable soft power-off functionality on the Freescale + boards with the MPC8349E-mITX-compatible MCU chips. This driver will + also register MCU GPIOs with the generic GPIO API, so you'll able + to use MCU pins as GPIOs. + endmenu diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 59c3d23f5bd..b9bef04b7be 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -139,15 +139,4 @@ config SENSORS_TSL2550 This driver can also be built as a module. If so, the module will be called tsl2550. -config MCU_MPC8349EMITX - tristate "MPC8349E-mITX MCU driver" - depends on I2C && PPC_83xx - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Say Y here to enable soft power-off functionality on the Freescale - boards with the MPC8349E-mITX-compatible MCU chips. This driver will - also register MCU GPIOs with the generic GPIO API, so you'll able - to use MCU pins as GPIOs. - endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 83accaaf816..00fcb5193ac 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_PCF8575) += pcf8575.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o -obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/chips/mcu_mpc8349emitx.c b/drivers/i2c/chips/mcu_mpc8349emitx.c deleted file mode 100644 index 82a9bcb858b..00000000000 --- a/drivers/i2c/chips/mcu_mpc8349emitx.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Power Management and GPIO expander driver for MPC8349E-mITX-compatible MCU - * - * Copyright (c) 2008 MontaVista Software, Inc. - * - * Author: Anton Vorontsov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * I don't have specifications for the MCU firmware, I found this register - * and bits positions by the trial&error method. - */ -#define MCU_REG_CTRL 0x20 -#define MCU_CTRL_POFF 0x40 - -#define MCU_NUM_GPIO 2 - -struct mcu { - struct mutex lock; - struct device_node *np; - struct i2c_client *client; - struct of_gpio_chip of_gc; - u8 reg_ctrl; -}; - -static struct mcu *glob_mcu; - -static void mcu_power_off(void) -{ - struct mcu *mcu = glob_mcu; - - pr_info("Sending power-off request to the MCU...\n"); - mutex_lock(&mcu->lock); - i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL, - mcu->reg_ctrl | MCU_CTRL_POFF); - mutex_unlock(&mcu->lock); -} - -static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); - struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); - u8 bit = 1 << (4 + gpio); - - mutex_lock(&mcu->lock); - if (val) - mcu->reg_ctrl &= ~bit; - else - mcu->reg_ctrl |= bit; - - i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl); - mutex_unlock(&mcu->lock); -} - -static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -{ - mcu_gpio_set(gc, gpio, val); - return 0; -} - -static int mcu_gpiochip_add(struct mcu *mcu) -{ - struct device_node *np; - struct of_gpio_chip *of_gc = &mcu->of_gc; - struct gpio_chip *gc = &of_gc->gc; - int ret; - - np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); - if (!np) - return -ENODEV; - - gc->owner = THIS_MODULE; - gc->label = np->full_name; - gc->can_sleep = 1; - gc->ngpio = MCU_NUM_GPIO; - gc->base = -1; - gc->set = mcu_gpio_set; - gc->direction_output = mcu_gpio_dir_out; - of_gc->gpio_cells = 2; - of_gc->xlate = of_gpio_simple_xlate; - - np->data = of_gc; - mcu->np = np; - - /* - * We don't want to lose the node, its ->data and ->full_name... - * So, if succeeded, we don't put the node here. - */ - ret = gpiochip_add(gc); - if (ret) - of_node_put(np); - return ret; -} - -static int mcu_gpiochip_remove(struct mcu *mcu) -{ - int ret; - - ret = gpiochip_remove(&mcu->of_gc.gc); - if (ret) - return ret; - of_node_put(mcu->np); - - return 0; -} - -static int __devinit mcu_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct mcu *mcu; - int ret; - - mcu = kzalloc(sizeof(*mcu), GFP_KERNEL); - if (!mcu) - return -ENOMEM; - - mutex_init(&mcu->lock); - mcu->client = client; - i2c_set_clientdata(client, mcu); - - ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL); - if (ret < 0) - goto err; - mcu->reg_ctrl = ret; - - ret = mcu_gpiochip_add(mcu); - if (ret) - goto err; - - /* XXX: this is potentially racy, but there is no lock for ppc_md */ - if (!ppc_md.power_off) { - glob_mcu = mcu; - ppc_md.power_off = mcu_power_off; - dev_info(&client->dev, "will provide power-off service\n"); - } - - return 0; -err: - kfree(mcu); - return ret; -} - -static int __devexit mcu_remove(struct i2c_client *client) -{ - struct mcu *mcu = i2c_get_clientdata(client); - int ret; - - if (glob_mcu == mcu) { - ppc_md.power_off = NULL; - glob_mcu = NULL; - } - - ret = mcu_gpiochip_remove(mcu); - if (ret) - return ret; - i2c_set_clientdata(client, NULL); - kfree(mcu); - return 0; -} - -static const struct i2c_device_id mcu_ids[] = { - { "mcu-mpc8349emitx", }, - {}, -}; -MODULE_DEVICE_TABLE(i2c, mcu_ids); - -static struct i2c_driver mcu_driver = { - .driver = { - .name = "mcu-mpc8349emitx", - .owner = THIS_MODULE, - }, - .probe = mcu_probe, - .remove = __devexit_p(mcu_remove), - .id_table = mcu_ids, -}; - -static int __init mcu_init(void) -{ - return i2c_add_driver(&mcu_driver); -} -module_init(mcu_init); - -static void __exit mcu_exit(void) -{ - i2c_del_driver(&mcu_driver); -} -module_exit(mcu_exit); - -MODULE_DESCRIPTION("Power Management and GPIO expander driver for " - "MPC8349E-mITX-compatible MCU"); -MODULE_AUTHOR("Anton Vorontsov "); -MODULE_LICENSE("GPL"); -- cgit v1.2.3