From 339d3261aa3eb0e12f68ef868e042c1ca03628f7 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 6 Feb 2010 09:42:39 +0100 Subject: x86/amd-iommu: Remove double NULL check in check_device dev was tested just above, so drop the second test. Signed-off-by: Julia Lawall Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index adb0ba0..2c4a501 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -118,7 +118,7 @@ static bool check_device(struct device *dev) return false; /* No device or no PCI device */ - if (!dev || dev->bus != &pci_bus_type) + if (dev->bus != &pci_bus_type) return false; devid = get_device_id(dev); -- cgit v1.1 From 5d214fe6e808a8caa9cb6f610c0190d3f50ac570 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 8 Feb 2010 14:44:49 +0100 Subject: x86/amd-iommu: Protect IOMMU-API map/unmap path This patch introduces a mutex to lock page table updates in the IOMMU-API path. We can't use the spin_lock here because this patch might sleep. Signed-off-by: Joerg Roedel --- arch/x86/include/asm/amd_iommu_types.h | 2 ++ arch/x86/kernel/amd_iommu.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index ba19ad4..5e46e78 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h @@ -21,6 +21,7 @@ #define _ASM_X86_AMD_IOMMU_TYPES_H #include +#include #include #include @@ -237,6 +238,7 @@ struct protection_domain { struct list_head list; /* for list of all protection domains */ struct list_head dev_list; /* List of all devices in this domain */ spinlock_t lock; /* mostly used to lock the page table*/ + struct mutex api_lock; /* protect page tables in the iommu-api path */ u16 id; /* the domain id written to the device table */ int mode; /* paging mode (0-6 levels) */ u64 *pt_root; /* page table root pointer */ diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 2c4a501..b97f2f1 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2327,6 +2327,7 @@ static struct protection_domain *protection_domain_alloc(void) return NULL; spin_lock_init(&domain->lock); + mutex_init(&domain->api_lock); domain->id = domain_id_alloc(); if (!domain->id) goto out_err; @@ -2456,6 +2457,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom, iova &= PAGE_MASK; paddr &= PAGE_MASK; + mutex_lock(&domain->api_lock); + for (i = 0; i < npages; ++i) { ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k); if (ret) @@ -2465,6 +2468,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom, paddr += PAGE_SIZE; } + mutex_unlock(&domain->api_lock); + return 0; } @@ -2477,12 +2482,16 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom, iova &= PAGE_MASK; + mutex_lock(&domain->api_lock); + for (i = 0; i < npages; ++i) { iommu_unmap_page(domain, iova, PM_MAP_4k); iova += PAGE_SIZE; } iommu_flush_tlb_pde(domain); + + mutex_unlock(&domain->api_lock); } static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, -- cgit v1.1 From 04e856c072b84042bb56c487c2868638bb3f78db Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Wed, 17 Feb 2010 08:51:20 -0800 Subject: x86/amd-iommu: Pt mode fix for domain_destroy After a guest is shutdown, assigned devices are not properly returned to the pt domain. This can leave the device using stale cached IOMMU data, and result in a non-functional device after it's re-bound to the host driver. For example, I see this upon rebinding: AMD-Vi: Event logged [IO_PAGE_FAULT device=02:00.0 domain=0x0000 address=0x000000007e2a8000 flags=0x0050] AMD-Vi: Event logged [IO_PAGE_FAULT device=02:00.0 domain=0x0000 address=0x000000007e2a8040 flags=0x0050] AMD-Vi: Event logged [IO_PAGE_FAULT device=02:00.0 domain=0x0000 address=0x000000007e2a8080 flags=0x0050] AMD-Vi: Event logged [IO_PAGE_FAULT device=02:00.0 domain=0x0000 address=0x000000007e2a80c0 flags=0x0050] 0000:02:00.0: eth2: Detected Hardware Unit Hang: ... The amd_iommu_destroy_domain() function calls do_detach() which doesn't reattach the pt domain to the device. Use __detach_device() instead. Cc: stable@kernel.org Signed-off-by: Chris Wright Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index b97f2f1..0c04254 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2298,7 +2298,7 @@ static void cleanup_domain(struct protection_domain *domain) list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { struct device *dev = dev_data->dev; - do_detach(dev); + __detach_device(dev); atomic_set(&dev_data->bind, 0); } -- cgit v1.1 From 3551a708f35fc712af43aeb7f541512c5cfc4936 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 13:52:19 +0100 Subject: x86/amd-iommu: Report errors in acpi parsing functions upstream Since acpi_table_parse ignores the return values of the parsing function this patch introduces a workaround and reports these errors upstream via a global variable. Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu_init.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 9dc91b4..feaf471 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -138,9 +138,9 @@ int amd_iommus_present; bool amd_iommu_np_cache __read_mostly; /* - * Set to true if ACPI table parsing and hardware intialization went properly + * The ACPI table parsing functions set this variable on an error */ -static bool amd_iommu_initialized; +static int __initdata amd_iommu_init_err; /* * List of protection domains - used during resume @@ -391,9 +391,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table) */ for (i = 0; i < table->length; ++i) checksum += p[i]; - if (checksum != 0) + if (checksum != 0) { /* ACPI table corrupt */ - return -ENODEV; + amd_iommu_init_err = -ENODEV; + return 0; + } p += IVRS_HEADER_LENGTH; @@ -920,11 +922,16 @@ static int __init init_iommu_all(struct acpi_table_header *table) h->mmio_phys); iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); - if (iommu == NULL) - return -ENOMEM; + if (iommu == NULL) { + amd_iommu_init_err = -ENOMEM; + return 0; + } + ret = init_iommu_one(iommu, h); - if (ret) - return ret; + if (ret) { + amd_iommu_init_err = ret; + return 0; + } break; default: break; @@ -934,8 +941,6 @@ static int __init init_iommu_all(struct acpi_table_header *table) } WARN_ON(p != end); - amd_iommu_initialized = true; - return 0; } @@ -1211,6 +1216,10 @@ static int __init amd_iommu_init(void) if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0) return -ENODEV; + ret = amd_iommu_init_err; + if (ret) + goto out; + dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE); alias_table_size = tbl_size(ALIAS_TABLE_ENTRY_SIZE); rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE); @@ -1270,12 +1279,19 @@ static int __init amd_iommu_init(void) if (acpi_table_parse("IVRS", init_iommu_all) != 0) goto free; - if (!amd_iommu_initialized) + if (amd_iommu_init_err) { + ret = amd_iommu_init_err; goto free; + } if (acpi_table_parse("IVRS", init_memory_definitions) != 0) goto free; + if (amd_iommu_init_err) { + ret = amd_iommu_init_err; + goto free; + } + ret = sysdev_class_register(&amd_iommu_sysdev_class); if (ret) goto free; -- cgit v1.1 From 8b408fe4f853dcfa18d133aa4cf1d7546b4c3870 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 8 Mar 2010 14:20:07 +0100 Subject: x86/amd-iommu: Use helper function to destroy domain In the amd_iommu_domain_destroy the protection_domain_free function is partly reimplemented. The 'partly' is the bug here because the domain is not deleted from the domain list. This results in use-after-free errors and data-corruption. Fix it by just using protection_domain_free instead. Cc: stable@kernel.org Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 0c04254..b06f29e 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2380,9 +2380,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom) free_pagetable(domain); - domain_id_free(domain->id); - - kfree(domain); + protection_domain_free(domain); dom->priv = NULL; } -- cgit v1.1 From 48fae657f04924c06fe8c9afdb149efdd99d68dd Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 18 Mar 2010 16:55:45 +0100 Subject: i.MX51 Babbage: Add uncompress output Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/uncompress.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h index 52e476a..b6d3d0f 100644 --- a/arch/arm/plat-mxc/include/mach/uncompress.h +++ b/arch/arm/plat-mxc/include/mach/uncompress.h @@ -66,6 +66,7 @@ static inline void flush(void) #define MX2X_UART1_BASE_ADDR 0x1000a000 #define MX3X_UART1_BASE_ADDR 0x43F90000 #define MX3X_UART2_BASE_ADDR 0x43F94000 +#define MX51_UART1_BASE_ADDR 0x73fbc000 static __inline__ void __arch_decomp_setup(unsigned long arch_id) { @@ -101,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) case MACH_TYPE_MAGX_ZN5: uart_base = MX3X_UART2_BASE_ADDR; break; + case MACH_TYPE_MX51_BABBAGE: + uart_base = MX51_UART1_BASE_ADDR; + break; default: break; } -- cgit v1.1 From 1b6a2b2d0ff2ced5fe608e0b2e13ccd2b7a283e5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 18 Mar 2010 16:56:11 +0100 Subject: i.MX51: Use correct clock for gpt The gpt uses the ipg clock, not ipg_perclk Signed-off-by: Sascha Hauer --- arch/arm/mach-mx5/clock-mx51.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index be90c03..8f85f73 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -757,7 +757,7 @@ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET, /* GPT */ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, - NULL, NULL, &ipg_perclk, NULL); + NULL, NULL, &ipg_clk, NULL); DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); -- cgit v1.1 From 3d1bc8626c7b17facfcb7fb5dee4686f47a1e75d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 18 Mar 2010 16:56:30 +0100 Subject: i.MX51: map TZIC dynamically This looks cleaner and allows us to call mx51_revision later when we can use ioremap to determine the silicon revision dynamically. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx5/mm.c | 27 +++++++++++++-------------- arch/arm/plat-mxc/include/mach/mx51.h | 11 +++-------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index c21e18b..9fe7beb 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -35,11 +35,6 @@ static struct map_desc mxc_io_desc[] __initdata = { .length = MX51_DEBUG_SIZE, .type = MT_DEVICE }, { - .virtual = MX51_TZIC_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR), - .length = MX51_TZIC_SIZE, - .type = MT_DEVICE - }, { .virtual = MX51_AIPS1_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR), .length = MX51_AIPS1_SIZE, @@ -69,14 +64,6 @@ static struct map_desc mxc_io_desc[] __initdata = { */ void __init mx51_map_io(void) { - u32 tzic_addr; - - if (mx51_revision() < MX51_CHIP_REV_2_0) - tzic_addr = 0x8FFFC000; - else - tzic_addr = 0xE0003000; - mxc_io_desc[2].pfn = __phys_to_pfn(tzic_addr); - mxc_set_cpu_type(MXC_CPU_MX51); mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR)); @@ -85,5 +72,17 @@ void __init mx51_map_io(void) void __init mx51_init_irq(void) { - tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR)); + unsigned long tzic_addr; + void __iomem *tzic_virt; + + if (mx51_revision() < MX51_CHIP_REV_2_0) + tzic_addr = MX51_TZIC_BASE_ADDR_TO1; + else + tzic_addr = MX51_TZIC_BASE_ADDR; + + tzic_virt = ioremap(tzic_addr, SZ_16K); + if (!tzic_virt) + panic("unable to map TZIC interrupt controller\n"); + + tzic_init_irq(tzic_virt); } diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index 771532b..f1396bd 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -14,7 +14,7 @@ * FB100000 70000000 1M SPBA 0 * FB000000 73F00000 1M AIPS 1 * FB200000 83F00000 1M AIPS 2 - * FA100000 8FFFC000 16K TZIC (interrupt controller) + * 8FFFC000 16K TZIC (interrupt controller) * 90000000 256M CSD0 SDRAM/DDR * A0000000 256M CSD1 SDRAM/DDR * B0000000 128M CS0 Flash @@ -49,9 +49,8 @@ #define MX51_GPU_BASE_ADDR 0x20000000 #define MX51_GPU2D_BASE_ADDR 0xD0000000 -#define MX51_TZIC_BASE_ADDR 0x8FFFC000 -#define MX51_TZIC_BASE_ADDR_VIRT 0xFA100000 -#define MX51_TZIC_SIZE SZ_16K +#define MX51_TZIC_BASE_ADDR_TO1 0x8FFFC000 +#define MX51_TZIC_BASE_ADDR 0xE0000000 #define MX51_DEBUG_BASE_ADDR 0x60000000 #define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000 @@ -232,7 +231,6 @@ #define MX51_IO_ADDRESS(x) \ (void __iomem *) \ (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \ @@ -246,9 +244,6 @@ #define MX51_IRAM_IO_ADDRESS(x) \ (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT) -#define MX51_TZIC_IO_ADDRESS(x) \ - (((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT) - #define MX51_DEBUG_IO_ADDRESS(x) \ (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT) -- cgit v1.1 From 5443856cadac7faaaeefeed9d769f497a8c6fa4b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 19 Mar 2010 10:50:55 +0100 Subject: i.MX51: determine silicon revision dynamically Freescale redboot passes the silicon revision via ATAG_REVISION. Remove this bootloader dependency by doing the same as redboot does in the Kernel. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx5/cpu.c | 53 +++++++++++++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/mx51.h | 13 +++++---- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c index 41c769f..2d37785 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c @@ -14,9 +14,62 @@ #include #include #include +#include #include #include +static int cpu_silicon_rev = -1; + +#define SI_REV 0x48 + +static void query_silicon_parameter(void) +{ + void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE); + u32 rev; + + if (!rom) { + cpu_silicon_rev = -EINVAL; + return; + } + + rev = readl(rom + SI_REV); + switch (rev) { + case 0x1: + cpu_silicon_rev = MX51_CHIP_REV_1_0; + break; + case 0x2: + cpu_silicon_rev = MX51_CHIP_REV_1_1; + break; + case 0x10: + cpu_silicon_rev = MX51_CHIP_REV_2_0; + break; + case 0x20: + cpu_silicon_rev = MX51_CHIP_REV_3_0; + break; + default: + cpu_silicon_rev = 0; + } + + iounmap(rom); +} + +/* + * Returns: + * the silicon revision of the cpu + * -EINVAL - not a mx51 + */ +int mx51_revision(void) +{ + if (!cpu_is_mx51()) + return -EINVAL; + + if (cpu_silicon_rev == -1) + query_silicon_parameter(); + + return cpu_silicon_rev; +} +EXPORT_SYMBOL(mx51_revision); + static int __init post_cpu_init(void) { unsigned int reg; diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index f1396bd..fd255a9 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -28,6 +28,12 @@ */ /* + * IROM + */ +#define MX51_IROM_BASE_ADDR 0x0 +#define MX51_IROM_SIZE SZ_64K + +/* * IRAM */ #define MX51_IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */ @@ -438,12 +444,7 @@ #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) -extern unsigned int system_rev; - -static inline unsigned int mx51_revision(void) -{ - return system_rev; -} +extern int mx51_revision(void); #endif #endif /* __ASM_ARCH_MXC_MX51_H__ */ -- cgit v1.1 From fc300206ad07e771ed003d35b1dc179eaf0c508f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 19 Mar 2010 11:12:02 +0100 Subject: i.MX51: remove NFC AXI static mapping This area contains the Nand Flash controller registers. There is no need to map them statically as the Nand driver uses ioremap(). Signed-off-by: Sascha Hauer --- arch/arm/mach-mx5/mm.c | 5 ----- arch/arm/plat-mxc/include/mach/mx51.h | 9 ++------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index 9fe7beb..b7677ef 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -49,11 +49,6 @@ static struct map_desc mxc_io_desc[] __initdata = { .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR), .length = MX51_AIPS2_SIZE, .type = MT_DEVICE - }, { - .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR), - .length = MX51_NFC_AXI_SIZE, - .type = MT_DEVICE }, }; diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index fd255a9..5aad344 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -23,7 +23,7 @@ * C8000000 64M CS3 Flash * CC000000 32M CS4 SRAM * CE000000 32M CS5 SRAM - * F9000000 CFFF0000 64K NFC (NAND Flash AXI) + * CFFF0000 64K NFC (NAND Flash AXI) * */ @@ -46,7 +46,6 @@ * NFC */ #define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */ -#define MX51_NFC_AXI_BASE_ADDR_VIRT 0xF9000000 #define MX51_NFC_AXI_SIZE SZ_64K /* @@ -240,8 +239,7 @@ MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \ + MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \ 0xDEADBEEF) /* @@ -262,9 +260,6 @@ #define MX51_AIPS2_IO_ADDRESS(x) \ (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT) -#define MX51_NFC_AXI_IO_ADDRESS(x) \ - (((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT) - #define MX51_IS_MEM_DEVICE_NONSHARED(x) 0 /* -- cgit v1.1 From 88fcf710c13bd41f2b98c5411e4f21ab98da4fb4 Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Fri, 19 Mar 2010 23:02:16 -0700 Subject: Input: sparse-keymap - free the right keymap on error 'map' is allocated in sparse_keymap_setup() and it it the one that should be freed on error instead of 'keymap'. Signed-off-by: Yong Wang Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/sparse-keymap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index e6bde55..f64e004 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -163,7 +163,7 @@ int sparse_keymap_setup(struct input_dev *dev, return 0; err_out: - kfree(keymap); + kfree(map); return error; } -- cgit v1.1 From d90e6f6aad0ffdc674bc3a05c85c40dcc18e604c Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 20 Mar 2010 00:06:40 -0700 Subject: Input: bcm5974 - retract efi-broken suspend_resume With the recent system-wide improvements on suspend/resume and EFI booting the suspend_resume method of the bcm5974 has broken. When waking up from the S3 state on the MacBookAir, the trackpad is found in a yet unknown state, unable to switch to the proper multitouch mode. The result is a frozen touchpad, and a flood of errors of the kind bcm5974: bad trackpad package, length: 8. This patch retracts the reset_resume method altogether, falling back on the generic unbind/rebind functionality of the usb layer until further investigations can be made as how to reset the device when booting from efi. Signed-off-by: Henrik Rydberg Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/bcm5974.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 4f8fe08..b89879b 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = { .disconnect = bcm5974_disconnect, .suspend = bcm5974_suspend, .resume = bcm5974_resume, - .reset_resume = bcm5974_resume, .id_table = bcm5974_table, .supports_autosuspend = 1, }; -- cgit v1.1 From 97065e033ec5fd824d0133ecd0c614fe1e5c20bd Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 21 Mar 2010 22:31:26 -0700 Subject: Input: clarify the no-finger event in multitouch protocol The current documentation does not explicitly specify how to report zero fingers, leaving a potential problem in the driver implementations and giving no parsing directive to userland. This patch defines two equally valid ways. Signed-off-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- Documentation/input/multi-touch-protocol.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt index 8490480..eacb226 100644 --- a/Documentation/input/multi-touch-protocol.txt +++ b/Documentation/input/multi-touch-protocol.txt @@ -68,6 +68,22 @@ like: SYN_MT_REPORT SYN_REPORT +Here is the sequence after lifting one of the fingers: + + ABS_MT_POSITION_X + ABS_MT_POSITION_Y + SYN_MT_REPORT + SYN_REPORT + +And here is the sequence after lifting the remaining finger: + + SYN_MT_REPORT + SYN_REPORT + +If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the +ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the +last SYN_REPORT will be dropped by the input core, resulting in no +zero-finger event reaching userland. Event Semantics --------------- -- cgit v1.1 From 13bad37b04c779d98983307a27f97e9caa36f9b1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 21 Mar 2010 22:31:26 -0700 Subject: Input: update the status of the Multitouch X driver project The Multitouch X driver project has moved to alpha status. This patch updates the documentation accordingly. Signed-off-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- Documentation/input/multi-touch-protocol.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt index eacb226..c0fc1c7 100644 --- a/Documentation/input/multi-touch-protocol.txt +++ b/Documentation/input/multi-touch-protocol.txt @@ -233,11 +233,6 @@ where examples can be found. difference between the contact position and the approaching tool position could be used to derive tilt. [2] The list can of course be extended. -[3] The multi-touch X driver is currently in the prototyping stage. At the -time of writing (April 2009), the MT protocol is not yet merged, and the -prototype implements finger matching, basic mouse support and two-finger -scrolling. The project aims at improving the quality of current multi-touch -functionality available in the Synaptics X driver, and in addition -implement more advanced gestures. +[3] Multitouch X driver project: http://bitmath.org/code/multitouch/. [4] See the section on event computation. [5] See the section on finger tracking. -- cgit v1.1 From 2e2e3b96d98d5c17e9c09bc6088df3e182a71814 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 21 Mar 2010 22:56:15 -0700 Subject: Input: sparse-keymap - implement safer freeing of the keymap Allow calling sparse_keymap_free() before unregistering input device whithout risk of racing with EVIOCGETKEYCODE and EVIOCSETKEYCODE. This makes life of drivers writers easier. Acked-by: Yong Wang Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 9 +++++++- drivers/input/sparse-keymap.c | 50 +++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index e2aad0a..be18fa9 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -659,7 +659,14 @@ static int input_default_setkeycode(struct input_dev *dev, int input_get_keycode(struct input_dev *dev, unsigned int scancode, unsigned int *keycode) { - return dev->getkeycode(dev, scancode, keycode); + unsigned long flags; + int retval; + + spin_lock_irqsave(&dev->event_lock, flags); + retval = dev->getkeycode(dev, scancode, keycode); + spin_unlock_irqrestore(&dev->event_lock, flags); + + return retval; } EXPORT_SYMBOL(input_get_keycode); diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index f64e004..2434ac5 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -67,12 +67,14 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, unsigned int scancode, unsigned int *keycode) { - const struct key_entry *key = - sparse_keymap_entry_from_scancode(dev, scancode); + const struct key_entry *key; - if (key && key->type == KE_KEY) { - *keycode = key->keycode; - return 0; + if (dev->keycode) { + key = sparse_keymap_entry_from_scancode(dev, scancode); + if (key && key->type == KE_KEY) { + *keycode = key->keycode; + return 0; + } } return -EINVAL; @@ -85,17 +87,16 @@ static int sparse_keymap_setkeycode(struct input_dev *dev, struct key_entry *key; int old_keycode; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - - key = sparse_keymap_entry_from_scancode(dev, scancode); - if (key && key->type == KE_KEY) { - old_keycode = key->keycode; - key->keycode = keycode; - set_bit(keycode, dev->keybit); - if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) - clear_bit(old_keycode, dev->keybit); - return 0; + if (dev->keycode) { + key = sparse_keymap_entry_from_scancode(dev, scancode); + if (key && key->type == KE_KEY) { + old_keycode = key->keycode; + key->keycode = keycode; + set_bit(keycode, dev->keybit); + if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) + clear_bit(old_keycode, dev->keybit); + return 0; + } } return -EINVAL; @@ -175,14 +176,27 @@ EXPORT_SYMBOL(sparse_keymap_setup); * * This function is used to free memory allocated by sparse keymap * in an input device that was set up by sparse_keymap_setup(). + * NOTE: It is safe to cal this function while input device is + * still registered (however the drivers should care not to try to + * use freed keymap and thus have to shut off interrups/polling + * before freeing the keymap). */ void sparse_keymap_free(struct input_dev *dev) { + unsigned long flags; + + /* + * Take event lock to prevent racing with input_get_keycode() + * and input_set_keycode() if we are called while input device + * is still registered. + */ + spin_lock_irqsave(&dev->event_lock, flags); + kfree(dev->keycode); dev->keycode = NULL; dev->keycodemax = 0; - dev->getkeycode = NULL; - dev->setkeycode = NULL; + + spin_unlock_irqrestore(&dev->event_lock, flags); } EXPORT_SYMBOL(sparse_keymap_free); -- cgit v1.1 From 157f1071354db1aed885816094888e0e257c9d0a Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Thu, 11 Feb 2010 07:10:38 -0600 Subject: eCryptfs: Fix metadata in xattr feature regression Fixes regression in 8faece5f906725c10e7a1f6caf84452abadbdc7b When using the ecryptfs_xattr_metadata mount option, eCryptfs stores the metadata (normally stored at the front of the file) in the user.ecryptfs xattr. This causes ecryptfs_crypt_stat.num_header_bytes_at_front to be 0, since there is no header data at the front of the file. This results in too much memory being requested and ENOMEM being returned from ecryptfs_write_metadata(). This patch fixes the problem by using the num_header_bytes_at_front variable for specifying the max size of the metadata, despite whether it is stored in the header or xattr. Reviewed-by: Eric Sandeen Signed-off-by: Tyler Hicks --- fs/ecryptfs/crypto.c | 7 ++++--- fs/ecryptfs/ecryptfs_kernel.h | 8 ++++++++ fs/ecryptfs/inode.c | 2 +- fs/ecryptfs/mmap.c | 19 +++++-------------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 7cb0a59..c907f6f 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -381,8 +381,8 @@ out: static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, struct ecryptfs_crypt_stat *crypt_stat) { - (*offset) = (crypt_stat->num_header_bytes_at_front - + (crypt_stat->extent_size * extent_num)); + (*offset) = ecryptfs_lower_header_size(crypt_stat) + + (crypt_stat->extent_size * extent_num); } /** @@ -834,7 +834,8 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) set_extent_mask_and_shift(crypt_stat); crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) - crypt_stat->num_header_bytes_at_front = 0; + crypt_stat->num_header_bytes_at_front = + ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; else { if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) crypt_stat->num_header_bytes_at_front = diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 542f625..8456f70 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -464,6 +464,14 @@ struct ecryptfs_daemon { extern struct mutex ecryptfs_daemon_hash_mux; +static inline size_t +ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat) +{ + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) + return 0; + return crypt_stat->num_header_bytes_at_front; +} + static inline struct ecryptfs_file_info * ecryptfs_file_to_private(struct file *file) { diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 4a430ab..1a73953 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -768,7 +768,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, { loff_t lower_size; - lower_size = crypt_stat->num_header_bytes_at_front; + lower_size = ecryptfs_lower_header_size(crypt_stat); if (upper_size != 0) { loff_t num_extents; diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index df4ce99d..5a30e01 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -97,19 +97,6 @@ out: * (big-endian) * Octet 26: Begin RFC 2440 authentication token packet set */ -static void set_header_info(char *page_virt, - struct ecryptfs_crypt_stat *crypt_stat) -{ - size_t written; - size_t save_num_header_bytes_at_front = - crypt_stat->num_header_bytes_at_front; - - crypt_stat->num_header_bytes_at_front = - ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; - ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); - crypt_stat->num_header_bytes_at_front = - save_num_header_bytes_at_front; -} /** * ecryptfs_copy_up_encrypted_with_header @@ -146,9 +133,13 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, memset(page_virt, 0, PAGE_CACHE_SIZE); /* TODO: Support more than one header extent */ if (view_extent_num == 0) { + size_t written; + rc = ecryptfs_read_xattr_region( page_virt, page->mapping->host); - set_header_info(page_virt, crypt_stat); + ecryptfs_write_header_metadata(page_virt + 20, + crypt_stat, + &written); } kunmap_atomic(page_virt, KM_USER0); flush_dcache_page(page); -- cgit v1.1 From fa3ef1cb4e6e9958a9bfaa977c107c515907f102 Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Thu, 11 Feb 2010 05:09:14 -0600 Subject: eCryptfs: Rename ecryptfs_crypt_stat.num_header_bytes_at_front This patch renames the num_header_bytes_at_front variable to metadata_size since it now contains the max size of the metadata. Reviewed-by: Eric Sandeen Signed-off-by: Tyler Hicks --- fs/ecryptfs/crypto.c | 24 ++++++++++-------------- fs/ecryptfs/ecryptfs_kernel.h | 4 ++-- fs/ecryptfs/inode.c | 2 +- fs/ecryptfs/mmap.c | 5 ++--- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index c907f6f..391f558 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -834,14 +834,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) set_extent_mask_and_shift(crypt_stat); crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) - crypt_stat->num_header_bytes_at_front = - ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; + crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; else { if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) - crypt_stat->num_header_bytes_at_front = + crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; else - crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE; + crypt_stat->metadata_size = PAGE_CACHE_SIZE; } } @@ -1238,8 +1237,7 @@ ecryptfs_write_header_metadata(char *virt, header_extent_size = (u32)crypt_stat->extent_size; num_header_extents_at_front = - (u16)(crypt_stat->num_header_bytes_at_front - / crypt_stat->extent_size); + (u16)(crypt_stat->metadata_size / crypt_stat->extent_size); put_unaligned_be32(header_extent_size, virt); virt += 4; put_unaligned_be16(num_header_extents_at_front, virt); @@ -1382,7 +1380,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) rc = -EINVAL; goto out; } - virt_len = crypt_stat->num_header_bytes_at_front; + virt_len = crypt_stat->metadata_size; order = get_order(virt_len); /* Released in this function */ virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); @@ -1428,16 +1426,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, header_extent_size = get_unaligned_be32(virt); virt += sizeof(__be32); num_header_extents_at_front = get_unaligned_be16(virt); - crypt_stat->num_header_bytes_at_front = - (((size_t)num_header_extents_at_front - * (size_t)header_extent_size)); + crypt_stat->metadata_size = (((size_t)num_header_extents_at_front + * (size_t)header_extent_size)); (*bytes_read) = (sizeof(__be32) + sizeof(__be16)); if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) - && (crypt_stat->num_header_bytes_at_front + && (crypt_stat->metadata_size < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { rc = -EINVAL; printk(KERN_WARNING "Invalid header size: [%zd]\n", - crypt_stat->num_header_bytes_at_front); + crypt_stat->metadata_size); } return rc; } @@ -1452,8 +1449,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, */ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) { - crypt_stat->num_header_bytes_at_front = - ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; + crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; } /** diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 8456f70..d031efd 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -273,7 +273,7 @@ struct ecryptfs_crypt_stat { u32 flags; unsigned int file_version; size_t iv_bytes; - size_t num_header_bytes_at_front; + size_t metadata_size; size_t extent_size; /* Data extent size; default is 4096 */ size_t key_size; size_t extent_shift; @@ -469,7 +469,7 @@ ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) return 0; - return crypt_stat->num_header_bytes_at_front; + return crypt_stat->metadata_size; } static inline struct ecryptfs_file_info * diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 1a73953..a50efb1 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -335,7 +335,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, ecryptfs_dentry->d_sb)->mount_crypt_stat; if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) - file_size = (crypt_stat->num_header_bytes_at_front + file_size = (crypt_stat->metadata_size + i_size_read(lower_dentry->d_inode)); else file_size = i_size_read(lower_dentry->d_inode); diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 5a30e01..270f42a 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -122,8 +122,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, * num_extents_per_page) + extent_num_in_page); size_t num_header_extents_at_front = - (crypt_stat->num_header_bytes_at_front - / crypt_stat->extent_size); + (crypt_stat->metadata_size / crypt_stat->extent_size); if (view_extent_num < num_header_extents_at_front) { /* This is a header extent */ @@ -152,7 +151,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, /* This is an encrypted data extent */ loff_t lower_offset = ((view_extent_num * crypt_stat->extent_size) - - crypt_stat->num_header_bytes_at_front); + - crypt_stat->metadata_size); rc = ecryptfs_read_lower_page_segment( page, (lower_offset >> PAGE_CACHE_SHIFT), -- cgit v1.1 From 1984c23f9e0cdb432d90a85ecf88b424d36878fc Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Wed, 10 Feb 2010 23:17:44 -0600 Subject: eCryptfs: Clear buffer before reading in metadata xattr We initially read in the first PAGE_CACHE_SIZE of a file to if the eCryptfs header marker can be found. If it isn't found and ecryptfs_xattr_metadata was given as a mount option, then the user.ecryptfs xattr is read into the same buffer. Since the data from the first page of the file wasn't cleared, it is possible that we think we've found a second tag 3 or tag 1 packet and then error out after the packet contents aren't as expected. This patch clears the buffer before filling it with metadata from the user.ecryptfs xattr. Reviewed-by: Eric Sandeen Signed-off-by: Tyler Hicks --- fs/ecryptfs/crypto.c | 1 + fs/ecryptfs/inode.c | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 391f558..4d9db0e 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -1603,6 +1603,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) ecryptfs_dentry, ECRYPTFS_VALIDATE_HEADER_SIZE); if (rc) { + memset(page_virt, 0, PAGE_CACHE_SIZE); rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); if (rc) { printk(KERN_DEBUG "Valid eCryptfs headers not found in " diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index a50efb1..ddbd096 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -323,6 +323,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, rc = ecryptfs_read_and_validate_header_region(page_virt, ecryptfs_dentry->d_inode); if (rc) { + memset(page_virt, 0, PAGE_CACHE_SIZE); rc = ecryptfs_read_and_validate_xattr_region(page_virt, ecryptfs_dentry); if (rc) { -- cgit v1.1 From f4e60e6b303bc46cdc477d3174dbf9cb5dd013aa Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Thu, 11 Feb 2010 00:02:32 -0600 Subject: eCryptfs: Strip metadata in xattr flag in encrypted view The ecryptfs_encrypted_view mount option provides a unified way of viewing encrypted eCryptfs files. If the metadata is stored in a xattr, the metadata is moved to the file header when the file is read inside the eCryptfs mount. Because of this, we should strip the ECRYPTFS_METADATA_IN_XATTR flag from the header's flag section. This allows eCryptfs to treat the file as an eCryptfs file with a header at the front. Reviewed-by: Eric Sandeen Signed-off-by: Tyler Hicks --- fs/ecryptfs/crypto.c | 9 +++++---- fs/ecryptfs/ecryptfs_kernel.h | 3 +++ fs/ecryptfs/mmap.c | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 4d9db0e..fad5bf6 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -1107,9 +1107,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written) (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; } -static void -write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, - size_t *written) +void ecryptfs_write_crypt_stat_flags(char *page_virt, + struct ecryptfs_crypt_stat *crypt_stat, + size_t *written) { u32 flags = 0; int i; @@ -1290,7 +1290,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max, offset = ECRYPTFS_FILE_SIZE_BYTES; write_ecryptfs_marker((page_virt + offset), &written); offset += written; - write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); + ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat, + &written); offset += written; ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, &written); diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index d031efd..bc71154 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -659,6 +659,9 @@ int ecryptfs_decrypt_page(struct page *page); int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); +void ecryptfs_write_crypt_stat_flags(char *page_virt, + struct ecryptfs_crypt_stat *crypt_stat, + size_t *written); int ecryptfs_read_and_validate_header_region(char *data, struct inode *ecryptfs_inode); int ecryptfs_read_and_validate_xattr_region(char *page_virt, diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 270f42a..bea998a 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -82,6 +82,19 @@ out: return rc; } +static void strip_xattr_flag(char *page_virt, + struct ecryptfs_crypt_stat *crypt_stat) +{ + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { + size_t written; + + crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR; + ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat, + &written); + crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; + } +} + /** * Header Extent: * Octets 0-7: Unencrypted file size (big-endian) @@ -136,6 +149,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, rc = ecryptfs_read_xattr_region( page_virt, page->mapping->host); + strip_xattr_flag(page_virt + 16, crypt_stat); ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); -- cgit v1.1 From 6dc2d6bf5148a9ed027af21285b0e17b83b3a8f4 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 24 Mar 2010 14:32:16 +0300 Subject: imx31: fix parent clock for rtc According to imx31 reference manual the signal from external low frequency clock is sent to RTC clock. The patch makes redundant the previously defined mxc_rtc clock. Signed-off-by: Vladimir Zapolskiy Cc: Sascha Hauer Cc: Daniel Mack Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/clock-imx31.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c index 80dba99..9a9eb6d 100644 --- a/arch/arm/mach-mx3/clock-imx31.c +++ b/arch/arm/mach-mx3/clock-imx31.c @@ -468,6 +468,7 @@ static struct clk ahb_clk = { } DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); @@ -490,7 +491,7 @@ DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk); -DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk); DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); @@ -514,7 +515,6 @@ DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk) DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); -DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); #define _REGISTER_CLOCK(d, n, c) \ { \ @@ -572,7 +572,6 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "iim", iim_clk) _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) _REGISTER_CLOCK(NULL, "mbx", mbx_clk) - _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk) }; int __init mx31_clocks_init(unsigned long fref) -- cgit v1.1 From 11a332adfeacee2634f73ad21b55aad5cc7fd54a Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 23 Mar 2010 19:46:57 +0100 Subject: MXC: mach-mx31_3ds: Update variable names over recent mach name modification. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/mach-mx31_3ds.c | 38 ++++++++-------- arch/arm/plat-mxc/include/mach/board-mx31_3ds.h | 59 +++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/board-mx31pdk.h | 59 ------------------------- 3 files changed, 78 insertions(+), 78 deletions(-) create mode 100644 arch/arm/plat-mxc/include/mach/board-mx31_3ds.h delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx31pdk.h diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index b88c18a..4a94c3c 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -31,20 +31,20 @@ #include #include #include -#include +#include #include #include #include "devices.h" /*! - * @file mx31pdk.c + * @file mx31_3ds.c * * @brief This file contains the board-specific initialization routines. * * @ingroup System */ -static int mx31pdk_pins[] = { +static int mx31_3ds_pins[] = { /* UART1 */ MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1, @@ -95,7 +95,7 @@ static struct platform_device smsc911x_device = { * LEDs, switches, interrupts for Ethernet. */ -static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc) +static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc) { uint32_t imr_val; uint32_t int_valid; @@ -163,7 +163,7 @@ static struct irq_chip expio_irq_chip = { .unmask = expio_unmask_irq, }; -static int __init mx31pdk_init_expio(void) +static int __init mx31_3ds_init_expio(void) { int i; int ret; @@ -176,7 +176,7 @@ static int __init mx31pdk_init_expio(void) return -ENODEV; } - pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n", + pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n", __raw_readw(CPLD_CODE_VER_REG)); /* @@ -201,7 +201,7 @@ static int __init mx31pdk_init_expio(void) set_irq_flags(i, IRQF_VALID); } set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW); - set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler); + set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler); return 0; } @@ -209,7 +209,7 @@ static int __init mx31pdk_init_expio(void) /* * This structure defines the MX31 memory map. */ -static struct map_desc mx31pdk_io_desc[] __initdata = { +static struct map_desc mx31_3ds_io_desc[] __initdata = { { .virtual = MX31_CS5_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR), @@ -221,10 +221,10 @@ static struct map_desc mx31pdk_io_desc[] __initdata = { /* * Set up static virtual mappings. */ -static void __init mx31pdk_map_io(void) +static void __init mx31_3ds_map_io(void) { mx31_map_io(); - iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc)); + iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc)); } /*! @@ -232,35 +232,35 @@ static void __init mx31pdk_map_io(void) */ static void __init mxc_board_init(void) { - mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins), - "mx31pdk"); + mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), + "mx31_3ds"); mxc_register_device(&mxc_uart_device0, &uart_pdata); - if (!mx31pdk_init_expio()) + if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); } -static void __init mx31pdk_timer_init(void) +static void __init mx31_3ds_timer_init(void) { mx31_clocks_init(26000000); } -static struct sys_timer mx31pdk_timer = { - .init = mx31pdk_timer_init, +static struct sys_timer mx31_3ds_timer = { + .init = mx31_3ds_timer_init, }; /* * The following uses standard kernel macros defined in arch.h in order to - * initialize __mach_desc_MX31PDK data structure. + * initialize __mach_desc_MX31_3DS data structure. */ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") /* Maintainer: Freescale Semiconductor, Inc. */ .phys_io = MX31_AIPS1_BASE_ADDR, .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc, .boot_params = MX3x_PHYS_OFFSET + 0x100, - .map_io = mx31pdk_map_io, + .map_io = mx31_3ds_map_io, .init_irq = mx31_init_irq, .init_machine = mxc_board_init, - .timer = &mx31pdk_timer, + .timer = &mx31_3ds_timer, MACHINE_END diff --git a/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h new file mode 100644 index 0000000..da92933a --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h @@ -0,0 +1,59 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ +#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ + +/* Definitions for components on the Debug board */ + +/* Base address of CPLD controller on the Debug board */ +#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(CS5_BASE_ADDR) + +/* LAN9217 ethernet base address */ +#define LAN9217_BASE_ADDR CS5_BASE_ADDR + +/* CPLD config and interrupt base address */ +#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000) + +/* LED switchs */ +#define CPLD_LED_REG (CPLD_ADDR + 0x00) +/* buttons */ +#define CPLD_SWITCH_BUTTONS_REG (EXPIO_ADDR + 0x08) +/* status, interrupt */ +#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10) +#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38) +#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20) +/* magic word for debug CPLD */ +#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40) +#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48) +/* CPLD code version */ +#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50) +/* magic word for debug CPLD */ +#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58) +/* module reset register */ +#define CPLD_MODULE_RESET_REG (CPLD_ADDR + 0x60) +/* CPU ID and Personality ID */ +#define CPLD_MCU_BOARD_ID_REG (CPLD_ADDR + 0x68) + +/* CPLD IRQ line for external uart, external ethernet etc */ +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) + +#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) +#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) + +#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0) +#define EXPIO_INT_XUART_A (MXC_EXP_IO_BASE + 1) +#define EXPIO_INT_XUART_B (MXC_EXP_IO_BASE + 2) +#define EXPIO_INT_BUTTON_A (MXC_EXP_IO_BASE + 3) +#define EXPIO_INT_BUTTON_B (MXC_EXP_IO_BASE + 4) + +#define MXC_MAX_EXP_IO_LINES 16 + +#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h deleted file mode 100644 index 2bbd6ed..0000000 --- a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__ -#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__ - -/* Definitions for components on the Debug board */ - -/* Base address of CPLD controller on the Debug board */ -#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(CS5_BASE_ADDR) - -/* LAN9217 ethernet base address */ -#define LAN9217_BASE_ADDR CS5_BASE_ADDR - -/* CPLD config and interrupt base address */ -#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000) - -/* LED switchs */ -#define CPLD_LED_REG (CPLD_ADDR + 0x00) -/* buttons */ -#define CPLD_SWITCH_BUTTONS_REG (EXPIO_ADDR + 0x08) -/* status, interrupt */ -#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10) -#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38) -#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20) -/* magic word for debug CPLD */ -#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40) -#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48) -/* CPLD code version */ -#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50) -/* magic word for debug CPLD */ -#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58) -/* module reset register */ -#define CPLD_MODULE_RESET_REG (CPLD_ADDR + 0x60) -/* CPU ID and Personality ID */ -#define CPLD_MCU_BOARD_ID_REG (CPLD_ADDR + 0x68) - -/* CPLD IRQ line for external uart, external ethernet etc */ -#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) - -#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) -#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) - -#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0) -#define EXPIO_INT_XUART_A (MXC_EXP_IO_BASE + 1) -#define EXPIO_INT_XUART_B (MXC_EXP_IO_BASE + 2) -#define EXPIO_INT_BUTTON_A (MXC_EXP_IO_BASE + 3) -#define EXPIO_INT_BUTTON_B (MXC_EXP_IO_BASE + 4) - -#define MXC_MAX_EXP_IO_LINES 16 - -#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */ -- cgit v1.1 From a1b67b957ea3b9138ed8239796cb48d8b1bf66b0 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 23 Mar 2010 19:49:35 +0100 Subject: MXC: mach-mx31_3ds: Add support for on board NAND Flash. Since the using of Bad Block Table is not constantly a good behave I had made it configurable. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Kconfig | 9 +++++++++ arch/arm/mach-mx3/mach-mx31_3ds.c | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 3872af1..9a2911e 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -62,6 +62,15 @@ config MACH_MX31_3DS Include support for MX31PDK (3DS) platform. This includes specific configurations for the board and its peripherals. +config MACH_MX31_3DS_MXC_NAND_USE_BBT + bool "Make the MXC NAND driver use the in flash Bad Block Table" + depends on MACH_MX31_3DS + depends on MTD_NAND_MXC + help + Enable this if you want that the MXC NAND driver uses the in flash + Bad Block Table to know what blocks are bad instead of scanning the + entire flash looking for bad block markers. + config MACH_MX31MOBOARD bool "Support mx31moboard platforms (EPFL Mobots group)" select ARCH_MX31 diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index 4a94c3c..bf1f54a 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "devices.h" /*! @@ -53,6 +54,17 @@ static int mx31_3ds_pins[] = { IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), }; +/* + * NAND Flash + */ +static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = { + .width = 1, + .hw_ecc = 1, +#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT + .flash_bbt = 1, +#endif +}; + static struct imxuart_platform_data uart_pdata = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -236,6 +248,7 @@ static void __init mxc_board_init(void) "mx31_3ds"); mxc_register_device(&mxc_uart_device0, &uart_pdata); + mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata); if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); -- cgit v1.1 From a1ac442443342f778d5230b16efadc4c32d96298 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 23 Mar 2010 19:50:28 +0100 Subject: MXC: mach-mx31_3ds: Add SPI1 device support. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/mach-mx31_3ds.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index bf1f54a..80179cf 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "devices.h" /*! @@ -52,6 +53,24 @@ static int mx31_3ds_pins[] = { MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1, IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), + /* SPI 1 */ + MX31_PIN_CSPI2_SCLK__SCLK, + MX31_PIN_CSPI2_MOSI__MOSI, + MX31_PIN_CSPI2_MISO__MISO, + MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, + MX31_PIN_CSPI2_SS0__SS0, + MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */ +}; + +/* SPI */ +static int spi1_internal_chipselect[] = { + MXC_SPI_CS(0), + MXC_SPI_CS(2), +}; + +static struct spi_imx_master spi1_pdata = { + .chipselect = spi1_internal_chipselect, + .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect), }; /* @@ -249,6 +268,7 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_uart_device0, &uart_pdata); mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata); + mxc_register_device(&mxc_spi_device1, &spi1_pdata); if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); -- cgit v1.1 From ae7a3f13ab59784d9d5041d8ecb08477a049e2c6 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 23 Mar 2010 19:51:45 +0100 Subject: MXC: mach-mx31_3ds: add support for freescale mc13783 power management device. Power Gates must to be always enabled. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/mach-mx31_3ds.c | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index 80179cf..f54af1e 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include #include @@ -60,6 +63,33 @@ static int mx31_3ds_pins[] = { MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */ + /* MC13783 IRQ */ + IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), +}; + +/* Regulators */ +static struct regulator_init_data pwgtx_init = { + .constraints = { + .boot_on = 1, + .always_on = 1, + }, +}; + +static struct mc13783_regulator_init_data mx31_3ds_regulators[] = { + { + .id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */ + .init_data = &pwgtx_init, + }, { + .id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */ + .init_data = &pwgtx_init, + }, +}; + +/* MC13783 */ +static struct mc13783_platform_data mc13783_pdata __initdata = { + .regulators = mx31_3ds_regulators, + .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), + .flags = MC13783_USE_REGULATOR, }; /* SPI */ @@ -73,6 +103,18 @@ static struct spi_imx_master spi1_pdata = { .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect), }; +static struct spi_board_info mx31_3ds_spi_devs[] __initdata = { + { + .modalias = "mc13783", + .max_speed_hz = 1000000, + .bus_num = 1, + .chip_select = 1, /* SS2 */ + .platform_data = &mc13783_pdata, + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + .mode = SPI_CS_HIGH, + }, +}; + /* * NAND Flash */ @@ -268,7 +310,10 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_uart_device0, &uart_pdata); mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata); + mxc_register_device(&mxc_spi_device1, &spi1_pdata); + spi_register_board_info(mx31_3ds_spi_devs, + ARRAY_SIZE(mx31_3ds_spi_devs)); if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); -- cgit v1.1 From 8d06a1e1e9c69244f08beb7d17146483f9dcd120 Mon Sep 17 00:00:00 2001 From: Robert Hooker Date: Fri, 19 Mar 2010 15:13:27 -0400 Subject: drm/i915: Disable FBC on 915GM and 945GM. It is causing hangs after a suspend/resume cycle with the default powersave=1 module option on these chipsets since 2.6.32-rc. BugLink: http://bugs.launchpad.net/bugs/492392 Signed-off-by: Robert Hooker Acked-by: Jesse Barnes Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.c | 4 ++-- drivers/gpu/drm/i915/intel_display.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4b26919..1a39ec7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -80,14 +80,14 @@ const static struct intel_device_info intel_i915g_info = { .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i915gm_info = { - .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, + .is_i9xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i945g_info = { .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i945gm_info = { - .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, + .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_hotplug = 1, .cursor_needs_physical = 1, }; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 58fc7fa..f021490 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4814,7 +4814,7 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.fbc_enabled = g4x_fbc_enabled; dev_priv->display.enable_fbc = g4x_enable_fbc; dev_priv->display.disable_fbc = g4x_disable_fbc; - } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) { + } else if (IS_I965GM(dev)) { dev_priv->display.fbc_enabled = i8xx_fbc_enabled; dev_priv->display.enable_fbc = i8xx_enable_fbc; dev_priv->display.disable_fbc = i8xx_disable_fbc; -- cgit v1.1 From 23010e43b353c2cdc9725cbedc7e364708039bf7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 8 Mar 2010 13:35:02 +0100 Subject: drm/i915: introduce to_intel_bo helper This is a purely cosmetic change to make changes in this area easier. And hey, it's not only clearer and typechecked, but actually shorter, too! [anholt: To clarify, this is a change to let us later make drm_i915_gem_object subclass drm_gem_object, instead of having drm_gem_object have a pointer to i915's private data] Signed-off-by: Daniel Vetter Acked-by: Dave Airlie Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 132 ++++++++++++++++----------------- drivers/gpu/drm/i915/i915_gem_debug.c | 4 +- drivers/gpu/drm/i915/i915_gem_tiling.c | 10 +-- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 28 +++---- drivers/gpu/drm/i915/intel_fb.c | 2 +- drivers/gpu/drm/i915/intel_overlay.c | 6 +- 10 files changed, 96 insertions(+), 94 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1376dfe..bb3a4a8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -225,7 +225,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) } else { struct drm_i915_gem_object *obj_priv; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); seq_printf(m, "Fenced object[%2d] = %p: %s " "%08x %08zx %08x %s %08x %08x %d", i, obj, get_pin_flag(obj_priv), diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1a39ec7..0af3dcc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -361,7 +361,7 @@ int i965_reset(struct drm_device *dev, u8 flags) !dev_priv->mm.suspended) { drm_i915_ring_buffer_t *ring = &dev_priv->ring; struct drm_gem_object *obj = ring->ring_obj; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.suspended = 0; /* Stop the ring if it's running. */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aba8260..b7cb4aa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -731,6 +731,8 @@ struct drm_i915_gem_object { atomic_t pending_flip; }; +#define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private) + /** * Request queue structure. * diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 933e865..b85727c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -162,7 +162,7 @@ fast_shmem_read(struct page **pages, static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) { drm_i915_private_t *dev_priv = obj->dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && obj_priv->tiling_mode != I915_TILING_NONE; @@ -263,7 +263,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pread *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); ssize_t remain; loff_t offset, page_base; char __user *user_data; @@ -284,7 +284,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, if (ret != 0) goto fail_put_pages; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = args->offset; while (remain > 0) { @@ -353,7 +353,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pread *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct mm_struct *mm = current->mm; struct page **user_pages; ssize_t remain; @@ -402,7 +402,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, if (ret != 0) goto fail_put_pages; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = args->offset; while (remain > 0) { @@ -478,7 +478,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EBADF; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); /* Bounds check source. * @@ -580,7 +580,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); drm_i915_private_t *dev_priv = dev->dev_private; ssize_t remain; loff_t offset, page_base; @@ -604,7 +604,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, if (ret) goto fail; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = obj_priv->gtt_offset + args->offset; while (remain > 0) { @@ -654,7 +654,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); drm_i915_private_t *dev_priv = dev->dev_private; ssize_t remain; loff_t gtt_page_base, offset; @@ -698,7 +698,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, if (ret) goto out_unpin_object; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = obj_priv->gtt_offset + args->offset; while (remain > 0) { @@ -760,7 +760,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); ssize_t remain; loff_t offset, page_base; char __user *user_data; @@ -780,7 +780,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, if (ret != 0) goto fail_put_pages; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = args->offset; obj_priv->dirty = 1; @@ -828,7 +828,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct mm_struct *mm = current->mm; struct page **user_pages; ssize_t remain; @@ -876,7 +876,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, if (ret != 0) goto fail_put_pages; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = args->offset; obj_priv->dirty = 1; @@ -951,7 +951,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EBADF; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); /* Bounds check destination. * @@ -1033,7 +1033,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EBADF; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); mutex_lock(&dev->struct_mutex); @@ -1095,7 +1095,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, DRM_INFO("%s: sw_finish %d (%p %zd)\n", __func__, args->handle, obj, obj->size); #endif - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); /* Pinned buffers may be scanout, so flush the cache */ if (obj_priv->pin_count) @@ -1166,7 +1166,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) struct drm_gem_object *obj = vma->vm_private_data; struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); pgoff_t page_offset; unsigned long pfn; int ret = 0; @@ -1233,7 +1233,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_gem_mm *mm = dev->mm_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_map_list *list; struct drm_local_map *map; int ret = 0; @@ -1304,7 +1304,7 @@ void i915_gem_release_mmap(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (dev->dev_mapping) unmap_mapping_range(dev->dev_mapping, @@ -1315,7 +1315,7 @@ static void i915_gem_free_mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_gem_mm *mm = dev->mm_private; struct drm_map_list *list; @@ -1346,7 +1346,7 @@ static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int start, i; /* @@ -1405,7 +1405,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to mmap a purgeable buffer\n"); @@ -1449,7 +1449,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, void i915_gem_object_put_pages(struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count = obj->size / PAGE_SIZE; int i; @@ -1485,7 +1485,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); /* Add a reference if we're newly entering the active list. */ if (!obj_priv->active) { @@ -1505,7 +1505,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); BUG_ON(!obj_priv->active); list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list); @@ -1516,7 +1516,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj) static void i915_gem_object_truncate(struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct inode *inode; inode = obj->filp->f_path.dentry->d_inode; @@ -1537,7 +1537,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); i915_verify_inactive(dev, __FILE__, __LINE__); if (obj_priv->pin_count != 0) @@ -1964,7 +1964,7 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; /* This function only exists to support waiting for existing rendering, @@ -1996,7 +1996,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret = 0; #if WATCH_BUF @@ -2172,7 +2172,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) #if WATCH_LRU DRM_INFO("%s: evicting %p\n", __func__, obj); #endif - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); BUG_ON(obj_priv->pin_count != 0); BUG_ON(obj_priv->active); @@ -2243,7 +2243,7 @@ int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count, i; struct address_space *mapping; struct inode *inode; @@ -2296,7 +2296,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int regnum = obj_priv->fence_reg; uint64_t val; @@ -2318,7 +2318,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int regnum = obj_priv->fence_reg; uint64_t val; @@ -2338,7 +2338,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int regnum = obj_priv->fence_reg; int tile_width; uint32_t fence_reg, val; @@ -2380,7 +2380,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int regnum = obj_priv->fence_reg; uint32_t val; uint32_t pitch_val; @@ -2424,7 +2424,7 @@ static int i915_find_fence_reg(struct drm_device *dev) if (!reg->obj) return i; - obj_priv = reg->obj->driver_private; + obj_priv = to_intel_bo(reg->obj); if (!obj_priv->pin_count) avail++; } @@ -2479,7 +2479,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_i915_fence_reg *reg = NULL; int ret; @@ -2546,7 +2546,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (IS_GEN6(dev)) { I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + @@ -2582,7 +2582,7 @@ int i915_gem_object_put_fence_reg(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (obj_priv->fence_reg == I915_FENCE_REG_NONE) return 0; @@ -2620,7 +2620,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_mm_node *free_space; gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; int ret; @@ -2727,7 +2727,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) void i915_gem_clflush_object(struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); /* If we don't have a page list set up, then we're not pinned * to GPU, and we can ignore the cache flush because it'll happen @@ -2828,7 +2828,7 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj) int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_write_domain, old_read_domains; int ret; @@ -2878,7 +2878,7 @@ int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_write_domain, old_read_domains; int ret; @@ -3091,7 +3091,7 @@ static void i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t invalidate_domains = 0; uint32_t flush_domains = 0; uint32_t old_read_domains; @@ -3176,7 +3176,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (!obj_priv->page_cpu_valid) return; @@ -3216,7 +3216,7 @@ static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, uint64_t offset, uint64_t size) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_read_domains; int i, ret; @@ -3285,7 +3285,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int i, ret; void __iomem *reloc_page; bool need_fence; @@ -3336,7 +3336,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, i915_gem_object_unpin(obj); return -EBADF; } - target_obj_priv = target_obj->driver_private; + target_obj_priv = to_intel_bo(target_obj); #if WATCH_RELOC DRM_INFO("%s: obj %p offset %08x target %d " @@ -3688,7 +3688,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, prepare_to_wait(&dev_priv->pending_flip_queue, &wait, TASK_INTERRUPTIBLE); for (i = 0; i < count; i++) { - obj_priv = object_list[i]->driver_private; + obj_priv = to_intel_bo(object_list[i]); if (atomic_read(&obj_priv->pending_flip) > 0) break; } @@ -3797,7 +3797,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } - obj_priv = object_list[i]->driver_private; + obj_priv = to_intel_bo(object_list[i]); if (obj_priv->in_execbuffer) { DRM_ERROR("Object %p appears more than once in object list\n", object_list[i]); @@ -3923,7 +3923,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_write_domain = obj->write_domain; obj->write_domain = obj->pending_write_domain; @@ -3998,7 +3998,7 @@ err: for (i = 0; i < args->buffer_count; i++) { if (object_list[i]) { - obj_priv = object_list[i]->driver_private; + obj_priv = to_intel_bo(object_list[i]); obj_priv->in_execbuffer = false; } drm_gem_object_unreference(object_list[i]); @@ -4176,7 +4176,7 @@ int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; i915_verify_inactive(dev, __FILE__, __LINE__); @@ -4209,7 +4209,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); i915_verify_inactive(dev, __FILE__, __LINE__); obj_priv->pin_count--; @@ -4249,7 +4249,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, mutex_unlock(&dev->struct_mutex); return -EBADF; } - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to pin a purgeable buffer\n"); @@ -4306,7 +4306,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data, return -EBADF; } - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->pin_filp != file_priv) { DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", args->handle); @@ -4348,7 +4348,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, */ i915_gem_retire_requests(dev); - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); /* Don't count being on the flushing list against the object being * done. Otherwise, a buffer left on the flushing list but not getting * flushed (because nobody's flushing that domain) won't ever return @@ -4394,7 +4394,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, } mutex_lock(&dev->struct_mutex); - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->pin_count) { drm_gem_object_unreference(obj); @@ -4455,7 +4455,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) void i915_gem_free_object(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); trace_i915_gem_object_destroy(obj); @@ -4564,7 +4564,7 @@ i915_gem_init_hws(struct drm_device *dev) DRM_ERROR("Failed to allocate status page\n"); return -ENOMEM; } - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; ret = i915_gem_object_pin(obj, 4096); @@ -4608,7 +4608,7 @@ i915_gem_cleanup_hws(struct drm_device *dev) return; obj = dev_priv->hws_obj; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); kunmap(obj_priv->pages[0]); i915_gem_object_unpin(obj); @@ -4642,7 +4642,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) i915_gem_cleanup_hws(dev); return -ENOMEM; } - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); ret = i915_gem_object_pin(obj, 4096); if (ret != 0) { @@ -4935,7 +4935,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev, int ret; int page_count; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (!obj_priv->phys_obj) return; @@ -4974,7 +4974,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, if (id > I915_MAX_PHYS_OBJECT) return -EINVAL; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->phys_obj) { if (obj_priv->phys_obj->id == id) @@ -5025,7 +5025,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); void *obj_addr; int ret; char __user *user_data; diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index e602614..35507cf 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -72,7 +72,7 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len, const char *where, uint32_t mark) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page; DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); @@ -137,7 +137,7 @@ void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page; uint32_t *gtt_mapping; uint32_t *backing_map = NULL; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index c01c878..449157f 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -240,7 +240,7 @@ bool i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (obj_priv->gtt_space == NULL) return true; @@ -280,7 +280,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { drm_gem_object_unreference_unlocked(obj); @@ -364,7 +364,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); mutex_lock(&dev->struct_mutex); @@ -427,7 +427,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count = obj->size >> PAGE_SHIFT; int i; @@ -456,7 +456,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count = obj->size >> PAGE_SHIFT; int i; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5388354..bfbdad9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -443,7 +443,7 @@ i915_error_object_create(struct drm_device *dev, if (src == NULL) return NULL; - src_priv = src->driver_private; + src_priv = to_intel_bo(src); if (src_priv->pages == NULL) return NULL; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f021490..7adb3a5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1002,7 +1002,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_framebuffer *fb = crtc->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane, i; u32 fbc_ctl, fbc_ctl2; @@ -1079,7 +1079,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_framebuffer *fb = crtc->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB); @@ -1175,7 +1175,7 @@ static void intel_update_fbc(struct drm_crtc *crtc, return; intel_fb = to_intel_framebuffer(fb); - obj_priv = intel_fb->obj->driver_private; + obj_priv = to_intel_bo(intel_fb->obj); /* * If FBC is already on, we just have to verify that we can @@ -1242,7 +1242,7 @@ out_disable: static int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); u32 alignment; int ret; @@ -1322,7 +1322,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, intel_fb = to_intel_framebuffer(crtc->fb); obj = intel_fb->obj; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); mutex_lock(&dev->struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj); @@ -1400,7 +1400,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (old_fb) { intel_fb = to_intel_framebuffer(old_fb); - obj_priv = intel_fb->obj->driver_private; + obj_priv = to_intel_bo(intel_fb->obj); i915_gem_object_unpin(intel_fb->obj); } intel_increase_pllclock(crtc, true); @@ -3510,7 +3510,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, if (!bo) return -ENOENT; - obj_priv = bo->driver_private; + obj_priv = to_intel_bo(bo); if (bo->size < width * height * 4) { DRM_ERROR("buffer is to small\n"); @@ -4155,7 +4155,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) work = intel_crtc->unpin_work; if (work == NULL || !work->pending) { if (work && !work->pending) { - obj_priv = work->pending_flip_obj->driver_private; + obj_priv = to_intel_bo(work->pending_flip_obj); DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", obj_priv, atomic_read(&obj_priv->pending_flip)); @@ -4180,7 +4180,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) spin_unlock_irqrestore(&dev->event_lock, flags); - obj_priv = work->pending_flip_obj->driver_private; + obj_priv = to_intel_bo(work->pending_flip_obj); /* Initial scanout buffer will have a 0 pending flip count */ if ((atomic_read(&obj_priv->pending_flip) == 0) || @@ -4251,7 +4251,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ret = intel_pin_and_fence_fb_obj(dev, obj); if (ret != 0) { DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", - obj->driver_private); + to_intel_bo(obj)); kfree(work); intel_crtc->unpin_work = NULL; mutex_unlock(&dev->struct_mutex); @@ -4265,7 +4265,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, crtc->fb = fb; i915_gem_object_flush_write_domain(obj); drm_vblank_get(dev, intel_crtc->pipe); - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); atomic_inc(&obj_priv->pending_flip); work->pending_flip_obj = obj; @@ -4778,14 +4778,14 @@ void intel_init_clock_gating(struct drm_device *dev) struct drm_i915_gem_object *obj_priv = NULL; if (dev_priv->pwrctx) { - obj_priv = dev_priv->pwrctx->driver_private; + obj_priv = to_intel_bo(dev_priv->pwrctx); } else { struct drm_gem_object *pwrctx; pwrctx = intel_alloc_power_context(dev); if (pwrctx) { dev_priv->pwrctx = pwrctx; - obj_priv = pwrctx->driver_private; + obj_priv = to_intel_bo(pwrctx); } } @@ -4956,7 +4956,7 @@ void intel_modeset_cleanup(struct drm_device *dev) if (dev_priv->pwrctx) { struct drm_i915_gem_object *obj_priv; - obj_priv = dev_priv->pwrctx->driver_private; + obj_priv = to_intel_bo(dev_priv->pwrctx); I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN); I915_READ(PWRCTXA); i915_gem_object_unpin(dev_priv->pwrctx); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 8cd791d..c9fbdfa 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -145,7 +145,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, ret = -ENOMEM; goto out; } - obj_priv = fbo->driver_private; + obj_priv = to_intel_bo(fbo); mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 60595fc..6d524a1 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -724,7 +724,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, int ret, tmp_width; struct overlay_registers *regs; bool scale_changed = false; - struct drm_i915_gem_object *bo_priv = new_bo->driver_private; + struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo); struct drm_device *dev = overlay->dev; BUG_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -809,7 +809,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, intel_overlay_continue(overlay, scale_changed); overlay->old_vid_bo = overlay->vid_bo; - overlay->vid_bo = new_bo->driver_private; + overlay->vid_bo = to_intel_bo(new_bo); return 0; @@ -1344,7 +1344,7 @@ void intel_setup_overlay(struct drm_device *dev) reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE); if (!reg_bo) goto out_free; - overlay->reg_bo = reg_bo->driver_private; + overlay->reg_bo = to_intel_bo(reg_bo); if (OVERLAY_NONPHYSICAL(dev)) { ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); -- cgit v1.1 From 5e64499f3d39c633de49320e399479642c2b1743 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 19 Mar 2010 21:46:23 +0100 Subject: agp/intel: intel_845_driver is an agp driver! ... not a GTT driver. So the additional chipset flush introduced in commit 2162e6a2b0cd5acbb9bd8a3c94e1c1269b078295 Author: Dave Airlie Date: Wed Nov 21 16:36:31 2007 +1000 agp/intel: Add chipset flushing support for i8xx chipsets. to fix a GTT problem makes absolutely no sense. If this would really be needed for AGP chipsets, too, we should add it to all i8xx agp drivers, not just one. Signed-off-by: Daniel Vetter Signed-off-by: Eric Anholt --- drivers/char/agp/intel-agp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b78d5c3..a34fc9f 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1816,8 +1816,6 @@ static int intel_845_configure(void) pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); /* clear any possible error conditions */ pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); - - intel_i830_setup_flush(); return 0; } @@ -2187,7 +2185,6 @@ static const struct agp_bridge_driver intel_845_driver = { .agp_destroy_page = agp_generic_destroy_page, .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, - .chipset_flush = intel_i830_chipset_flush, }; static const struct agp_bridge_driver intel_850_driver = { -- cgit v1.1 From 21d40d37eca86872f2bf0af995809ebdef25c9d9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 25 Mar 2010 11:11:14 -0700 Subject: drm/i915: Rename intel_output to intel_encoder. The intel_output naming is inherited from the UMS code, which had a structure of screen -> CRTC -> output. The DRM code has an additional notion of encoder/connector, so the structure is screen -> CRTC -> encoder -> connector. This is a useful structure for SDVO encoders which can support multiple connectors (each of which requires different programming in the one encoder and could be connected to different CRTCs), or for DVI-I, where multiple encoders feed into the connector for whether it's used for digital or analog. Most of our code is encoder-related, so transition it to talking about encoders before we start trying to distinguish connectors. This patch is produced by sed s/intel_output/intel_encoder/ over the driver. Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_irq.c | 6 +- drivers/gpu/drm/i915/intel_crt.c | 68 ++--- drivers/gpu/drm/i915/intel_display.c | 46 +-- drivers/gpu/drm/i915/intel_dp.c | 256 ++++++++-------- drivers/gpu/drm/i915/intel_drv.h | 18 +- drivers/gpu/drm/i915/intel_dvo.c | 92 +++--- drivers/gpu/drm/i915/intel_hdmi.c | 86 +++--- drivers/gpu/drm/i915/intel_lvds.c | 64 ++-- drivers/gpu/drm/i915/intel_modes.c | 22 +- drivers/gpu/drm/i915/intel_sdvo.c | 572 +++++++++++++++++------------------ drivers/gpu/drm/i915/intel_tv.c | 96 +++--- 11 files changed, 663 insertions(+), 663 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index bfbdad9..5b53adf 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -259,10 +259,10 @@ static void i915_hotplug_work_func(struct work_struct *work) if (mode_config->num_connector) { list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - if (intel_output->hot_plug) - (*intel_output->hot_plug) (intel_output); + if (intel_encoder->hot_plug) + (*intel_encoder->hot_plug) (intel_encoder); } } /* Just fire off a uevent and let userspace tell us what to do */ diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index fccf074..36c4ad7 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -246,19 +246,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) static bool intel_crt_detect_ddc(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); /* CRT should always be at 0, but check anyway */ - if (intel_output->type != INTEL_OUTPUT_ANALOG) + if (intel_encoder->type != INTEL_OUTPUT_ANALOG) return false; - return intel_ddc_probe(intel_output); + return intel_ddc_probe(intel_encoder); } static enum drm_connector_status -intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) +intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) { - struct drm_encoder *encoder = &intel_output->enc; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -386,8 +386,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_crtc *crtc; int dpms_mode; enum drm_connector_status status; @@ -404,13 +404,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto /* for pre-945g platforms use load detect */ if (encoder->crtc && encoder->crtc->enabled) { - status = intel_crt_load_detect(encoder->crtc, intel_output); + status = intel_crt_load_detect(encoder->crtc, intel_encoder); } else { - crtc = intel_get_load_detect_pipe(intel_output, + crtc = intel_get_load_detect_pipe(intel_encoder, NULL, &dpms_mode); if (crtc) { - status = intel_crt_load_detect(crtc, intel_output); - intel_release_load_detect_pipe(intel_output, dpms_mode); + status = intel_crt_load_detect(crtc, intel_encoder); + intel_release_load_detect_pipe(intel_encoder, dpms_mode); } else status = connector_status_unknown; } @@ -420,9 +420,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto static void intel_crt_destroy(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - intel_i2c_destroy(intel_output->ddc_bus); + intel_i2c_destroy(intel_encoder->ddc_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); kfree(connector); @@ -431,28 +431,28 @@ static void intel_crt_destroy(struct drm_connector *connector) static int intel_crt_get_modes(struct drm_connector *connector) { int ret; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); struct i2c_adapter *ddcbus; struct drm_device *dev = connector->dev; - ret = intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_encoder); if (ret || !IS_G4X(dev)) goto end; - ddcbus = intel_output->ddc_bus; + ddcbus = intel_encoder->ddc_bus; /* Try to probe digital port for output in DVI-I -> VGA mode. */ - intel_output->ddc_bus = + intel_encoder->ddc_bus = intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); - if (!intel_output->ddc_bus) { - intel_output->ddc_bus = ddcbus; + if (!intel_encoder->ddc_bus) { + intel_encoder->ddc_bus = ddcbus; dev_printk(KERN_ERR, &connector->dev->pdev->dev, "DDC bus registration failed for CRTDDC_D.\n"); goto end; } /* Try to get modes by GPIOD port */ - ret = intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_encoder); intel_i2c_destroy(ddcbus); end: @@ -505,23 +505,23 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { void intel_crt_init(struct drm_device *dev) { struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct drm_i915_private *dev_priv = dev->dev_private; u32 i2c_reg; - intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); - if (!intel_output) + intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); + if (!intel_encoder) return; - connector = &intel_output->base; - drm_connector_init(dev, &intel_output->base, + connector = &intel_encoder->base; + drm_connector_init(dev, &intel_encoder->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC); - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, + &intel_encoder->enc); /* Set up the DDC bus. */ if (HAS_PCH_SPLIT(dev)) @@ -532,22 +532,22 @@ void intel_crt_init(struct drm_device *dev) if (dev_priv->crt_ddc_bus != 0) i2c_reg = dev_priv->crt_ddc_bus; } - intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); - if (!intel_output->ddc_bus) { + intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); + if (!intel_encoder->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); return; } - intel_output->type = INTEL_OUTPUT_ANALOG; - intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + intel_encoder->type = INTEL_OUTPUT_ANALOG; + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT) | (1 << INTEL_SDVO_LVDS_CLONE_BIT); - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); drm_sysfs_connector_add(connector); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7adb3a5..2595c4c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -746,8 +746,8 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) list_for_each_entry(l_entry, &mode_config->connector_list, head) { if (l_entry->encoder && l_entry->encoder->crtc == crtc) { - struct intel_output *intel_output = to_intel_output(l_entry); - if (intel_output->type == type) + struct intel_encoder *intel_encoder = to_intel_encoder(l_entry); + if (intel_encoder->type == type) return true; } } @@ -2942,19 +2942,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, drm_vblank_pre_modeset(dev, pipe); list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); if (!connector->encoder || connector->encoder->crtc != crtc) continue; - switch (intel_output->type) { + switch (intel_encoder->type) { case INTEL_OUTPUT_LVDS: is_lvds = true; break; case INTEL_OUTPUT_SDVO: case INTEL_OUTPUT_HDMI: is_sdvo = true; - if (intel_output->needs_tv_clock) + if (intel_encoder->needs_tv_clock) is_tv = true; break; case INTEL_OUTPUT_DVO: @@ -3049,7 +3049,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_connector *edp; target_clock = mode->clock; edp = intel_pipe_get_output(crtc); - intel_edp_link_config(to_intel_output(edp), + intel_edp_link_config(to_intel_encoder(edp), &lane, &link_bw); } else { /* DP over FDI requires target mode clock @@ -3669,14 +3669,14 @@ static struct drm_display_mode load_detect_mode = { 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), }; -struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, +struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, struct drm_display_mode *mode, int *dpms_mode) { struct intel_crtc *intel_crtc; struct drm_crtc *possible_crtc; struct drm_crtc *supported_crtc =NULL; - struct drm_encoder *encoder = &intel_output->enc; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_crtc *crtc = NULL; struct drm_device *dev = encoder->dev; struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; @@ -3728,8 +3728,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, } encoder->crtc = crtc; - intel_output->base.encoder = encoder; - intel_output->load_detect_temp = true; + intel_encoder->base.encoder = encoder; + intel_encoder->load_detect_temp = true; intel_crtc = to_intel_crtc(crtc); *dpms_mode = intel_crtc->dpms_mode; @@ -3754,18 +3754,18 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, return crtc; } -void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode) +void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode) { - struct drm_encoder *encoder = &intel_output->enc; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_device *dev = encoder->dev; struct drm_crtc *crtc = encoder->crtc; struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - if (intel_output->load_detect_temp) { + if (intel_encoder->load_detect_temp) { encoder->crtc = NULL; - intel_output->base.encoder = NULL; - intel_output->load_detect_temp = false; + intel_encoder->base.encoder = NULL; + intel_encoder->load_detect_temp = false; crtc->enabled = drm_helper_crtc_in_use(crtc); drm_helper_disable_unused_functions(dev); } @@ -4398,8 +4398,8 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) int entry = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - if (type_mask & intel_output->clone_mask) + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + if (type_mask & intel_encoder->clone_mask) index_mask |= (1 << entry); entry++; } @@ -4494,12 +4494,12 @@ static void intel_setup_outputs(struct drm_device *dev) intel_tv_init(dev); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_encoder *encoder = &intel_encoder->enc; - encoder->possible_crtcs = intel_output->crtc_mask; + encoder->possible_crtcs = intel_encoder->crtc_mask; encoder->possible_clones = intel_connector_clones(dev, - intel_output->clone_mask); + intel_encoder->clone_mask); } } @@ -4977,9 +4977,9 @@ void intel_modeset_cleanup(struct drm_device *dev) */ struct drm_encoder *intel_best_encoder(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - return &intel_output->enc; + return &intel_encoder->enc; } /* diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3ef3a0d..0a7e326 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -54,23 +54,23 @@ struct intel_dp_priv { uint8_t link_bw; uint8_t lane_count; uint8_t dpcd[4]; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct i2c_adapter adapter; struct i2c_algo_dp_aux_data algo; }; static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, +intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); +intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP); void -intel_edp_link_config (struct intel_output *intel_output, +intel_edp_link_config (struct intel_encoder *intel_encoder, int *lane_num, int *link_bw) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; *lane_num = dp_priv->lane_count; if (dp_priv->link_bw == DP_LINK_BW_1_62) @@ -80,9 +80,9 @@ intel_edp_link_config (struct intel_output *intel_output, } static int -intel_dp_max_lane_count(struct intel_output *intel_output) +intel_dp_max_lane_count(struct intel_encoder *intel_encoder) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int max_lane_count = 4; if (dp_priv->dpcd[0] >= 0x11) { @@ -98,9 +98,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output) } static int -intel_dp_max_link_bw(struct intel_output *intel_output) +intel_dp_max_link_bw(struct intel_encoder *intel_encoder) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int max_link_bw = dp_priv->dpcd[1]; switch (max_link_bw) { @@ -126,11 +126,11 @@ intel_dp_link_clock(uint8_t link_bw) /* I think this is a fiction */ static int intel_dp_link_required(struct drm_device *dev, - struct intel_output *intel_output, int pixel_clock) + struct intel_encoder *intel_encoder, int pixel_clock) { struct drm_i915_private *dev_priv = dev->dev_private; - if (IS_eDP(intel_output)) + if (IS_eDP(intel_encoder)) return (pixel_clock * dev_priv->edp_bpp) / 8; else return pixel_clock * 3; @@ -140,11 +140,11 @@ static int intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_output *intel_output = to_intel_output(connector); - int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); - int max_lanes = intel_dp_max_lane_count(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); + int max_lanes = intel_dp_max_lane_count(intel_encoder); - if (intel_dp_link_required(connector->dev, intel_output, mode->clock) + if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) > max_link_clock * max_lanes) return MODE_CLOCK_HIGH; @@ -208,13 +208,13 @@ intel_hrawclk(struct drm_device *dev) } static int -intel_dp_aux_ch(struct intel_output *intel_output, +intel_dp_aux_ch(struct intel_encoder *intel_encoder, uint8_t *send, int send_bytes, uint8_t *recv, int recv_size) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; uint32_t output_reg = dp_priv->output_reg; - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t ch_ctl = output_reg + 0x10; uint32_t ch_data = ch_ctl + 4; @@ -229,7 +229,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, * and would like to run at 2MHz. So, take the * hrawclk value and divide by 2 and use that */ - if (IS_eDP(intel_output)) + if (IS_eDP(intel_encoder)) aux_clock_divider = 225; /* eDP input clock at 450Mhz */ else if (HAS_PCH_SPLIT(dev)) aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ @@ -312,7 +312,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, /* Write data to the aux channel in native mode */ static int -intel_dp_aux_native_write(struct intel_output *intel_output, +intel_dp_aux_native_write(struct intel_encoder *intel_encoder, uint16_t address, uint8_t *send, int send_bytes) { int ret; @@ -329,7 +329,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output, memcpy(&msg[4], send, send_bytes); msg_bytes = send_bytes + 4; for (;;) { - ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1); + ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1); if (ret < 0) return ret; if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) @@ -344,15 +344,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output, /* Write a single byte to the aux channel in native mode */ static int -intel_dp_aux_native_write_1(struct intel_output *intel_output, +intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder, uint16_t address, uint8_t byte) { - return intel_dp_aux_native_write(intel_output, address, &byte, 1); + return intel_dp_aux_native_write(intel_encoder, address, &byte, 1); } /* read bytes from a native aux channel */ static int -intel_dp_aux_native_read(struct intel_output *intel_output, +intel_dp_aux_native_read(struct intel_encoder *intel_encoder, uint16_t address, uint8_t *recv, int recv_bytes) { uint8_t msg[4]; @@ -371,7 +371,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output, reply_bytes = recv_bytes + 1; for (;;) { - ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, + ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, reply, reply_bytes); if (ret == 0) return -EPROTO; @@ -397,7 +397,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, struct intel_dp_priv *dp_priv = container_of(adapter, struct intel_dp_priv, adapter); - struct intel_output *intel_output = dp_priv->intel_output; + struct intel_encoder *intel_encoder = dp_priv->intel_encoder; uint16_t address = algo_data->address; uint8_t msg[5]; uint8_t reply[2]; @@ -436,7 +436,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, } for (;;) { - ret = intel_dp_aux_ch(intel_output, + ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, reply, reply_bytes); if (ret < 0) { @@ -464,9 +464,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, } static int -intel_dp_i2c_init(struct intel_output *intel_output, const char *name) +intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; DRM_DEBUG_KMS("i2c_init %s\n", name); dp_priv->algo.running = false; @@ -479,7 +479,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name) strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; dp_priv->adapter.algo_data = &dp_priv->algo; - dp_priv->adapter.dev.parent = &intel_output->base.kdev; + dp_priv->adapter.dev.parent = &intel_encoder->base.kdev; return i2c_dp_aux_add_bus(&dp_priv->adapter); } @@ -488,18 +488,18 @@ static bool intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int lane_count, clock; - int max_lane_count = intel_dp_max_lane_count(intel_output); - int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0; + int max_lane_count = intel_dp_max_lane_count(intel_encoder); + int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; - if (intel_dp_link_required(encoder->dev, intel_output, mode->clock) + if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) <= link_avail) { dp_priv->link_bw = bws[clock]; dp_priv->lane_count = lane_count; @@ -561,16 +561,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct intel_dp_m_n m_n; /* - * Find the lane count in the intel_output private + * Find the lane count in the intel_encoder private */ list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; if (!connector->encoder || connector->encoder->crtc != crtc) continue; - if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) { + if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { lane_count = dp_priv->lane_count; break; } @@ -625,9 +625,9 @@ static void intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - struct drm_crtc *crtc = intel_output->enc.crtc; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; + struct drm_crtc *crtc = intel_encoder->enc.crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); dp_priv->DP = (DP_LINK_TRAIN_OFF | @@ -666,7 +666,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, if (intel_crtc->pipe == 1) dp_priv->DP |= DP_PIPEB_SELECT; - if (IS_eDP(intel_output)) { + if (IS_eDP(intel_encoder)) { /* don't miss out required setting for eDP */ dp_priv->DP |= DP_PLL_ENABLE; if (adjusted_mode->clock < 200000) @@ -701,22 +701,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev) static void intel_dp_dpms(struct drm_encoder *encoder, int mode) { - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - struct drm_device *dev = intel_output->base.dev; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t dp_reg = I915_READ(dp_priv->output_reg); if (mode != DRM_MODE_DPMS_ON) { if (dp_reg & DP_PORT_EN) { - intel_dp_link_down(intel_output, dp_priv->DP); - if (IS_eDP(intel_output)) + intel_dp_link_down(intel_encoder, dp_priv->DP); + if (IS_eDP(intel_encoder)) ironlake_edp_backlight_off(dev); } } else { if (!(dp_reg & DP_PORT_EN)) { - intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); - if (IS_eDP(intel_output)) + intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); + if (IS_eDP(intel_encoder)) ironlake_edp_backlight_on(dev); } } @@ -728,12 +728,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) * link status information */ static bool -intel_dp_get_link_status(struct intel_output *intel_output, +intel_dp_get_link_status(struct intel_encoder *intel_encoder, uint8_t link_status[DP_LINK_STATUS_SIZE]) { int ret; - ret = intel_dp_aux_native_read(intel_output, + ret = intel_dp_aux_native_read(intel_encoder, DP_LANE0_1_STATUS, link_status, DP_LINK_STATUS_SIZE); if (ret != DP_LINK_STATUS_SIZE) @@ -751,13 +751,13 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], static void intel_dp_save(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; dp_priv->save_DP = I915_READ(dp_priv->output_reg); - intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET, + intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET, dp_priv->save_link_configuration, sizeof (dp_priv->save_link_configuration)); } @@ -824,7 +824,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) } static void -intel_get_adjust_train(struct intel_output *intel_output, +intel_get_adjust_train(struct intel_encoder *intel_encoder, uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count, uint8_t train_set[4]) @@ -941,15 +941,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) } static bool -intel_dp_set_link_train(struct intel_output *intel_output, +intel_dp_set_link_train(struct intel_encoder *intel_encoder, uint32_t dp_reg_value, uint8_t dp_train_pat, uint8_t train_set[4], bool first) { - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int ret; I915_WRITE(dp_priv->output_reg, dp_reg_value); @@ -957,11 +957,11 @@ intel_dp_set_link_train(struct intel_output *intel_output, if (first) intel_wait_for_vblank(dev); - intel_dp_aux_native_write_1(intel_output, + intel_dp_aux_native_write_1(intel_encoder, DP_TRAINING_PATTERN_SET, dp_train_pat); - ret = intel_dp_aux_native_write(intel_output, + ret = intel_dp_aux_native_write(intel_encoder, DP_TRAINING_LANE0_SET, train_set, 4); if (ret != 4) return false; @@ -970,12 +970,12 @@ intel_dp_set_link_train(struct intel_output *intel_output, } static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, +intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) { - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; uint8_t train_set[4]; uint8_t link_status[DP_LINK_STATUS_SIZE]; int i; @@ -986,7 +986,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, int tries; /* Write the link configuration data */ - intel_dp_aux_native_write(intel_output, 0x100, + intel_dp_aux_native_write(intel_encoder, 0x100, link_configuration, DP_LINK_CONFIGURATION_SIZE); DP |= DP_PORT_EN; @@ -1000,14 +1000,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; - if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1, + if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1, DP_TRAINING_PATTERN_1, train_set, first)) break; first = false; /* Set training pattern 1 */ udelay(100); - if (!intel_dp_get_link_status(intel_output, link_status)) + if (!intel_dp_get_link_status(intel_encoder, link_status)) break; if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { @@ -1032,7 +1032,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; /* Compute new train_set as requested by target */ - intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); + intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); } /* channel equalization */ @@ -1044,13 +1044,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; /* channel eq pattern */ - if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2, + if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2, DP_TRAINING_PATTERN_2, train_set, false)) break; udelay(400); - if (!intel_dp_get_link_status(intel_output, link_status)) + if (!intel_dp_get_link_status(intel_encoder, link_status)) break; if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { @@ -1063,26 +1063,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, break; /* Compute new train_set as requested by target */ - intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); + intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); ++tries; } I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); POSTING_READ(dp_priv->output_reg); - intel_dp_aux_native_write_1(intel_output, + intel_dp_aux_native_write_1(intel_encoder, DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); } static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) +intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) { - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; DRM_DEBUG_KMS("\n"); - if (IS_eDP(intel_output)) { + if (IS_eDP(intel_encoder)) { DP &= ~DP_PLL_ENABLE; I915_WRITE(dp_priv->output_reg, DP); POSTING_READ(dp_priv->output_reg); @@ -1095,7 +1095,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) udelay(17000); - if (IS_eDP(intel_output)) + if (IS_eDP(intel_encoder)) DP |= DP_LINK_TRAIN_OFF; I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); POSTING_READ(dp_priv->output_reg); @@ -1104,13 +1104,13 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) static void intel_dp_restore(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; if (dp_priv->save_DP & DP_PORT_EN) - intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration); + intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration); else - intel_dp_link_down(intel_output, dp_priv->save_DP); + intel_dp_link_down(intel_encoder, dp_priv->save_DP); } /* @@ -1123,32 +1123,32 @@ intel_dp_restore(struct drm_connector *connector) */ static void -intel_dp_check_link_status(struct intel_output *intel_output) +intel_dp_check_link_status(struct intel_encoder *intel_encoder) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; uint8_t link_status[DP_LINK_STATUS_SIZE]; - if (!intel_output->enc.crtc) + if (!intel_encoder->enc.crtc) return; - if (!intel_dp_get_link_status(intel_output, link_status)) { - intel_dp_link_down(intel_output, dp_priv->DP); + if (!intel_dp_get_link_status(intel_encoder, link_status)) { + intel_dp_link_down(intel_encoder, dp_priv->DP); return; } if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) - intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); + intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); } static enum drm_connector_status ironlake_dp_detect(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; enum drm_connector_status status; status = connector_status_disconnected; - if (intel_dp_aux_native_read(intel_output, + if (intel_dp_aux_native_read(intel_encoder, 0x000, dp_priv->dpcd, sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) { @@ -1167,10 +1167,10 @@ ironlake_dp_detect(struct drm_connector *connector) static enum drm_connector_status intel_dp_detect(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; uint32_t temp, bit; enum drm_connector_status status; @@ -1209,7 +1209,7 @@ intel_dp_detect(struct drm_connector *connector) return connector_status_disconnected; status = connector_status_disconnected; - if (intel_dp_aux_native_read(intel_output, + if (intel_dp_aux_native_read(intel_encoder, 0x000, dp_priv->dpcd, sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) { @@ -1221,20 +1221,20 @@ intel_dp_detect(struct drm_connector *connector) static int intel_dp_get_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; int ret; /* We should parse the EDID data and find out if it has an audio sink */ - ret = intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_encoder); if (ret) return ret; /* if eDP has no EDID, try to use fixed panel mode from VBT */ - if (IS_eDP(intel_output)) { + if (IS_eDP(intel_encoder)) { if (dev_priv->panel_fixed_mode != NULL) { struct drm_display_mode *mode; mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); @@ -1248,13 +1248,13 @@ static int intel_dp_get_modes(struct drm_connector *connector) static void intel_dp_destroy (struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); + if (intel_encoder->i2c_bus) + intel_i2c_destroy(intel_encoder->i2c_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { @@ -1290,12 +1290,12 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = { }; void -intel_dp_hot_plug(struct intel_output *intel_output) +intel_dp_hot_plug(struct intel_encoder *intel_encoder) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) - intel_dp_check_link_status(intel_output); + intel_dp_check_link_status(intel_encoder); } void @@ -1303,53 +1303,53 @@ intel_dp_init(struct drm_device *dev, int output_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_dp_priv *dp_priv; const char *name = NULL; - intel_output = kcalloc(sizeof(struct intel_output) + + intel_encoder = kcalloc(sizeof(struct intel_encoder) + sizeof(struct intel_dp_priv), 1, GFP_KERNEL); - if (!intel_output) + if (!intel_encoder) return; - dp_priv = (struct intel_dp_priv *)(intel_output + 1); + dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); - connector = &intel_output->base; + connector = &intel_encoder->base; drm_connector_init(dev, connector, &intel_dp_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); if (output_reg == DP_A) - intel_output->type = INTEL_OUTPUT_EDP; + intel_encoder->type = INTEL_OUTPUT_EDP; else - intel_output->type = INTEL_OUTPUT_DISPLAYPORT; + intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; if (output_reg == DP_B || output_reg == PCH_DP_B) - intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); + intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); else if (output_reg == DP_C || output_reg == PCH_DP_C) - intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); + intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); else if (output_reg == DP_D || output_reg == PCH_DP_D) - intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); + intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); - if (IS_eDP(intel_output)) - intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT); + if (IS_eDP(intel_encoder)) + intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = true; connector->doublescan_allowed = 0; - dp_priv->intel_output = intel_output; + dp_priv->intel_encoder = intel_encoder; dp_priv->output_reg = output_reg; dp_priv->has_audio = false; dp_priv->dpms_mode = DRM_MODE_DPMS_ON; - intel_output->dev_priv = dp_priv; + intel_encoder->dev_priv = dp_priv; - drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs); - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, + &intel_encoder->enc); drm_sysfs_connector_add(connector); /* Set up the DDC bus. */ @@ -1377,10 +1377,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) break; } - intel_dp_i2c_init(intel_output, name); + intel_dp_i2c_init(intel_encoder, name); - intel_output->ddc_bus = &dp_priv->adapter; - intel_output->hot_plug = intel_dp_hot_plug; + intel_encoder->ddc_bus = &dp_priv->adapter; + intel_encoder->hot_plug = intel_dp_hot_plug; if (output_reg == DP_A) { /* initialize panel mode from VBT if available for eDP */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3a467ca..e302537 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -95,7 +95,7 @@ struct intel_framebuffer { }; -struct intel_output { +struct intel_encoder { struct drm_connector base; struct drm_encoder enc; @@ -105,7 +105,7 @@ struct intel_output { bool load_detect_temp; bool needs_tv_clock; void *dev_priv; - void (*hot_plug)(struct intel_output *); + void (*hot_plug)(struct intel_encoder *); int crtc_mask; int clone_mask; }; @@ -152,15 +152,15 @@ struct intel_crtc { }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) -#define to_intel_output(x) container_of(x, struct intel_output, base) -#define enc_to_intel_output(x) container_of(x, struct intel_output, enc) +#define to_intel_encoder(x) container_of(x, struct intel_encoder, base) +#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, const char *name); void intel_i2c_destroy(struct i2c_adapter *adapter); -int intel_ddc_get_modes(struct intel_output *intel_output); -extern bool intel_ddc_probe(struct intel_output *intel_output); +int intel_ddc_get_modes(struct intel_encoder *intel_encoder); +extern bool intel_ddc_probe(struct intel_encoder *intel_encoder); void intel_i2c_quirk_set(struct drm_device *dev, bool enable); void intel_i2c_reset_gmbus(struct drm_device *dev); @@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg); void intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); -extern void intel_edp_link_config (struct intel_output *, int *, int *); +extern void intel_edp_link_config (struct intel_encoder *, int *, int *); extern int intel_panel_fitter_pipe (struct drm_device *dev); @@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void intel_wait_for_vblank(struct drm_device *dev); extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); -extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, +extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, struct drm_display_mode *mode, int *dpms_mode); -extern void intel_release_load_detect_pipe(struct intel_output *intel_output, +extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode); extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a4d2606..62282f3 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -79,8 +79,8 @@ static struct intel_dvo_device intel_dvo_devices[] = { static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) { struct drm_i915_private *dev_priv = encoder->dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; u32 dvo_reg = dvo->dvo_reg; u32 temp = I915_READ(dvo_reg); @@ -98,8 +98,8 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) static void intel_dvo_save(struct drm_connector *connector) { struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; /* Each output should probably just save the registers it touches, * but for now, use more overkill. @@ -114,8 +114,8 @@ static void intel_dvo_save(struct drm_connector *connector) static void intel_dvo_restore(struct drm_connector *connector) { struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; dvo->dev_ops->restore(dvo); @@ -127,8 +127,8 @@ static void intel_dvo_restore(struct drm_connector *connector) static int intel_dvo_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; @@ -149,8 +149,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; /* If we have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, @@ -185,8 +185,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; int pipe = intel_crtc->pipe; u32 dvo_val; u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; @@ -240,23 +240,23 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, */ static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; return dvo->dev_ops->detect(dvo); } static int intel_dvo_get_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; /* We should probably have an i2c driver get_modes function for those * devices which will have a fixed set of modes determined by the chip * (TV-out, for example), but for now with just TMDS and LVDS, * that's not the case. */ - intel_ddc_get_modes(intel_output); + intel_ddc_get_modes(intel_encoder); if (!list_empty(&connector->probed_modes)) return 1; @@ -274,8 +274,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector) static void intel_dvo_destroy (struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; if (dvo) { if (dvo->dev_ops->destroy) @@ -285,13 +285,13 @@ static void intel_dvo_destroy (struct drm_connector *connector) /* no need, in i830_dvoices[] now */ //kfree(dvo); } - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_encoder->i2c_bus) + intel_i2c_destroy(intel_encoder->i2c_bus); + if (intel_encoder->ddc_bus) + intel_i2c_destroy(intel_encoder->ddc_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } #ifdef RANDR_GET_CRTC_INTERFACE @@ -299,8 +299,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT); return intel_pipe_to_crtc(pScrn, pipe); @@ -351,8 +351,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; uint32_t dvo_reg = dvo->dvo_reg; uint32_t dvo_val = I915_READ(dvo_reg); struct drm_display_mode *mode = NULL; @@ -382,24 +382,24 @@ intel_dvo_get_current_mode (struct drm_connector *connector) void intel_dvo_init(struct drm_device *dev) { - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_dvo_device *dvo; struct i2c_adapter *i2cbus = NULL; int ret = 0; int i; int encoder_type = DRM_MODE_ENCODER_NONE; - intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); - if (!intel_output) + intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL); + if (!intel_encoder) return; /* Set up the DDC bus */ - intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); - if (!intel_output->ddc_bus) + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); + if (!intel_encoder->ddc_bus) goto free_intel; /* Now, try to find a controller */ for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { - struct drm_connector *connector = &intel_output->base; + struct drm_connector *connector = &intel_encoder->base; int gpio; dvo = &intel_dvo_devices[i]; @@ -434,11 +434,11 @@ void intel_dvo_init(struct drm_device *dev) if (!ret) continue; - intel_output->type = INTEL_OUTPUT_DVO; - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->type = INTEL_OUTPUT_DVO; + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); switch (dvo->type) { case INTEL_DVO_CHIP_TMDS: - intel_output->clone_mask = + intel_encoder->clone_mask = (1 << INTEL_DVO_TMDS_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); drm_connector_init(dev, connector, @@ -447,7 +447,7 @@ void intel_dvo_init(struct drm_device *dev) encoder_type = DRM_MODE_ENCODER_TMDS; break; case INTEL_DVO_CHIP_LVDS: - intel_output->clone_mask = + intel_encoder->clone_mask = (1 << INTEL_DVO_LVDS_CLONE_BIT); drm_connector_init(dev, connector, &intel_dvo_connector_funcs, @@ -462,16 +462,16 @@ void intel_dvo_init(struct drm_device *dev) connector->interlace_allowed = false; connector->doublescan_allowed = false; - intel_output->dev_priv = dvo; - intel_output->i2c_bus = i2cbus; + intel_encoder->dev_priv = dvo; + intel_encoder->i2c_bus = i2cbus; - drm_encoder_init(dev, &intel_output->enc, + drm_encoder_init(dev, &intel_encoder->enc, &intel_dvo_enc_funcs, encoder_type); - drm_encoder_helper_add(&intel_output->enc, + drm_encoder_helper_add(&intel_encoder->enc, &intel_dvo_helper_funcs); - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, + &intel_encoder->enc); if (dvo->type == INTEL_DVO_CHIP_LVDS) { /* For our LVDS chipsets, we should hopefully be able * to dig the fixed panel mode out of the BIOS data. @@ -489,10 +489,10 @@ void intel_dvo_init(struct drm_device *dev) return; } - intel_i2c_destroy(intel_output->ddc_bus); + intel_i2c_destroy(intel_encoder->ddc_bus); /* Didn't find a chip, so tear down. */ if (i2cbus != NULL) intel_i2c_destroy(i2cbus); free_intel: - kfree(intel_output); + kfree(intel_encoder); } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index a30f8bf..9777504 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -50,8 +50,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; u32 sdvox; sdvox = SDVO_ENCODING_HDMI | @@ -73,8 +73,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; u32 temp; temp = I915_READ(hdmi_priv->sdvox_reg); @@ -109,8 +109,8 @@ static void intel_hdmi_save(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg); } @@ -119,8 +119,8 @@ static void intel_hdmi_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX); POSTING_READ(hdmi_priv->sdvox_reg); @@ -150,21 +150,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; struct edid *edid = NULL; enum drm_connector_status status = connector_status_disconnected; hdmi_priv->has_hdmi_sink = false; - edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); + edid = drm_get_edid(&intel_encoder->base, + intel_encoder->ddc_bus); if (edid) { if (edid->input & DRM_EDID_INPUT_DIGITAL) { status = connector_status_connected; hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); } - intel_output->base.display_info.raw_edid = NULL; + intel_encoder->base.display_info.raw_edid = NULL; kfree(edid); } @@ -173,24 +173,24 @@ intel_hdmi_detect(struct drm_connector *connector) static int intel_hdmi_get_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); /* We should parse the EDID data and find out if it's an HDMI sink so * we can send audio to it. */ - return intel_ddc_get_modes(intel_output); + return intel_ddc_get_modes(intel_encoder); } static void intel_hdmi_destroy(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); + if (intel_encoder->i2c_bus) + intel_i2c_destroy(intel_encoder->i2c_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { @@ -229,63 +229,63 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_hdmi_priv *hdmi_priv; - intel_output = kcalloc(sizeof(struct intel_output) + + intel_encoder = kcalloc(sizeof(struct intel_encoder) + sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); - if (!intel_output) + if (!intel_encoder) return; - hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1); + hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); - connector = &intel_output->base; + connector = &intel_encoder->base; drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); - intel_output->type = INTEL_OUTPUT_HDMI; + intel_encoder->type = INTEL_OUTPUT_HDMI; connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); /* Set up the DDC bus. */ if (sdvox_reg == SDVOB) { - intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); + intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == SDVOC) { - intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); + intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIB) { - intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, + intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, "HDMIB"); dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIC) { - intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, + intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, "HDMIC"); dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMID) { - intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, + intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, "HDMID"); dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; } - if (!intel_output->ddc_bus) + if (!intel_encoder->ddc_bus) goto err_connector; hdmi_priv->sdvox_reg = sdvox_reg; - intel_output->dev_priv = hdmi_priv; + intel_encoder->dev_priv = hdmi_priv; - drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs); - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, + &intel_encoder->enc); drm_sysfs_connector_add(connector); /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written @@ -301,7 +301,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) err_connector: drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); return; } diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 2b3fa7a..9d99ddc 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -238,8 +238,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct drm_encoder *tmp_encoder; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; u32 pfit_control = 0, pfit_pgm_ratios = 0; int left_border = 0, right_border = 0, top_border = 0; int bottom_border = 0; @@ -586,8 +586,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; /* * The LVDS pin pair will already have been turned on in the @@ -634,11 +634,11 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect static int intel_lvds_get_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); struct drm_i915_private *dev_priv = dev->dev_private; int ret = 0; - ret = intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_encoder); if (ret) return ret; @@ -714,11 +714,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, static void intel_lvds_destroy(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); struct drm_i915_private *dev_priv = dev->dev_private; - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_encoder->ddc_bus) + intel_i2c_destroy(intel_encoder->ddc_bus); if (dev_priv->lid_notifier.notifier_call) acpi_lid_notifier_unregister(&dev_priv->lid_notifier); drm_sysfs_connector_remove(connector); @@ -731,13 +731,13 @@ static int intel_lvds_set_property(struct drm_connector *connector, uint64_t value) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = - to_intel_output(connector); + struct intel_encoder *intel_encoder = + to_intel_encoder(connector); if (property == dev->mode_config.scaling_mode_property && connector->encoder) { struct drm_crtc *crtc = connector->encoder->crtc; - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; + struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; if (value == DRM_MODE_SCALE_NONE) { DRM_DEBUG_KMS("no scaling not supported\n"); return 0; @@ -967,7 +967,7 @@ static int lvds_is_present_in_vbt(struct drm_device *dev) void intel_lvds_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct drm_connector *connector; struct drm_encoder *encoder; struct drm_display_mode *scan; /* *modes, *bios_mode; */ @@ -995,40 +995,40 @@ void intel_lvds_init(struct drm_device *dev) gpio = PCH_GPIOC; } - intel_output = kzalloc(sizeof(struct intel_output) + + intel_encoder = kzalloc(sizeof(struct intel_encoder) + sizeof(struct intel_lvds_priv), GFP_KERNEL); - if (!intel_output) { + if (!intel_encoder) { return; } - connector = &intel_output->base; - encoder = &intel_output->enc; - drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs, + connector = &intel_encoder->base; + encoder = &intel_encoder->enc; + drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs, DRM_MODE_CONNECTOR_LVDS); - drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); - drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); - intel_output->type = INTEL_OUTPUT_LVDS; + drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); + intel_encoder->type = INTEL_OUTPUT_LVDS; - intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); - intel_output->crtc_mask = (1 << 1); + intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); + intel_encoder->crtc_mask = (1 << 1); drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = false; connector->doublescan_allowed = false; - lvds_priv = (struct intel_lvds_priv *)(intel_output + 1); - intel_output->dev_priv = lvds_priv; + lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1); + intel_encoder->dev_priv = lvds_priv; /* create the scaling mode property */ drm_mode_create_scaling_mode_property(dev); /* * the initial panel fitting mode will be FULL_SCREEN. */ - drm_connector_attach_property(&intel_output->base, + drm_connector_attach_property(&intel_encoder->base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; @@ -1043,8 +1043,8 @@ void intel_lvds_init(struct drm_device *dev) */ /* Set up the DDC bus. */ - intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); - if (!intel_output->ddc_bus) { + intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); + if (!intel_encoder->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); goto failed; @@ -1054,7 +1054,7 @@ void intel_lvds_init(struct drm_device *dev) * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. */ - intel_ddc_get_modes(intel_output); + intel_ddc_get_modes(intel_encoder); list_for_each_entry(scan, &connector->probed_modes, head) { mutex_lock(&dev->mode_config.mutex); @@ -1132,9 +1132,9 @@ out: failed: DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_encoder->ddc_bus) + intel_i2c_destroy(intel_encoder->ddc_bus); drm_connector_cleanup(connector); drm_encoder_cleanup(encoder); - kfree(intel_output); + kfree(intel_encoder); } diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 67e2f46..3111a1c 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -33,7 +33,7 @@ * intel_ddc_probe * */ -bool intel_ddc_probe(struct intel_output *intel_output) +bool intel_ddc_probe(struct intel_encoder *intel_encoder) { u8 out_buf[] = { 0x0, 0x0}; u8 buf[2]; @@ -53,9 +53,9 @@ bool intel_ddc_probe(struct intel_output *intel_output) } }; - intel_i2c_quirk_set(intel_output->base.dev, true); - ret = i2c_transfer(intel_output->ddc_bus, msgs, 2); - intel_i2c_quirk_set(intel_output->base.dev, false); + intel_i2c_quirk_set(intel_encoder->base.dev, true); + ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2); + intel_i2c_quirk_set(intel_encoder->base.dev, false); if (ret == 2) return true; @@ -68,19 +68,19 @@ bool intel_ddc_probe(struct intel_output *intel_output) * * Fetch the EDID information from @connector using the DDC bus. */ -int intel_ddc_get_modes(struct intel_output *intel_output) +int intel_ddc_get_modes(struct intel_encoder *intel_encoder) { struct edid *edid; int ret = 0; - intel_i2c_quirk_set(intel_output->base.dev, true); - edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); - intel_i2c_quirk_set(intel_output->base.dev, false); + intel_i2c_quirk_set(intel_encoder->base.dev, true); + edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus); + intel_i2c_quirk_set(intel_encoder->base.dev, false); if (edid) { - drm_mode_connector_update_edid_property(&intel_output->base, + drm_mode_connector_update_edid_property(&intel_encoder->base, edid); - ret = drm_add_edid_modes(&intel_output->base, edid); - intel_output->base.display_info.raw_edid = NULL; + ret = drm_add_edid_modes(&intel_encoder->base, edid); + intel_encoder->base.display_info.raw_edid = NULL; kfree(edid); } diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 48daee5..ea6de3b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -161,18 +161,18 @@ struct intel_sdvo_priv { }; static bool -intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags); +intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags); /** * Writes the SDVOB or SDVOC with the given value, but always writes both * SDVOB and SDVOC to work around apparent hardware issues (according to * comments in the BIOS). */ -static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val) +static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) { - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u32 bval = val, cval = val; int i; @@ -195,10 +195,10 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val) } } -static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, +static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, u8 *ch) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u8 out_buf[2]; u8 buf[2]; int ret; @@ -221,7 +221,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, out_buf[0] = addr; out_buf[1] = 0; - if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) + if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2) { *ch = buf[0]; return true; @@ -231,10 +231,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, return false; } -static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, +static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr, u8 ch) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u8 out_buf[2]; struct i2c_msg msgs[] = { { @@ -248,7 +248,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, out_buf[0] = addr; out_buf[1] = ch; - if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) + if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1) { return true; } @@ -355,10 +355,10 @@ static const struct _sdvo_cmd_name { #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") #define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv) -static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, +static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, void *args, int args_len) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int i; DRM_DEBUG_KMS("%s: W: %02X ", @@ -378,19 +378,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, DRM_LOG_KMS("\n"); } -static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd, +static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd, void *args, int args_len) { int i; - intel_sdvo_debug_write(intel_output, cmd, args, args_len); + intel_sdvo_debug_write(intel_encoder, cmd, args, args_len); for (i = 0; i < args_len; i++) { - intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i, + intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i, ((u8*)args)[i]); } - intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd); + intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd); } static const char *cmd_status_names[] = { @@ -403,11 +403,11 @@ static const char *cmd_status_names[] = { "Scaling not supported" }; -static void intel_sdvo_debug_response(struct intel_output *intel_output, +static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, void *response, int response_len, u8 status) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int i; DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); @@ -422,7 +422,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output, DRM_LOG_KMS("\n"); } -static u8 intel_sdvo_read_response(struct intel_output *intel_output, +static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, void *response, int response_len) { int i; @@ -432,16 +432,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output, while (retry--) { /* Read the command response */ for (i = 0; i < response_len; i++) { - intel_sdvo_read_byte(intel_output, + intel_sdvo_read_byte(intel_encoder, SDVO_I2C_RETURN_0 + i, &((u8 *)response)[i]); } /* read the return status */ - intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS, + intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS, &status); - intel_sdvo_debug_response(intel_output, response, response_len, + intel_sdvo_debug_response(intel_encoder, response, response_len, status); if (status != SDVO_CMD_STATUS_PENDING) return status; @@ -469,10 +469,10 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) * another I2C transaction after issuing the DDC bus switch, it will be * switched to the internal SDVO register. */ -static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, +static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder, u8 target) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u8 out_buf[2], cmd_buf[2], ret_value[2], ret; struct i2c_msg msgs[] = { { @@ -496,10 +496,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, }, }; - intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, + intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1); /* write the DDC switch command argument */ - intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target); + intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target); out_buf[0] = SDVO_I2C_OPCODE; out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; @@ -508,7 +508,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, ret_value[0] = 0; ret_value[1] = 0; - ret = i2c_transfer(intel_output->i2c_bus, msgs, 3); + ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3); if (ret != 3) { /* failure in I2C transfer */ DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); @@ -522,7 +522,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, return; } -static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) +static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1) { struct intel_sdvo_set_target_input_args targets = {0}; u8 status; @@ -533,10 +533,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool if (target_1) targets.target_1 = 1; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets, sizeof(targets)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } @@ -547,13 +547,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool * This function is making an assumption about the layout of the response, * which should be checked against the docs. */ -static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2) +static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2) { struct intel_sdvo_get_trained_inputs_response response; u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, sizeof(response)); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -562,29 +562,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo return true; } -static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output, +static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder, u16 *outputs) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); - status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs)); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs)); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output, +static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, u16 outputs) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, sizeof(outputs)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output, +static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder, int mode) { u8 status, state = SDVO_ENCODER_STATE_ON; @@ -604,24 +604,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output break; } - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output, +static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder, int *clock_min, int *clock_max) { struct intel_sdvo_pixel_clock_range clocks; u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL, 0); - status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks)); + status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -633,31 +633,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou return true; } -static bool intel_sdvo_set_target_output(struct intel_output *intel_output, +static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, u16 outputs) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, sizeof(outputs)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd, +static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd, struct intel_sdvo_dtd *dtd) { u8 status; - intel_sdvo_write_cmd(intel_output, cmd, NULL, 0); - status = intel_sdvo_read_response(intel_output, &dtd->part1, + intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &dtd->part1, sizeof(dtd->part1)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; - intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0); - status = intel_sdvo_read_response(intel_output, &dtd->part2, + intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &dtd->part2, sizeof(dtd->part2)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -665,54 +665,54 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd, return true; } -static bool intel_sdvo_get_input_timing(struct intel_output *intel_output, +static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { - return intel_sdvo_get_timing(intel_output, + return intel_sdvo_get_timing(intel_encoder, SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); } -static bool intel_sdvo_get_output_timing(struct intel_output *intel_output, +static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { - return intel_sdvo_get_timing(intel_output, + return intel_sdvo_get_timing(intel_encoder, SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd); } -static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd, +static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, struct intel_sdvo_dtd *dtd) { u8 status; - intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1)); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) return false; - intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2)); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) return false; return true; } -static bool intel_sdvo_set_input_timing(struct intel_output *intel_output, +static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { - return intel_sdvo_set_timing(intel_output, + return intel_sdvo_set_timing(intel_encoder, SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); } -static bool intel_sdvo_set_output_timing(struct intel_output *intel_output, +static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { - return intel_sdvo_set_timing(intel_output, + return intel_sdvo_set_timing(intel_encoder, SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); } static bool -intel_sdvo_create_preferred_input_timing(struct intel_output *output, +intel_sdvo_create_preferred_input_timing(struct intel_encoder *output, uint16_t clock, uint16_t width, uint16_t height) @@ -741,7 +741,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, return true; } -static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, +static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *output, struct intel_sdvo_dtd *dtd) { bool status; @@ -765,12 +765,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, return false; } -static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) +static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder) { u8 response, status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, 1); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &response, 1); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n"); @@ -782,12 +782,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) return response; } -static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val) +static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); - status = intel_sdvo_read_response(intel_output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -876,7 +876,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, mode->flags |= DRM_MODE_FLAG_PVSYNC; } -static bool intel_sdvo_get_supp_encode(struct intel_output *output, +static bool intel_sdvo_get_supp_encode(struct intel_encoder *output, struct intel_sdvo_encode *encode) { uint8_t status; @@ -891,7 +891,7 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output, return true; } -static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode) +static bool intel_sdvo_set_encode(struct intel_encoder *output, uint8_t mode) { uint8_t status; @@ -901,7 +901,7 @@ static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode) return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_set_colorimetry(struct intel_output *output, +static bool intel_sdvo_set_colorimetry(struct intel_encoder *output, uint8_t mode) { uint8_t status; @@ -913,7 +913,7 @@ static bool intel_sdvo_set_colorimetry(struct intel_output *output, } #if 0 -static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) +static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *output) { int i, j; uint8_t set_buf_index[2]; @@ -943,7 +943,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) } #endif -static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index, +static void intel_sdvo_set_hdmi_buf(struct intel_encoder *output, int index, uint8_t *data, int8_t size, uint8_t tx_rate) { uint8_t set_buf_index[2]; @@ -1033,7 +1033,7 @@ struct dip_infoframe { } __attribute__ ((packed)) u; } __attribute__((packed)); -static void intel_sdvo_set_avi_infoframe(struct intel_output *output, +static void intel_sdvo_set_avi_infoframe(struct intel_encoder *output, struct drm_display_mode * mode) { struct dip_infoframe avi_if = { @@ -1048,7 +1048,7 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, SDVO_HBUF_TX_VSYNC); } -static void intel_sdvo_set_tv_format(struct intel_output *output) +static void intel_sdvo_set_tv_format(struct intel_encoder *output) { struct intel_sdvo_tv_format format; @@ -1078,7 +1078,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *output = enc_to_intel_output(encoder); + struct intel_encoder *output = enc_to_intel_encoder(encoder); struct intel_sdvo_priv *dev_priv = output->dev_priv; if (dev_priv->is_tv) { @@ -1181,7 +1181,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *output = enc_to_intel_output(encoder); + struct intel_encoder *output = enc_to_intel_encoder(encoder); struct intel_sdvo_priv *sdvo_priv = output->dev_priv; u32 sdvox = 0; int sdvo_pixel_multiply; @@ -1305,19 +1305,19 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u32 temp; if (mode != DRM_MODE_DPMS_ON) { - intel_sdvo_set_active_outputs(intel_output, 0); + intel_sdvo_set_active_outputs(intel_encoder, 0); if (0) - intel_sdvo_set_encoder_power_state(intel_output, mode); + intel_sdvo_set_encoder_power_state(intel_encoder, mode); if (mode == DRM_MODE_DPMS_OFF) { temp = I915_READ(sdvo_priv->output_device); if ((temp & SDVO_ENABLE) != 0) { - intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE); + intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); } } } else { @@ -1327,11 +1327,11 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) temp = I915_READ(sdvo_priv->output_device); if ((temp & SDVO_ENABLE) == 0) - intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE); + intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); for (i = 0; i < 2; i++) intel_wait_for_vblank(dev); - status = intel_sdvo_get_trained_inputs(intel_output, &input1, + status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2); @@ -1345,8 +1345,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) } if (0) - intel_sdvo_set_encoder_power_state(intel_output, mode); - intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output); + intel_sdvo_set_encoder_power_state(intel_encoder, mode); + intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output); } return; } @@ -1355,22 +1355,22 @@ static void intel_sdvo_save(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int o; - sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output); - intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs); + sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder); + intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs); if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - intel_sdvo_set_target_input(intel_output, true, false); - intel_sdvo_get_input_timing(intel_output, + intel_sdvo_set_target_input(intel_encoder, true, false); + intel_sdvo_get_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1); } if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - intel_sdvo_set_target_input(intel_output, false, true); - intel_sdvo_get_input_timing(intel_output, + intel_sdvo_set_target_input(intel_encoder, false, true); + intel_sdvo_get_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2); } @@ -1379,8 +1379,8 @@ static void intel_sdvo_save(struct drm_connector *connector) u16 this_output = (1 << o); if (sdvo_priv->caps.output_flags & this_output) { - intel_sdvo_set_target_output(intel_output, this_output); - intel_sdvo_get_output_timing(intel_output, + intel_sdvo_set_target_output(intel_encoder, this_output); + intel_sdvo_get_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]); } } @@ -1394,60 +1394,60 @@ static void intel_sdvo_save(struct drm_connector *connector) static void intel_sdvo_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int o; int i; bool input1, input2; u8 status; - intel_sdvo_set_active_outputs(intel_output, 0); + intel_sdvo_set_active_outputs(intel_encoder, 0); for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) { u16 this_output = (1 << o); if (sdvo_priv->caps.output_flags & this_output) { - intel_sdvo_set_target_output(intel_output, this_output); - intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]); + intel_sdvo_set_target_output(intel_encoder, this_output); + intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]); } } if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - intel_sdvo_set_target_input(intel_output, true, false); - intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1); + intel_sdvo_set_target_input(intel_encoder, true, false); + intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1); } if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - intel_sdvo_set_target_input(intel_output, false, true); - intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2); + intel_sdvo_set_target_input(intel_encoder, false, true); + intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2); } - intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult); + intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult); if (sdvo_priv->is_tv) { /* XXX: Restore TV format/enhancements. */ } - intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX); + intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX); if (sdvo_priv->save_SDVOX & SDVO_ENABLE) { for (i = 0; i < 2; i++) intel_wait_for_vblank(dev); - status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2); + status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2); if (status == SDVO_CMD_STATUS_SUCCESS && !input1) DRM_DEBUG_KMS("First %s output reported failure to " "sync\n", SDVO_NAME(sdvo_priv)); } - intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs); + intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs); } static int intel_sdvo_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; @@ -1472,12 +1472,12 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, return MODE_OK; } -static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps) +static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); - status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps)); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -1487,12 +1487,12 @@ static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struc struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) { struct drm_connector *connector = NULL; - struct intel_output *iout = NULL; + struct intel_encoder *iout = NULL; struct intel_sdvo_priv *sdvo; /* find the sdvo connector */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - iout = to_intel_output(connector); + iout = to_intel_encoder(connector); if (iout->type != INTEL_OUTPUT_SDVO) continue; @@ -1514,16 +1514,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) { u8 response[2]; u8 status; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; DRM_DEBUG_KMS("\n"); if (!connector) return 0; - intel_output = to_intel_output(connector); + intel_encoder = to_intel_encoder(connector); - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (response[0] !=0) return 1; @@ -1535,30 +1535,30 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) { u8 response[2]; u8 status; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); - intel_sdvo_read_response(intel_output, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); + intel_sdvo_read_response(intel_encoder, &response, 2); if (on) { - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &response, 2); - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); } else { response[0] = 0; response[1] = 0; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); } - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); - intel_sdvo_read_response(intel_output, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); + intel_sdvo_read_response(intel_encoder, &response, 2); } static bool -intel_sdvo_multifunc_encoder(struct intel_output *intel_output) +intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int caps = 0; if (sdvo_priv->caps.output_flags & @@ -1592,11 +1592,11 @@ static struct drm_connector * intel_find_analog_connector(struct drm_device *dev) { struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - intel_output = to_intel_output(connector); - if (intel_output->type == INTEL_OUTPUT_ANALOG) + intel_encoder = to_intel_encoder(connector); + if (intel_encoder->type == INTEL_OUTPUT_ANALOG) return connector; } return NULL; @@ -1621,16 +1621,16 @@ intel_analog_is_connected(struct drm_device *dev) enum drm_connector_status intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; enum drm_connector_status status = connector_status_connected; struct edid *edid = NULL; - edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); + edid = drm_get_edid(&intel_encoder->base, + intel_encoder->ddc_bus); /* This is only applied to SDVO cards with multiple outputs */ - if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) { + if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { uint8_t saved_ddc, temp_ddc; saved_ddc = sdvo_priv->ddc_bus; temp_ddc = sdvo_priv->ddc_bus >> 1; @@ -1640,8 +1640,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) */ while(temp_ddc > 1) { sdvo_priv->ddc_bus = temp_ddc; - edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); + edid = drm_get_edid(&intel_encoder->base, + intel_encoder->ddc_bus); if (edid) { /* * When we can get the EDID, maybe it is the @@ -1660,8 +1660,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) */ if (edid == NULL && sdvo_priv->analog_ddc_bus && - !intel_analog_is_connected(intel_output->base.dev)) - edid = drm_get_edid(&intel_output->base, + !intel_analog_is_connected(intel_encoder->base.dev)) + edid = drm_get_edid(&intel_encoder->base, sdvo_priv->analog_ddc_bus); if (edid != NULL) { /* Don't report the output as connected if it's a DVI-I @@ -1676,7 +1676,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) } kfree(edid); - intel_output->base.display_info.raw_edid = NULL; + intel_encoder->base.display_info.raw_edid = NULL; } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) status = connector_status_disconnected; @@ -1688,16 +1688,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect { uint16_t response; u8 status; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); if (sdvo_priv->is_tv) { /* add 30ms delay when the output type is SDVO-TV */ mdelay(30); } - status = intel_sdvo_read_response(intel_output, &response, 2); + status = intel_sdvo_read_response(intel_encoder, &response, 2); DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); @@ -1707,10 +1707,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect if (response == 0) return connector_status_disconnected; - if (intel_sdvo_multifunc_encoder(intel_output) && + if (intel_sdvo_multifunc_encoder(intel_encoder) && sdvo_priv->attached_output != response) { if (sdvo_priv->controlled_output != response && - intel_sdvo_output_setup(intel_output, response) != true) + intel_sdvo_output_setup(intel_encoder, response) != true) return connector_status_unknown; sdvo_priv->attached_output = response; } @@ -1719,12 +1719,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int num_modes; /* set the bus switch and get the modes */ - num_modes = intel_ddc_get_modes(intel_output); + num_modes = intel_ddc_get_modes(intel_encoder); /* * Mac mini hack. On this device, the DVI-I connector shares one DDC @@ -1734,17 +1734,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) */ if (num_modes == 0 && sdvo_priv->analog_ddc_bus && - !intel_analog_is_connected(intel_output->base.dev)) { + !intel_analog_is_connected(intel_encoder->base.dev)) { struct i2c_adapter *digital_ddc_bus; /* Switch to the analog ddc bus and try that */ - digital_ddc_bus = intel_output->ddc_bus; - intel_output->ddc_bus = sdvo_priv->analog_ddc_bus; + digital_ddc_bus = intel_encoder->ddc_bus; + intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus; - (void) intel_ddc_get_modes(intel_output); + (void) intel_ddc_get_modes(intel_encoder); - intel_output->ddc_bus = digital_ddc_bus; + intel_encoder->ddc_bus = digital_ddc_bus; } } @@ -1815,7 +1815,7 @@ struct drm_display_mode sdvo_tv_modes[] = { static void intel_sdvo_get_tv_modes(struct drm_connector *connector) { - struct intel_output *output = to_intel_output(connector); + struct intel_encoder *output = to_intel_encoder(connector); struct intel_sdvo_priv *sdvo_priv = output->dev_priv; struct intel_sdvo_sdtv_resolution_request tv_res; uint32_t reply = 0, format_map = 0; @@ -1857,9 +1857,9 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct drm_display_mode *newmode; /* @@ -1867,7 +1867,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) * Assume that the preferred modes are * arranged in priority order. */ - intel_ddc_get_modes(intel_output); + intel_ddc_get_modes(intel_encoder); if (list_empty(&connector->probed_modes) == false) goto end; @@ -1896,7 +1896,7 @@ end: static int intel_sdvo_get_modes(struct drm_connector *connector) { - struct intel_output *output = to_intel_output(connector); + struct intel_encoder *output = to_intel_encoder(connector); struct intel_sdvo_priv *sdvo_priv = output->dev_priv; if (sdvo_priv->is_tv) @@ -1914,8 +1914,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) static void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct drm_device *dev = connector->dev; if (sdvo_priv->is_tv) { @@ -1952,13 +1952,13 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) static void intel_sdvo_destroy(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_encoder->i2c_bus) + intel_i2c_destroy(intel_encoder->i2c_bus); + if (intel_encoder->ddc_bus) + intel_i2c_destroy(intel_encoder->ddc_bus); if (sdvo_priv->analog_ddc_bus) intel_i2c_destroy(sdvo_priv->analog_ddc_bus); @@ -1976,7 +1976,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector) drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } static int @@ -1984,9 +1984,9 @@ intel_sdvo_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t val) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_crtc *crtc = encoder->crtc; int ret = 0; bool changed = false; @@ -2094,8 +2094,8 @@ intel_sdvo_set_property(struct drm_connector *connector, sdvo_priv->cur_brightness = temp_value; } if (cmd) { - intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2); - status = intel_sdvo_read_response(intel_output, + intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO command \n"); @@ -2190,7 +2190,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) } static bool -intel_sdvo_get_digital_encoding_mode(struct intel_output *output) +intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output) { struct intel_sdvo_priv *sdvo_priv = output->dev_priv; uint8_t status; @@ -2204,42 +2204,42 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output) return true; } -static struct intel_output * -intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) +static struct intel_encoder * +intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) { struct drm_device *dev = chan->drm_dev; struct drm_connector *connector; - struct intel_output *intel_output = NULL; + struct intel_encoder *intel_encoder = NULL; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (to_intel_output(connector)->ddc_bus == &chan->adapter) { - intel_output = to_intel_output(connector); + if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) { + intel_encoder = to_intel_encoder(connector); break; } } - return intel_output; + return intel_encoder; } static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_sdvo_priv *sdvo_priv; struct i2c_algo_bit_data *algo_data; const struct i2c_algorithm *algo; algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; - intel_output = - intel_sdvo_chan_to_intel_output( + intel_encoder = + intel_sdvo_chan_to_intel_encoder( (struct intel_i2c_chan *)(algo_data->data)); - if (intel_output == NULL) + if (intel_encoder == NULL) return -EINVAL; - sdvo_priv = intel_output->dev_priv; - algo = intel_output->i2c_bus->algo; + sdvo_priv = intel_encoder->dev_priv; + algo = intel_encoder->i2c_bus->algo; - intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); + intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus); return algo->master_xfer(i2c_adap, msgs, num); } @@ -2304,15 +2304,15 @@ static struct dmi_system_id intel_sdvo_bad_tv[] = { }; static bool -intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) +intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) { - struct drm_connector *connector = &intel_output->base; - struct drm_encoder *encoder = &intel_output->enc; - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct drm_connector *connector = &intel_encoder->base; + struct drm_encoder *encoder = &intel_encoder->enc; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; bool ret = true, registered = false; sdvo_priv->is_tv = false; - intel_output->needs_tv_clock = false; + intel_encoder->needs_tv_clock = false; sdvo_priv->is_lvds = false; if (device_is_registered(&connector->kdev)) { @@ -2330,16 +2330,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_TMDS; connector->connector_type = DRM_MODE_CONNECTOR_DVID; - if (intel_sdvo_get_supp_encode(intel_output, + if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode) && - intel_sdvo_get_digital_encoding_mode(intel_output) && + intel_sdvo_get_digital_encoding_mode(intel_encoder) && sdvo_priv->is_hdmi) { /* enable hdmi encoding mode if supported */ - intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); - intel_sdvo_set_colorimetry(intel_output, + intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); + intel_sdvo_set_colorimetry(intel_encoder, SDVO_COLORIMETRY_RGB256); connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; - intel_output->clone_mask = + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); } @@ -2350,21 +2350,21 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; sdvo_priv->is_tv = true; - intel_output->needs_tv_clock = true; - intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; + intel_encoder->needs_tv_clock = true; + intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; } else if (flags & SDVO_OUTPUT_RGB0) { sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; encoder->encoder_type = DRM_MODE_ENCODER_DAC; connector->connector_type = DRM_MODE_CONNECTOR_VGA; - intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); } else if (flags & SDVO_OUTPUT_RGB1) { sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; encoder->encoder_type = DRM_MODE_ENCODER_DAC; connector->connector_type = DRM_MODE_CONNECTOR_VGA; - intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); } else if (flags & SDVO_OUTPUT_CVBS0) { @@ -2372,15 +2372,15 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; sdvo_priv->is_tv = true; - intel_output->needs_tv_clock = true; - intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; + intel_encoder->needs_tv_clock = true; + intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; } else if (flags & SDVO_OUTPUT_LVDS0) { sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; encoder->encoder_type = DRM_MODE_ENCODER_LVDS; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; sdvo_priv->is_lvds = true; - intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | + intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | (1 << INTEL_SDVO_LVDS_CLONE_BIT); } else if (flags & SDVO_OUTPUT_LVDS1) { @@ -2388,7 +2388,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_LVDS; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; sdvo_priv->is_lvds = true; - intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | + intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | (1 << INTEL_SDVO_LVDS_CLONE_BIT); } else { @@ -2401,7 +2401,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) bytes[0], bytes[1]); ret = false; } - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); if (ret && registered) ret = drm_sysfs_connector_add(connector) == 0 ? true : false; @@ -2413,18 +2413,18 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) static void intel_sdvo_tv_create_property(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct intel_sdvo_tv_format format; uint32_t format_map, i; uint8_t status; - intel_sdvo_set_target_output(intel_output, + intel_sdvo_set_target_output(intel_encoder, sdvo_priv->controlled_output); - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &format, sizeof(format)); if (status != SDVO_CMD_STATUS_SUCCESS) return; @@ -2462,16 +2462,16 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector) static void intel_sdvo_create_enhance_property(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct intel_sdvo_enhancements_reply sdvo_data; struct drm_device *dev = connector->dev; uint8_t status; uint16_t response, data_value[2]; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, NULL, 0); - status = intel_sdvo_read_response(intel_output, &sdvo_data, + status = intel_sdvo_read_response(intel_encoder, &sdvo_data, sizeof(sdvo_data)); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS(" incorrect response is returned\n"); @@ -2487,18 +2487,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) * property */ if (sdvo_data.overscan_h) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO max " "h_overscan\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_OVERSCAN_H, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); @@ -2528,18 +2528,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.overscan_v) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO max " "v_overscan\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_OVERSCAN_V, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); @@ -2569,17 +2569,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.position_h) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_POSITION_H, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); @@ -2600,17 +2600,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.position_v) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_POSITION_V, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); @@ -2633,17 +2633,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) } if (sdvo_priv->is_tv) { if (sdvo_data.saturation) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_SATURATION, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SATURATION, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); @@ -2665,17 +2665,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.contrast) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CONTRAST, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); @@ -2696,17 +2696,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.hue) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_HUE, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HUE, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); @@ -2729,17 +2729,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) } if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { if (sdvo_data.brightness) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_BRIGHTNESS, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); @@ -2768,40 +2768,40 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_sdvo_priv *sdvo_priv; u8 ch[0x40]; int i; - intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); - if (!intel_output) { + intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); + if (!intel_encoder) { return false; } - sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); + sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); sdvo_priv->output_device = output_device; - intel_output->dev_priv = sdvo_priv; - intel_output->type = INTEL_OUTPUT_SDVO; + intel_encoder->dev_priv = sdvo_priv; + intel_encoder->type = INTEL_OUTPUT_SDVO; /* setup the DDC bus. */ if (output_device == SDVOB) - intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); + intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); else - intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); + intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); - if (!intel_output->i2c_bus) + if (!intel_encoder->i2c_bus) goto err_inteloutput; sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); /* Save the bit-banging i2c functionality for use by the DDC wrapper */ - intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; + intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; /* Read the regs to test if we can talk to the device */ for (i = 0; i < 0x40; i++) { - if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { + if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", output_device == SDVOB ? 'B' : 'C'); goto err_i2c; @@ -2810,27 +2810,27 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) /* setup the DDC bus. */ if (output_device == SDVOB) { - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOB/VGA DDC BUS"); dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; } else { - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOC/VGA DDC BUS"); dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; } - if (intel_output->ddc_bus == NULL) + if (intel_encoder->ddc_bus == NULL) goto err_i2c; /* Wrap with our custom algo which switches to DDC mode */ - intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; + intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; /* In default case sdvo lvds is false */ - intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); + intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); - if (intel_sdvo_output_setup(intel_output, + if (intel_sdvo_output_setup(intel_encoder, sdvo_priv->caps.output_flags) != true) { DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", output_device == SDVOB ? 'B' : 'C'); @@ -2838,7 +2838,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) } - connector = &intel_output->base; + connector = &intel_encoder->base; drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, connector->connector_type); @@ -2847,12 +2847,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) connector->doublescan_allowed = 0; connector->display_info.subpixel_order = SubPixelHorizontalRGB; - drm_encoder_init(dev, &intel_output->enc, - &intel_sdvo_enc_funcs, intel_output->enc.encoder_type); + drm_encoder_init(dev, &intel_encoder->enc, + &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type); - drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); - drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); if (sdvo_priv->is_tv) intel_sdvo_tv_create_property(connector); @@ -2864,9 +2864,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) intel_sdvo_select_ddc_bus(sdvo_priv); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(intel_output, true, false); + intel_sdvo_set_target_input(intel_encoder, true, false); - intel_sdvo_get_input_pixel_clock_range(intel_output, + intel_sdvo_get_input_pixel_clock_range(intel_encoder, &sdvo_priv->pixel_clock_min, &sdvo_priv->pixel_clock_max); @@ -2893,12 +2893,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) err_i2c: if (sdvo_priv->analog_ddc_bus != NULL) intel_i2c_destroy(sdvo_priv->analog_ddc_bus); - if (intel_output->ddc_bus != NULL) - intel_i2c_destroy(intel_output->ddc_bus); - if (intel_output->i2c_bus != NULL) - intel_i2c_destroy(intel_output->i2c_bus); + if (intel_encoder->ddc_bus != NULL) + intel_i2c_destroy(intel_encoder->ddc_bus); + if (intel_encoder->i2c_bus != NULL) + intel_i2c_destroy(intel_encoder->i2c_bus); err_inteloutput: - kfree(intel_output); + kfree(intel_encoder); return false; } diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 552ec11..d7d39b2 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; int i; tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1); @@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; struct drm_crtc *crtc = connector->encoder->crtc; struct intel_crtc *intel_crtc; int i; @@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format) } static const struct tv_mode * -intel_tv_mode_find (struct intel_output *intel_output) +intel_tv_mode_find (struct intel_encoder *intel_encoder) { - struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; return intel_tv_mode_lookup(tv_priv->tv_format); } @@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output *intel_output) static enum drm_mode_status intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_output *intel_output = to_intel_output(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); /* Ensure TV refresh is close to desired refresh */ if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) @@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, { struct drm_device *dev = encoder->dev; struct drm_mode_config *drm_config = &dev->mode_config; - struct intel_output *intel_output = enc_to_intel_output(encoder); - const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output); + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder); struct drm_encoder *other_encoder; if (!tv_mode) @@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); u32 tv_ctl; u32 hctl1, hctl2, hctl3; u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; @@ -1360,9 +1360,9 @@ static const struct drm_display_mode reported_modes[] = { * \return false if TV is disconnected. */ static int -intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) +intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder) { - struct drm_encoder *encoder = &intel_output->enc; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) */ static void intel_tv_find_better_format(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); int i; if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == @@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *connector) { struct drm_crtc *crtc; struct drm_display_mode mode; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; + struct drm_encoder *encoder = &intel_encoder->enc; int dpms_mode; int type = tv_priv->type; @@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *connector) drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); if (encoder->crtc && encoder->crtc->enabled) { - type = intel_tv_detect_type(encoder->crtc, intel_output); + type = intel_tv_detect_type(encoder->crtc, intel_encoder); } else { - crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode); + crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode); if (crtc) { - type = intel_tv_detect_type(crtc, intel_output); - intel_release_load_detect_pipe(intel_output, dpms_mode); + type = intel_tv_detect_type(crtc, intel_encoder); + intel_release_load_detect_pipe(intel_encoder, dpms_mode); } else type = -1; } @@ -1525,8 +1525,8 @@ static void intel_tv_chose_preferred_modes(struct drm_connector *connector, struct drm_display_mode *mode_ptr) { - struct intel_output *intel_output = to_intel_output(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; @@ -1550,8 +1550,8 @@ static int intel_tv_get_modes(struct drm_connector *connector) { struct drm_display_mode *mode_ptr; - struct intel_output *intel_output = to_intel_output(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); int j, count = 0; u64 tmp; @@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector *connector) static void intel_tv_destroy (struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } @@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop uint64_t val) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_crtc *crtc = encoder->crtc; int ret = 0; bool changed = false; @@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_tv_priv *tv_priv; u32 tv_dac_on, tv_dac_off, save_tv_dac; char **tv_format_names; @@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev) (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) return; - intel_output = kzalloc(sizeof(struct intel_output) + + intel_encoder = kzalloc(sizeof(struct intel_encoder) + sizeof(struct intel_tv_priv), GFP_KERNEL); - if (!intel_output) { + if (!intel_encoder) { return; } - connector = &intel_output->base; + connector = &intel_encoder->base; drm_connector_init(dev, connector, &intel_tv_connector_funcs, DRM_MODE_CONNECTOR_SVIDEO); - drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs, DRM_MODE_ENCODER_TVDAC); - drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); - tv_priv = (struct intel_tv_priv *)(intel_output + 1); - intel_output->type = INTEL_OUTPUT_TVOUT; - intel_output->crtc_mask = (1 << 0) | (1 << 1); - intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); - intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); - intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); - intel_output->dev_priv = tv_priv; + drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); + tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); + intel_encoder->type = INTEL_OUTPUT_TVOUT; + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); + intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); + intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); + intel_encoder->dev_priv = tv_priv; tv_priv->type = DRM_MODE_CONNECTOR_Unknown; /* BIOS margin values */ @@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); - drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); connector->interlace_allowed = false; connector->doublescan_allowed = false; -- cgit v1.1 From c751ce4f52b11ea93764a7cd44e6ae9c098d361b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 25 Mar 2010 11:48:48 -0700 Subject: drm/i915: Rename many remaining uses of "output" to encoder or connector. Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 20 ++-- drivers/gpu/drm/i915/intel_sdvo.c | 181 ++++++++++++++++++----------------- 2 files changed, 103 insertions(+), 98 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2595c4c..34d2652 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -754,8 +754,8 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) return false; } -struct drm_connector * -intel_pipe_get_output (struct drm_crtc *crtc) +static struct drm_connector * +intel_pipe_get_connector (struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_mode_config *mode_config = &dev->mode_config; @@ -2916,7 +2916,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk, num_outputs = 0; + int refclk, num_connectors = 0; intel_clock_t clock, reduced_clock; u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; @@ -2974,10 +2974,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, break; } - num_outputs++; + num_connectors++; } - if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) { + if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) { refclk = dev_priv->lvds_ssc_freq * 1000; DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", refclk / 1000); @@ -3048,7 +3048,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, if (is_edp) { struct drm_connector *edp; target_clock = mode->clock; - edp = intel_pipe_get_output(crtc); + edp = intel_pipe_get_connector(crtc); intel_edp_link_config(to_intel_encoder(edp), &lane, &link_bw); } else { @@ -3230,7 +3230,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* XXX: just matching BIOS for now */ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ dpll |= 3; - else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) + else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; @@ -3654,9 +3654,9 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, * detection. * * It will be up to the load-detect code to adjust the pipe as appropriate for - * its requirements. The pipe will be connected to no other outputs. + * its requirements. The pipe will be connected to no other encoders. * - * Currently this code will only succeed if there is a pipe with no outputs + * Currently this code will only succeed if there is a pipe with no encoders * configured for it. In the future, it could choose to temporarily disable * some outputs to free up a pipe for its use. * @@ -3770,7 +3770,7 @@ void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpm drm_helper_disable_unused_functions(dev); } - /* Switch crtc and output back off if necessary */ + /* Switch crtc and encoder back off if necessary */ if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) { if (encoder->crtc == crtc) encoder_funcs->dpms(encoder, dpms_mode); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index ea6de3b..a5b049f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -53,7 +53,7 @@ struct intel_sdvo_priv { u8 slave_addr; /* Register for the SDVO device: SDVOB or SDVOC */ - int output_device; + int sdvo_reg; /* Active outputs controlled by this SDVO output */ uint16_t controlled_output; @@ -123,7 +123,7 @@ struct intel_sdvo_priv { */ struct intel_sdvo_encode encode; - /* DDC bus used by this SDVO output */ + /* DDC bus used by this SDVO encoder */ uint8_t ddc_bus; /* Mac mini hack -- use the same DDC as the analog connector */ @@ -176,7 +176,7 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) u32 bval = val, cval = val; int i; - if (sdvo_priv->output_device == SDVOB) { + if (sdvo_priv->sdvo_reg == SDVOB) { cval = I915_READ(SDVOC); } else { bval = I915_READ(SDVOB); @@ -352,8 +352,8 @@ static const struct _sdvo_cmd_name { SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), }; -#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") -#define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv) +#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC") +#define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, void *args, int args_len) @@ -712,13 +712,13 @@ static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, } static bool -intel_sdvo_create_preferred_input_timing(struct intel_encoder *output, +intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, uint16_t clock, uint16_t width, uint16_t height) { struct intel_sdvo_preferred_input_timing_args args; - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; uint8_t status; memset(&args, 0, sizeof(args)); @@ -732,32 +732,33 @@ intel_sdvo_create_preferred_input_timing(struct intel_encoder *output, sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) args.scaled = 1; - intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, + intel_sdvo_write_cmd(intel_encoder, + SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, &args, sizeof(args)); - status = intel_sdvo_read_response(output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) return false; return true; } -static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *output, +static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { bool status; - intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, NULL, 0); - status = intel_sdvo_read_response(output, &dtd->part1, + status = intel_sdvo_read_response(intel_encoder, &dtd->part1, sizeof(dtd->part1)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; - intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, NULL, 0); - status = intel_sdvo_read_response(output, &dtd->part2, + status = intel_sdvo_read_response(intel_encoder, &dtd->part2, sizeof(dtd->part2)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -876,13 +877,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, mode->flags |= DRM_MODE_FLAG_PVSYNC; } -static bool intel_sdvo_get_supp_encode(struct intel_encoder *output, +static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder, struct intel_sdvo_encode *encode) { uint8_t status; - intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); - status = intel_sdvo_read_response(output, encode, sizeof(*encode)); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode)); if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ memset(encode, 0, sizeof(*encode)); return false; @@ -891,29 +892,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_encoder *output, return true; } -static bool intel_sdvo_set_encode(struct intel_encoder *output, uint8_t mode) +static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, + uint8_t mode) { uint8_t status; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1); - status = intel_sdvo_read_response(output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_set_colorimetry(struct intel_encoder *output, +static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder, uint8_t mode) { uint8_t status; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1); - status = intel_sdvo_read_response(output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } #if 0 -static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *output) +static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) { int i, j; uint8_t set_buf_index[2]; @@ -922,43 +924,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *output) uint8_t buf[48]; uint8_t *pos; - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); - intel_sdvo_read_response(output, &av_split, 1); + intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); + intel_sdvo_read_response(encoder, &av_split, 1); for (i = 0; i <= av_split; i++) { set_buf_index[0] = i; set_buf_index[1] = 0; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, + intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0); - intel_sdvo_read_response(output, &buf_size, 1); + intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0); + intel_sdvo_read_response(encoder, &buf_size, 1); pos = buf; for (j = 0; j <= buf_size; j += 8) { - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, + intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA, NULL, 0); - intel_sdvo_read_response(output, pos, 8); + intel_sdvo_read_response(encoder, pos, 8); pos += 8; } } } #endif -static void intel_sdvo_set_hdmi_buf(struct intel_encoder *output, int index, - uint8_t *data, int8_t size, uint8_t tx_rate) +static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, + int index, + uint8_t *data, int8_t size, uint8_t tx_rate) { uint8_t set_buf_index[2]; set_buf_index[0] = index; set_buf_index[1] = 0; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX, + set_buf_index, 2); for (; size > 0; size -= 8) { - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8); data += 8; } - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); } static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) @@ -1033,7 +1037,7 @@ struct dip_infoframe { } __attribute__ ((packed)) u; } __attribute__((packed)); -static void intel_sdvo_set_avi_infoframe(struct intel_encoder *output, +static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, struct drm_display_mode * mode) { struct dip_infoframe avi_if = { @@ -1044,15 +1048,16 @@ static void intel_sdvo_set_avi_infoframe(struct intel_encoder *output, avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, 4 + avi_if.len); - intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len, + intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, + 4 + avi_if.len, SDVO_HBUF_TX_VSYNC); } -static void intel_sdvo_set_tv_format(struct intel_encoder *output) +static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) { struct intel_sdvo_tv_format format; - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; uint32_t format_map, i; uint8_t status; @@ -1065,10 +1070,10 @@ static void intel_sdvo_set_tv_format(struct intel_encoder *output) memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? sizeof(format) : sizeof(format_map)); - intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map, sizeof(format)); - status = intel_sdvo_read_response(output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) DRM_DEBUG_KMS("%s: Failed to set TV format\n", SDVO_NAME(sdvo_priv)); @@ -1078,8 +1083,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_encoder *output = enc_to_intel_encoder(encoder); - struct intel_sdvo_priv *dev_priv = output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv; if (dev_priv->is_tv) { struct intel_sdvo_dtd output_dtd; @@ -1094,22 +1099,22 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, /* Set output timings */ intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - intel_sdvo_set_target_output(output, + intel_sdvo_set_target_output(intel_encoder, dev_priv->controlled_output); - intel_sdvo_set_output_timing(output, &output_dtd); + intel_sdvo_set_output_timing(intel_encoder, &output_dtd); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, true, false); + intel_sdvo_set_target_input(intel_encoder, true, false); - success = intel_sdvo_create_preferred_input_timing(output, + success = intel_sdvo_create_preferred_input_timing(intel_encoder, mode->clock / 10, mode->hdisplay, mode->vdisplay); if (success) { struct intel_sdvo_dtd input_dtd; - intel_sdvo_get_preferred_input_timing(output, + intel_sdvo_get_preferred_input_timing(intel_encoder, &input_dtd); intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; @@ -1132,16 +1137,16 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, intel_sdvo_get_dtd_from_mode(&output_dtd, dev_priv->sdvo_lvds_fixed_mode); - intel_sdvo_set_target_output(output, + intel_sdvo_set_target_output(intel_encoder, dev_priv->controlled_output); - intel_sdvo_set_output_timing(output, &output_dtd); + intel_sdvo_set_output_timing(intel_encoder, &output_dtd); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, true, false); + intel_sdvo_set_target_input(intel_encoder, true, false); success = intel_sdvo_create_preferred_input_timing( - output, + intel_encoder, mode->clock / 10, mode->hdisplay, mode->vdisplay); @@ -1149,7 +1154,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, if (success) { struct intel_sdvo_dtd input_dtd; - intel_sdvo_get_preferred_input_timing(output, + intel_sdvo_get_preferred_input_timing(intel_encoder, &input_dtd); intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; @@ -1181,8 +1186,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_encoder *output = enc_to_intel_encoder(encoder); - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u32 sdvox = 0; int sdvo_pixel_multiply; struct intel_sdvo_in_out_map in_out; @@ -1201,12 +1206,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, in_out.in0 = sdvo_priv->controlled_output; in_out.in1 = 0; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, &in_out, sizeof(in_out)); - status = intel_sdvo_read_response(output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (sdvo_priv->is_hdmi) { - intel_sdvo_set_avi_infoframe(output, mode); + intel_sdvo_set_avi_infoframe(intel_encoder, mode); sdvox |= SDVO_AUDIO_ENABLE; } @@ -1223,16 +1228,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, */ if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { /* Set the output timing to the screen */ - intel_sdvo_set_target_output(output, + intel_sdvo_set_target_output(intel_encoder, sdvo_priv->controlled_output); - intel_sdvo_set_output_timing(output, &input_dtd); + intel_sdvo_set_output_timing(intel_encoder, &input_dtd); } /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, true, false); + intel_sdvo_set_target_input(intel_encoder, true, false); if (sdvo_priv->is_tv) - intel_sdvo_set_tv_format(output); + intel_sdvo_set_tv_format(intel_encoder); /* We would like to use intel_sdvo_create_preferred_input_timing() to * provide the device with a timing it can support, if it supports that @@ -1240,29 +1245,29 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, * output the preferred timing, and we don't support that currently. */ #if 0 - success = intel_sdvo_create_preferred_input_timing(output, clock, + success = intel_sdvo_create_preferred_input_timing(encoder, clock, width, height); if (success) { struct intel_sdvo_dtd *input_dtd; - intel_sdvo_get_preferred_input_timing(output, &input_dtd); - intel_sdvo_set_input_timing(output, &input_dtd); + intel_sdvo_get_preferred_input_timing(encoder, &input_dtd); + intel_sdvo_set_input_timing(encoder, &input_dtd); } #else - intel_sdvo_set_input_timing(output, &input_dtd); + intel_sdvo_set_input_timing(intel_encoder, &input_dtd); #endif switch (intel_sdvo_get_pixel_multiplier(mode)) { case 1: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_encoder, SDVO_CLOCK_RATE_MULT_1X); break; case 2: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_encoder, SDVO_CLOCK_RATE_MULT_2X); break; case 4: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_encoder, SDVO_CLOCK_RATE_MULT_4X); break; } @@ -1273,8 +1278,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; } else { - sdvox |= I915_READ(sdvo_priv->output_device); - switch (sdvo_priv->output_device) { + sdvox |= I915_READ(sdvo_priv->sdvo_reg); + switch (sdvo_priv->sdvo_reg) { case SDVOB: sdvox &= SDVOB_PRESERVE_MASK; break; @@ -1298,7 +1303,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) sdvox |= SDVO_STALL_SELECT; - intel_sdvo_write_sdvox(output, sdvox); + intel_sdvo_write_sdvox(intel_encoder, sdvox); } static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) @@ -1315,7 +1320,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) intel_sdvo_set_encoder_power_state(intel_encoder, mode); if (mode == DRM_MODE_DPMS_OFF) { - temp = I915_READ(sdvo_priv->output_device); + temp = I915_READ(sdvo_priv->sdvo_reg); if ((temp & SDVO_ENABLE) != 0) { intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); } @@ -1325,7 +1330,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) int i; u8 status; - temp = I915_READ(sdvo_priv->output_device); + temp = I915_READ(sdvo_priv->sdvo_reg); if ((temp & SDVO_ENABLE) == 0) intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); for (i = 0; i < 2; i++) @@ -1388,7 +1393,7 @@ static void intel_sdvo_save(struct drm_connector *connector) /* XXX: Save TV format/enhancements. */ } - sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device); + sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg); } static void intel_sdvo_restore(struct drm_connector *connector) @@ -1499,10 +1504,10 @@ struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) sdvo = iout->dev_priv; - if (sdvo->output_device == SDVOB && sdvoB) + if (sdvo->sdvo_reg == SDVOB && sdvoB) return connector; - if (sdvo->output_device == SDVOC && !sdvoB) + if (sdvo->sdvo_reg == SDVOC && !sdvoB) return connector; } @@ -2248,12 +2253,12 @@ static struct i2c_algorithm intel_sdvo_i2c_bit_algo = { }; static u8 -intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) +intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct sdvo_device_mapping *my_mapping, *other_mapping; - if (output_device == SDVOB) { + if (sdvo_reg == SDVOB) { my_mapping = &dev_priv->sdvo_mappings[0]; other_mapping = &dev_priv->sdvo_mappings[1]; } else { @@ -2278,7 +2283,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) /* No SDVO device info is found for another DVO port, * so use mapping assumption we had before BIOS parsing. */ - if (output_device == SDVOB) + if (sdvo_reg == SDVOB) return 0x70; else return 0x72; @@ -2764,7 +2769,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) return; } -bool intel_sdvo_init(struct drm_device *dev, int output_device) +bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; @@ -2780,13 +2785,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) } sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); - sdvo_priv->output_device = output_device; + sdvo_priv->sdvo_reg = sdvo_reg; intel_encoder->dev_priv = sdvo_priv; intel_encoder->type = INTEL_OUTPUT_SDVO; /* setup the DDC bus. */ - if (output_device == SDVOB) + if (sdvo_reg == SDVOB) intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); else intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); @@ -2794,7 +2799,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) if (!intel_encoder->i2c_bus) goto err_inteloutput; - sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); + sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); /* Save the bit-banging i2c functionality for use by the DDC wrapper */ intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; @@ -2803,13 +2808,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) for (i = 0; i < 0x40; i++) { if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", - output_device == SDVOB ? 'B' : 'C'); + sdvo_reg == SDVOB ? 'B' : 'C'); goto err_i2c; } } /* setup the DDC bus. */ - if (output_device == SDVOB) { + if (sdvo_reg == SDVOB) { intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOB/VGA DDC BUS"); @@ -2833,7 +2838,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) if (intel_sdvo_output_setup(intel_encoder, sdvo_priv->caps.output_flags) != true) { DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", - output_device == SDVOB ? 'B' : 'C'); + sdvo_reg == SDVOB ? 'B' : 'C'); goto err_i2c; } -- cgit v1.1 From a7dc12ba756021a95866730b482c6e34b13f84ee Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 19 Mar 2010 18:16:37 +0300 Subject: imx3: Add watchdog platform device support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for build-in watchdog device found on Freescale imx31 and imx35 SoCs. Signed-off-by: Vladimir Zapolskiy Cc: Sascha Hauer Cc: Uwe Kleine-König Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/devices.c | 19 ++++++++++++++++++- arch/arm/mach-mx3/devices.h | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 6adb586..f891115 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = { .resource = imx_ssi_resources1, }; -static int mx3_devices_init(void) +static struct resource imx_wdt_resources[] = { + { + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device imx_wdt_device0 = { + .name = "imx-wdt", + .id = 0, + .num_resources = ARRAY_SIZE(imx_wdt_resources), + .resource = imx_wdt_resources, +}; + +static int __init mx3_devices_init(void) { if (cpu_is_mx31()) { mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR; mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff; + imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR; + imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff; mxc_register_device(&mxc_rnga_device, NULL); } if (cpu_is_mx35()) { @@ -597,6 +612,8 @@ static int mx3_devices_init(void) imx_ssi_resources0[1].end = MX35_INT_SSI1; imx_ssi_resources1[1].start = MX35_INT_SSI2; imx_ssi_resources1[1].end = MX35_INT_SSI2; + imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR; + imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff; } return 0; diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index 42cf175..4f77eb5 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h @@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_device1; extern struct platform_device mxc_spi_device2; extern struct platform_device imx_ssi_device0; extern struct platform_device imx_ssi_device1; - +extern struct platform_device imx_ssi_device1; +extern struct platform_device imx_wdt_device0; -- cgit v1.1 From 7d7a77e56744bb32b8a97a9903fd12433af1c4b2 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 19 Mar 2010 18:16:59 +0300 Subject: imx31: add watchdog device on litekit board. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for SoC build-in watchdog device on litekit board. Signed-off-by: Vladimir Zapolskiy Cc: Uwe Kleine-König Cc: Sascha Hauer Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/mx31lite-db.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c index ccd8742..0201683 100644 --- a/arch/arm/mach-mx3/mx31lite-db.c +++ b/arch/arm/mach-mx3/mx31lite-db.c @@ -206,5 +206,6 @@ void __init mx31lite_db_init(void) mxc_register_device(&mxcsdhc_device0, &mmc_pdata); mxc_register_device(&mxc_spi_device0, &spi0_pdata); platform_device_register(&litekit_led_device); + mxc_register_device(&imx_wdt_device0, NULL); } -- cgit v1.1 From 034cf2362af85259718c4930bc7b548fa4165c1c Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Thu, 25 Mar 2010 18:22:33 +0100 Subject: ARM mach-mx3: duplicated include arch/arm/mach-mx3/mach-pcm037.c: linux/fsl_devices.h is included more than once. Signed-off-by: Andrea Gelmini Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/mach-pcm037.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c index 11f5315..a550ae9 100644 --- a/arch/arm/mach-mx3/mach-pcm037.c +++ b/arch/arm/mach-mx3/mach-pcm037.c @@ -35,7 +35,6 @@ #include #include #include -#include #include -- cgit v1.1 From 17669fd60e6b245945cdd4bbe87d1186a07a03b6 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Thu, 25 Mar 2010 18:22:34 +0100 Subject: ARM mach-mx3: duplicated include arch/arm/mach-mx3/mx31lite-db.c: linux/platform_device.h is included more than once. Signed-off-by: Andrea Gelmini Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/mx31lite-db.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c index 0201683..093c595 100644 --- a/arch/arm/mach-mx3/mx31lite-db.c +++ b/arch/arm/mach-mx3/mx31lite-db.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include -- cgit v1.1 From b3aa111f7ac1ad07009081a824b5ce7a71462c4c Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Fri, 26 Feb 2010 18:36:32 +0100 Subject: MXC: mach_armadillo5x0: Add USB Host support. This add USB Host capability. The Armadillo 500 board is supplied with two USB Host connectors driven by the USB OTG and USB Host 2 ports, through two NXP isp 1504 transceivers. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Kconfig | 1 + arch/arm/mach-mx3/mach-armadillo5x0.c | 166 ++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 9a2911e..170f68e 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -104,6 +104,7 @@ config MACH_PCM043 config MACH_ARMADILLO5X0 bool "Support Atmark Armadillo-500 Development Base Board" select ARCH_MX31 + select MXC_ULPI if USB_ULPI help Include support for Atmark Armadillo-500 platform. This includes specific configurations for the board and its peripherals. diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c index 3d72b0b..5f72ec9 100644 --- a/arch/arm/mach-mx3/mach-armadillo5x0.c +++ b/arch/arm/mach-mx3/mach-armadillo5x0.c @@ -36,6 +36,9 @@ #include #include #include +#include +#include +#include #include #include @@ -52,6 +55,8 @@ #include #include #include +#include +#include #include "devices.h" #include "crm_regs.h" @@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = { /* I2C2 */ MX31_PIN_CSPI2_MOSI__SCL, MX31_PIN_CSPI2_MISO__SDA, + /* OTG */ + MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, + MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, + MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, + MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, + MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, + MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, + MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, + MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, + MX31_PIN_USBOTG_CLK__USBOTG_CLK, + MX31_PIN_USBOTG_DIR__USBOTG_DIR, + MX31_PIN_USBOTG_NXT__USBOTG_NXT, + MX31_PIN_USBOTG_STP__USBOTG_STP, + /* USB host 2 */ + IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC), }; +/* USB */ +#if defined(CONFIG_USB_ULPI) + +#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4) +#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6) +#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3) + +#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ + PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + +static int usbotg_init(struct platform_device *pdev) +{ + int err; + + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); + + /* Chip already enabled by hardware */ + /* OTG phy reset*/ + err = gpio_request(OTG_RESET, "USB-OTG-RESET"); + if (err) { + pr_err("Failed to request the usb otg reset gpio\n"); + return err; + } + + err = gpio_direction_output(OTG_RESET, 1/*HIGH*/); + if (err) { + pr_err("Failed to reset the usb otg phy\n"); + goto otg_free_reset; + } + + gpio_set_value(OTG_RESET, 0/*LOW*/); + mdelay(5); + gpio_set_value(OTG_RESET, 1/*HIGH*/); + + return 0; + +otg_free_reset: + gpio_free(OTG_RESET); + return err; +} + +static int usbh2_init(struct platform_device *pdev) +{ + int err; + + mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); + + mxc_iomux_set_gpr(MUX_PGP_UH2, true); + + + /* Enable the chip */ + err = gpio_request(USBH2_CS, "USB-H2-CS"); + if (err) { + pr_err("Failed to request the usb host 2 CS gpio\n"); + return err; + } + + err = gpio_direction_output(USBH2_CS, 0/*Enabled*/); + if (err) { + pr_err("Failed to drive the usb host 2 CS gpio\n"); + goto h2_free_cs; + } + + /* H2 phy reset*/ + err = gpio_request(USBH2_RESET, "USB-H2-RESET"); + if (err) { + pr_err("Failed to request the usb host 2 reset gpio\n"); + goto h2_free_cs; + } + + err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/); + if (err) { + pr_err("Failed to reset the usb host 2 phy\n"); + goto h2_free_reset; + } + + gpio_set_value(USBH2_RESET, 0/*LOW*/); + mdelay(5); + gpio_set_value(USBH2_RESET, 1/*HIGH*/); + + return 0; + +h2_free_reset: + gpio_free(USBH2_RESET); +h2_free_cs: + gpio_free(USBH2_CS); + return err; +} + +static struct mxc_usbh_platform_data usbotg_pdata = { + .init = usbotg_init, + .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, + .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI, +}; + +static struct mxc_usbh_platform_data usbh2_pdata = { + .init = usbh2_init, + .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, + .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI, +}; +#endif /* CONFIG_USB_ULPI */ + /* RTC over I2C*/ #define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) @@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void) if (armadillo5x0_i2c_rtc.irq == 0) pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); + + /* USB */ +#if defined(CONFIG_USB_ULPI) + usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + + mxc_register_device(&mxc_otg_host, &usbotg_pdata); + mxc_register_device(&mxc_usbh2, &usbh2_pdata); +#endif } static void __init armadillo5x0_timer_init(void) -- cgit v1.1 From 9358c6d4c0264b1572554c49c4b92673ea9a5c72 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 30 Mar 2010 13:54:41 -0700 Subject: ceph: fix dentry rehashing on virtual .snap dir If a lookup fails on the magic .snap directory, we bind it to a magic snap directory inode in ceph_lookup_finish(). That code assumes the dentry is unhashed, but a recent server-side change started returning NULL leases on lookup failure, causing the .snap dentry to be hashed and NULL by ceph_fill_trace(). This causes dentry hash chain corruption, or a dies when d_rehash() includes BUG_ON(!d_unhashed(entry)); So, avoid processing the NULL dentry lease if it the dentry matches the snapdir name in ceph_fill_trace(). That allows the lookup completion to properly bind it to the snapdir inode. BUG there if dentry is hashed to be sure. Signed-off-by: Sage Weil --- fs/ceph/dir.c | 1 + fs/ceph/inode.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 8a9116e..aed8fda 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -488,6 +488,7 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, struct inode *inode = ceph_get_snapdir(parent); dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n", dentry, dentry->d_name.len, dentry->d_name.name, inode); + BUG_ON(!d_unhashed(dentry)); d_add(dentry, inode); err = 0; } diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index aca82d5..26f883c 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -886,6 +886,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, struct inode *in = NULL; struct ceph_mds_reply_inode *ininfo; struct ceph_vino vino; + struct ceph_client *client = ceph_sb_to_client(sb); int i = 0; int err = 0; @@ -949,7 +950,14 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, return err; } - if (rinfo->head->is_dentry && !req->r_aborted) { + /* + * ignore null lease/binding on snapdir ENOENT, or else we + * will have trouble splicing in the virtual snapdir later + */ + if (rinfo->head->is_dentry && !req->r_aborted && + (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name, + client->mount_args->snapdir_name, + req->r_dentry->d_name.len))) { /* * lookup link rename : null -> possibly existing inode * mknod symlink mkdir : null -> new inode -- cgit v1.1 From 753234007f4ac2c96921cfb19ec1ba535ac29790 Mon Sep 17 00:00:00 2001 From: Li Hong Date: Wed, 31 Mar 2010 15:41:00 +0800 Subject: nilfs2: fix a wrong type conversion in nilfs_ioctl() (void * __user *) should be (void __user *) Signed-off-by: Li Hong Signed-off-by: Ryusuke Konishi --- fs/nilfs2/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 313d0a2..c446017 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -648,7 +648,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = filp->f_dentry->d_inode; - void __user *argp = (void * __user *)arg; + void __user *argp = (void __user *)arg; switch (cmd) { case NILFS_IOCTL_CHANGE_CPMODE: -- cgit v1.1 From 80e755fedebc8de0599a79efad2c656503df2e62 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 31 Mar 2010 21:52:10 -0700 Subject: ceph: allow writeback of snapped pages older than 'oldest' snapc On snap deletion, we don't regenerate ceph_cap_snaps for inodes with dirty pages because deletion does not affect metadata writeback. However, we did run into problems when we went to write back the pages because the 'oldest' snapc is determined by the oldest cap_snap, and that may be the newer snapc that reflects the deletion. This caused confusion and an infinite loop in ceph_update_writeable_page(). Change the snapc checks to allow writeback of any snapc that is equal to OR older than the 'oldest' snapc. When there are no cap_snaps, we were also using the realm's latest snapc for writeback, which complicates ceph_put_wrbufffer_cap_refs(). Instead, use i_head_snapc, the most snapc used for the most recent ('head') data. This makes the writeback snapc (ceph_osd_request.r_snapc) _always_ match a capsnap or i_head_snapc. Also, in writepags_finish(), drop the snapc referenced by the _page_ and do not assume it matches the request snapc (it may not anymore). Signed-off-by: Sage Weil --- fs/ceph/addr.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index ce8ef61..a313e9b 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -356,8 +356,8 @@ static struct ceph_snap_context *__get_oldest_context(struct inode *inode, break; } } - if (!snapc && ci->i_snap_realm) { - snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context); + if (!snapc && ci->i_head_snapc) { + snapc = ceph_get_snap_context(ci->i_head_snapc); dout(" head snapc %p has %d dirty pages\n", snapc, ci->i_wrbuffer_ref_head); } @@ -412,7 +412,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) dout("writepage %p page %p not dirty?\n", inode, page); goto out; } - if (snapc != get_oldest_context(inode, &snap_size)) { + if (snapc->seq > get_oldest_context(inode, &snap_size)->seq) { dout("writepage %p page %p snapc %p not writeable - noop\n", inode, page, (void *)page->private); /* we should only noop if called by kswapd */ @@ -557,9 +557,9 @@ static void writepages_finish(struct ceph_osd_request *req, dout("inode %p skipping page %p\n", inode, page); wbc->pages_skipped++; } + ceph_put_snap_context((void *)page->private); page->private = 0; ClearPagePrivate(page); - ceph_put_snap_context(snapc); dout("unlocking %d %p\n", i, page); end_page_writeback(page); @@ -617,7 +617,7 @@ static int ceph_writepages_start(struct address_space *mapping, int range_whole = 0; int should_loop = 1; pgoff_t max_pages = 0, max_pages_ever = 0; - struct ceph_snap_context *snapc = NULL, *last_snapc = NULL; + struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc; struct pagevec pvec; int done = 0; int rc = 0; @@ -769,9 +769,10 @@ get_more_pages: } /* only if matching snap context */ - if (snapc != (void *)page->private) { - dout("page snapc %p != oldest %p\n", - (void *)page->private, snapc); + pgsnapc = (void *)page->private; + if (pgsnapc->seq > snapc->seq) { + dout("page snapc %p %lld > oldest %p %lld\n", + pgsnapc, pgsnapc->seq, snapc, snapc->seq); unlock_page(page); if (!locked_pages) continue; /* keep looking for snap */ @@ -935,8 +936,8 @@ static int ceph_update_writeable_page(struct file *file, int pos_in_page = pos & ~PAGE_CACHE_MASK; int end_in_page = pos_in_page + len; loff_t i_size; - struct ceph_snap_context *snapc; int r; + struct ceph_snap_context *snapc, *oldest; retry_locked: /* writepages currently holds page lock, but if we change that later, */ @@ -946,16 +947,16 @@ retry_locked: BUG_ON(!ci->i_snap_realm); down_read(&mdsc->snap_rwsem); BUG_ON(!ci->i_snap_realm->cached_context); - if (page->private && - (void *)page->private != ci->i_snap_realm->cached_context) { + snapc = (void *)page->private; + if (snapc && snapc != ci->i_head_snapc) { /* * this page is already dirty in another (older) snap * context! is it writeable now? */ - snapc = get_oldest_context(inode, NULL); + oldest = get_oldest_context(inode, NULL); up_read(&mdsc->snap_rwsem); - if (snapc != (void *)page->private) { + if (snapc->seq > oldest->seq) { dout(" page %p snapc %p not current or oldest\n", page, (void *)page->private); /* -- cgit v1.1 From 6298a33757ba7361bb8f506c106daad77e5ac8cf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 31 Mar 2010 22:01:38 -0700 Subject: ceph: fix snap context reference leaks The get_oldest_context() helper takes a reference to the returned snap context, but most callers weren't dropping that reference. Fix them. Also drop the unused locked __get_oldest_context() variant. Signed-off-by: Sage Weil --- fs/ceph/addr.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index a313e9b..41f1f71 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -336,16 +336,15 @@ out: /* * Get ref for the oldest snapc for an inode with dirty data... that is, the * only snap context we are allowed to write back. - * - * Caller holds i_lock. */ -static struct ceph_snap_context *__get_oldest_context(struct inode *inode, - u64 *snap_size) +static struct ceph_snap_context *get_oldest_context(struct inode *inode, + u64 *snap_size) { struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_snap_context *snapc = NULL; struct ceph_cap_snap *capsnap = NULL; + spin_lock(&inode->i_lock); list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap, capsnap->context, capsnap->dirty_pages); @@ -361,16 +360,6 @@ static struct ceph_snap_context *__get_oldest_context(struct inode *inode, dout(" head snapc %p has %d dirty pages\n", snapc, ci->i_wrbuffer_ref_head); } - return snapc; -} - -static struct ceph_snap_context *get_oldest_context(struct inode *inode, - u64 *snap_size) -{ - struct ceph_snap_context *snapc = NULL; - - spin_lock(&inode->i_lock); - snapc = __get_oldest_context(inode, snap_size); spin_unlock(&inode->i_lock); return snapc; } @@ -391,7 +380,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) int len = PAGE_CACHE_SIZE; loff_t i_size; int err = 0; - struct ceph_snap_context *snapc; + struct ceph_snap_context *snapc, *oldest; u64 snap_size = 0; long writeback_stat; @@ -412,13 +401,16 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) dout("writepage %p page %p not dirty?\n", inode, page); goto out; } - if (snapc->seq > get_oldest_context(inode, &snap_size)->seq) { + oldest = get_oldest_context(inode, &snap_size); + if (snapc->seq > oldest->seq) { dout("writepage %p page %p snapc %p not writeable - noop\n", inode, page, (void *)page->private); /* we should only noop if called by kswapd */ WARN_ON((current->flags & PF_MEMALLOC) == 0); + ceph_put_snap_context(oldest); goto out; } + ceph_put_snap_context(oldest); /* is this a partial page at end of file? */ if (snap_size) @@ -457,7 +449,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) ClearPagePrivate(page); end_page_writeback(page); ceph_put_wrbuffer_cap_refs(ci, 1, snapc); - ceph_put_snap_context(snapc); + ceph_put_snap_context(snapc); /* page's reference */ out: return err; } @@ -914,7 +906,10 @@ static int context_is_writeable_or_written(struct inode *inode, struct ceph_snap_context *snapc) { struct ceph_snap_context *oldest = get_oldest_context(inode, NULL); - return !oldest || snapc->seq <= oldest->seq; + int ret = !oldest || snapc->seq <= oldest->seq; + + ceph_put_snap_context(oldest); + return ret; } /* @@ -957,13 +952,14 @@ retry_locked: up_read(&mdsc->snap_rwsem); if (snapc->seq > oldest->seq) { + ceph_put_snap_context(oldest); dout(" page %p snapc %p not current or oldest\n", - page, (void *)page->private); + page, snapc); /* * queue for writeback, and wait for snapc to * be writeable or written */ - snapc = ceph_get_snap_context((void *)page->private); + snapc = ceph_get_snap_context(snapc); unlock_page(page); ceph_queue_writeback(inode); r = wait_event_interruptible(ci->i_cap_wq, @@ -973,6 +969,7 @@ retry_locked: return r; return -EAGAIN; } + ceph_put_snap_context(oldest); /* yay, writeable, do it now (without dropping page lock) */ dout(" page %p snapc %p not current, but oldest\n", -- cgit v1.1 From 819ccbfa448403992ceafc05d6d7097aaa74d4c3 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 1 Apr 2010 09:33:46 -0700 Subject: ceph: fix leaked inode ref due to snap metadata writeback race We create a ceph_cap_snap if there is dirty cap metadata (for writeback to mds) OR dirty pages (for writeback to osd). It is thus possible that the metadata has been written back to the MDS but the OSD data has not when the cap_snap is created. This results in a cap_snap with dirty(caps) == 0. The problem is that cap writeback to the MDS isn't necessary, and a FLUSHSNAP cap op gets no ack from the MDS. This leaves the cap_snap attached to the inode along with its inode reference. Fix the problem by dropping the cap_snap if it becomes 'complete' (all pages written out) and dirty(caps) == 0 in ceph_put_wrbuffer_cap_refs(). Also, BUG() in __ceph_flush_snaps() if we encounter a cap_snap with dirty(caps) == 0. Signed-off-by: Sage Weil --- fs/ceph/caps.c | 42 ++++++++++++++++++++++++++++++++---------- fs/ceph/snap.c | 10 ++++++---- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 7d0a0d0..b6fdf01 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1204,6 +1204,12 @@ retry: if (capsnap->dirty_pages || capsnap->writing) continue; + /* + * if cap writeback already occurred, we should have dropped + * the capsnap in ceph_put_wrbuffer_cap_refs. + */ + BUG_ON(capsnap->dirty == 0); + /* pick mds, take s_mutex */ mds = __ceph_get_cap_mds(ci, &mseq); if (session && session->s_mds != mds) { @@ -2117,8 +2123,8 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) } spin_unlock(&inode->i_lock); - dout("put_cap_refs %p had %s %s\n", inode, ceph_cap_string(had), - last ? "last" : ""); + dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had), + last ? " last" : "", put ? " put" : ""); if (last && !flushsnaps) ceph_check_caps(ci, 0, NULL); @@ -2142,7 +2148,8 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, { struct inode *inode = &ci->vfs_inode; int last = 0; - int last_snap = 0; + int complete_capsnap = 0; + int drop_capsnap = 0; int found = 0; struct ceph_cap_snap *capsnap = NULL; @@ -2165,19 +2172,32 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { if (capsnap->context == snapc) { found = 1; - capsnap->dirty_pages -= nr; - last_snap = !capsnap->dirty_pages; break; } } BUG_ON(!found); + capsnap->dirty_pages -= nr; + if (capsnap->dirty_pages == 0) { + complete_capsnap = 1; + if (capsnap->dirty == 0) + /* cap writeback completed before we created + * the cap_snap; no FLUSHSNAP is needed */ + drop_capsnap = 1; + } dout("put_wrbuffer_cap_refs on %p cap_snap %p " - " snap %lld %d/%d -> %d/%d %s%s\n", + " snap %lld %d/%d -> %d/%d %s%s%s\n", inode, capsnap, capsnap->context->seq, ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr, ci->i_wrbuffer_ref, capsnap->dirty_pages, last ? " (wrbuffer last)" : "", - last_snap ? " (capsnap last)" : ""); + complete_capsnap ? " (complete capsnap)" : "", + drop_capsnap ? " (drop capsnap)" : ""); + if (drop_capsnap) { + ceph_put_snap_context(capsnap->context); + list_del(&capsnap->ci_item); + list_del(&capsnap->flushing_item); + ceph_put_cap_snap(capsnap); + } } spin_unlock(&inode->i_lock); @@ -2185,10 +2205,12 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, if (last) { ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); iput(inode); - } else if (last_snap) { + } else if (complete_capsnap) { ceph_flush_snaps(ci); wake_up(&ci->i_cap_wq); } + if (drop_capsnap) + iput(inode); } /* @@ -2464,8 +2486,8 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, break; } WARN_ON(capsnap->dirty_pages || capsnap->writing); - dout(" removing cap_snap %p follows %lld\n", - capsnap, follows); + dout(" removing %p cap_snap %p follows %lld\n", + inode, capsnap, follows); ceph_put_snap_context(capsnap->context); list_del(&capsnap->ci_item); list_del(&capsnap->flushing_item); diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index df04e21..7e3e5f9 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -521,15 +521,17 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci, capsnap->ctime = inode->i_ctime; capsnap->time_warp_seq = ci->i_time_warp_seq; if (capsnap->dirty_pages) { - dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu " + dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu " "still has %d dirty pages\n", inode, capsnap, capsnap->context, capsnap->context->seq, - capsnap->size, capsnap->dirty_pages); + ceph_cap_string(capsnap->dirty), capsnap->size, + capsnap->dirty_pages); return 0; } - dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu clean\n", + dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n", inode, capsnap, capsnap->context, - capsnap->context->seq, capsnap->size); + capsnap->context->seq, ceph_cap_string(capsnap->dirty), + capsnap->size); spin_lock(&mdsc->snap_flush_lock); list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list); -- cgit v1.1 From 308f44193f796b1c522b3b87760e43d8d8e316d2 Mon Sep 17 00:00:00 2001 From: Li Hong Date: Fri, 2 Apr 2010 18:40:39 +0800 Subject: nilfs2: Remove an uninitialization warning in nilfs_btree_propagate_v() `make CONFIG_NILFS2_FS=m M=fs/nilfs2/` will give the following warnings: fs/nilfs2/btree.c: In function 'nilfs_btree_propagate': fs/nilfs2/btree.c:1882: warning: 'maxlevel' may be used uninitialized in this function fs/nilfs2/btree.c:1882: note: 'maxlevel' was declared here Set maxlevel = 0 to fix it. Signed-off-by: Li Hong Signed-off-by: Ryusuke Konishi --- fs/nilfs2/btree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index 7cdd98b..76c38e3 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c @@ -1879,7 +1879,7 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree, struct nilfs_btree_path *path, int level, struct buffer_head *bh) { - int maxlevel, ret; + int maxlevel = 0, ret; struct nilfs_btree_node *parent; struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap); __u64 ptr; -- cgit v1.1 From 0e0d5e0c4bb0476d53a43bfc87d03a25ec4b5579 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 2 Apr 2010 16:07:19 -0700 Subject: ceph: fix ack counter reset on connection reset If in_seq_acked isn't reset along with in_seq, we don't ack received messages until we reach the old count, consuming gobs memory on the other end of the connection and introducing a large delay when those messages are eventually deleted. Signed-off-by: Sage Weil --- fs/ceph/messenger.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index a32f0f8..f35b494 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -332,6 +332,7 @@ static void reset_connection(struct ceph_connection *con) con->out_msg = NULL; } con->in_seq = 0; + con->in_seq_acked = 0; } /* -- cgit v1.1 From 9875557ee8247c3f7390d378c027b45c7535a224 Mon Sep 17 00:00:00 2001 From: Stefan Bader Date: Mon, 29 Mar 2010 17:53:12 +0200 Subject: drm/i915: Add no_lvds entry for the Clientron U800 BugLink: http://bugs.launchpad.net/ubuntu/bugs/544671 This system claims to have a LVDS but has not. Signed-off-by: Stephane Graber Signed-off-by: Stefan Bader CC: stable@kernel.org Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_lvds.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 9d99ddc..8238b40 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -857,6 +857,14 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), }, }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Clientron U800", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), + DMI_MATCH(DMI_PRODUCT_NAME, "U800"), + }, + }, { } /* terminating entry */ }; -- cgit v1.1 From bade732a2848e640482c1e99629a90e085d574dd Mon Sep 17 00:00:00 2001 From: Tom Tucker Date: Sat, 3 Apr 2010 08:27:29 -0500 Subject: svcrdma: RDMA support not yet compatible with RPC6 RPC6 requires that it be possible to create endpoints that listen exclusively for IPv4 or IPv6 connection requests. This is not currently supported by the RDMA API. This fixes a server RDMA regression introduced by 37498292a "NFSD: Create PF_INET6 listener in write_ports". Signed-off-by: Tom Tucker Tested-by: Steve Wise Reviewed-by: Chuck Lever Signed-off-by: J. Bruce Fields --- net/sunrpc/xprtrdma/svc_rdma_transport.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 3fa5751..4e6bbf9 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -678,7 +678,10 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, int ret; dprintk("svcrdma: Creating RDMA socket\n"); - + if (sa->sa_family != AF_INET) { + dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family); + return ERR_PTR(-EAFNOSUPPORT); + } cma_xprt = rdma_create_xprt(serv, 1); if (!cma_xprt) return ERR_PTR(-ENOMEM); -- cgit v1.1 From ab6e24103cbd215e922938a4f58c75194761a60e Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 19 Mar 2010 14:38:13 +0000 Subject: Btrfs: fix data enospc check overflow Because we account for reserved space we get from the allocator before we actually account for allocating delalloc space, we can have a small window where the amount of "used" space in a space_info is more than the total amount of space in the space_info. This will cause a overflow in our check, so it will seem like we have _tons_ of free space, and we'll allow reservations to occur that will end up larger than the amount of space we have. I've seen users report ENOSPC panic's in cow_file_range a few times recently, so I tried to reproduce this problem and found I could reproduce it if I ran one of my tests in a loop for like 20 minutes. With this patch my test ran all night without issues. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 101041d..786899d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3234,7 +3234,8 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, u64 bytes) { struct btrfs_space_info *data_sinfo; - int ret = 0, committed = 0; + u64 used; + int ret = 0, committed = 0, flushed = 0; /* make sure bytes are sectorsize aligned */ bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); @@ -3246,12 +3247,21 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, again: /* make sure we have enough space to handle the data first */ spin_lock(&data_sinfo->lock); - if (data_sinfo->total_bytes - data_sinfo->bytes_used - - data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - - data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - - data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) { + used = data_sinfo->bytes_used + data_sinfo->bytes_delalloc + + data_sinfo->bytes_reserved + data_sinfo->bytes_pinned + + data_sinfo->bytes_readonly + data_sinfo->bytes_may_use + + data_sinfo->bytes_super; + + if (used + bytes > data_sinfo->total_bytes) { struct btrfs_trans_handle *trans; + if (!flushed) { + spin_unlock(&data_sinfo->lock); + flush_delalloc(root, data_sinfo); + flushed = 1; + goto again; + } + /* * if we don't have enough free bytes in this space then we need * to alloc a new chunk. -- cgit v1.1 From 2c860a1101471a69f7a6778b7b1fb43344c38619 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 5 Apr 2010 22:29:09 -0700 Subject: Input: i8042 - spelling fix Signed-off-by: Dominik Brodowski Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index fce8ab7..90e5668 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -38,7 +38,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); static bool i8042_nomux; module_param_named(nomux, i8042_nomux, bool, 0); -MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present."); +MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present."); static bool i8042_unlock; module_param_named(unlock, i8042_unlock, bool, 0); -- cgit v1.1 From 5e28d8eb68c12eab9c4a47b42ba993a6420d71d3 Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Mon, 5 Apr 2010 22:29:08 -0700 Subject: Input: ALPS - add signature for HP Pavilion dm3 laptops Tested by a user running Ubuntu 9.10 in the following bug report. BugLink: http://bugs.launchpad.net/bugs/545307 Signed-off-by: Chase Douglas Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 7490f1d..2a791e0 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -63,6 +63,7 @@ static const struct alps_model_info alps_model_data[] = { { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ + { { 0x73, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, /* HP Pavilion dm3 */ { { 0x52, 0x01, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ }; -- cgit v1.1 From 9d32c30542f9ecdb4b96a1a960924c9f403e3562 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Apr 2010 22:29:09 -0700 Subject: Input: matrix_keypad - allow platform to disable key autorepeat In an embedded system the matrix_keypad driver might be used to interface with an external control panel and not an actual keyboard. On the control panel some of the keys could be used to turn on/off various functions. If key autorepeat is enabled this causes the function to quickly toggle between the on and off states and makes operation difficult. Add an option in the platform-specific data to disable the key autorepeat. Signed-off-by: H Hartley Sweeten Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/matrix_keypad.c | 4 +++- include/linux/input/matrix_keypad.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index d3c8b61..f9d86cf 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -373,7 +373,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT_MASK(EV_KEY); + if (!pdata->no_autorepeat) + input_dev->evbit[0] |= BIT_MASK(EV_REP); input_dev->open = matrix_keypad_start; input_dev->close = matrix_keypad_stop; diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 3bd018b..c964cd7 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h @@ -44,6 +44,7 @@ struct matrix_keymap_data { * @active_low: gpio polarity * @wakeup: controls whether the device should be set up as wakeup * source + * @no_autorepeat: disable key autorepeat * * This structure represents platform-specific data that use used by * matrix_keypad driver to perform proper initialization. @@ -64,6 +65,7 @@ struct matrix_keypad_platform_data { bool active_low; bool wakeup; + bool no_autorepeat; }; /** -- cgit v1.1 From 9f680ce04ea19dabbbafe01b57b61930a9b70741 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 6 Apr 2010 09:37:47 -0400 Subject: Btrfs: make sure the chunk allocator doesn't create zero length chunks A recent commit allowed for smaller chunks to be created, but didn't make sure they were always bigger than a stripe. After some divides, this led to zero length stripes. Signed-off-by: Chris Mason --- fs/btrfs/volumes.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 9bf1f58..b584e9a 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2249,6 +2249,12 @@ again: if (!looped) calc_size = max_t(u64, min_stripe_size, calc_size); + /* + * we're about to do_div by the stripe_len so lets make sure + * we end up with something bigger than a stripe + */ + calc_size = max_t(u64, calc_size, stripe_len * 4); + do_div(calc_size, stripe_len); calc_size *= stripe_len; -- cgit v1.1 From 75f66533bc883f761a7adcab3281fe3323efbc90 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Fri, 2 Apr 2010 18:27:52 -0700 Subject: x86/amd-iommu: enable iommu before attaching devices Hit another kdump problem as reported by Neil Horman. When initializaing the IOMMU, we attach devices to their domains before the IOMMU is fully (re)initialized. Attaching a device will issue some important invalidations. In the context of the newly kexec'd kdump kernel, the IOMMU may have stale cached data from the original kernel. Because we do the attach too early, the invalidation commands are placed in the new command buffer before the IOMMU is updated w/ that buffer. This leaves the stale entries in the kdump context and can renders device unusable. Simply enable the IOMMU before we do the attach. Cc: stable@kernel.org Cc: Neil Horman Cc: Vivek Goyal Signed-off-by: Chris Wright Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu_init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index feaf471..8975965 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -1304,6 +1304,8 @@ static int __init amd_iommu_init(void) if (ret) goto free; + enable_iommus(); + if (iommu_pass_through) ret = amd_iommu_init_passthrough(); else @@ -1316,8 +1318,6 @@ static int __init amd_iommu_init(void) amd_iommu_init_notifier(); - enable_iommus(); - if (iommu_pass_through) goto out; @@ -1331,6 +1331,7 @@ out: return ret; free: + disable_iommus(); amd_iommu_uninit_devices(); -- cgit v1.1 From 549c90dc9a6d659e792b2a42a0930c7da015ea4a Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Fri, 2 Apr 2010 18:27:53 -0700 Subject: x86/amd-iommu: warn when issuing command to uninitialized cmd buffer To catch future potential issues we can add a warning whenever we issue a command before the command buffer is fully initialized. Signed-off-by: Chris Wright Signed-off-by: Joerg Roedel --- arch/x86/include/asm/amd_iommu_types.h | 1 + arch/x86/kernel/amd_iommu.c | 1 + arch/x86/kernel/amd_iommu_init.c | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 5e46e78..86a0ff0 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h @@ -141,6 +141,7 @@ /* constants to configure the command buffer */ #define CMD_BUFFER_SIZE 8192 +#define CMD_BUFFER_UNINITIALIZED 1 #define CMD_BUFFER_ENTRIES 512 #define MMIO_CMD_SIZE_SHIFT 56 #define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT) diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index b06f29e..71dfc0a 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -392,6 +392,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) u32 tail, head; u8 *target; + WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED); tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); target = iommu->cmd_buf + tail; memcpy_toio(target, cmd, sizeof(*cmd)); diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 8975965..5edf41c 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -438,7 +438,7 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu) if (cmd_buf == NULL) return NULL; - iommu->cmd_buf_size = CMD_BUFFER_SIZE; + iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED; return cmd_buf; } @@ -474,12 +474,13 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu) &entry, sizeof(entry)); amd_iommu_reset_cmd_buffer(iommu); + iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED); } static void __init free_command_buffer(struct amd_iommu *iommu) { free_pages((unsigned long)iommu->cmd_buf, - get_order(iommu->cmd_buf_size)); + get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED))); } /* allocates the memory where the IOMMU will log its events to */ -- cgit v1.1 From 8f9f55e83e939724490d7cde3833c4883c6d1310 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Fri, 2 Apr 2010 18:27:54 -0700 Subject: Revert "x86: disable IOMMUs on kernel crash" This effectively reverts commit 61d047be99757fd9b0af900d7abce9a13a337488. Disabling the IOMMU can potetially allow DMA transactions to complete without being translated. Leave it enabled, and allow crash kernel to do the IOMMU reinitialization properly. Cc: stable@kernel.org Cc: Joerg Roedel Cc: Eric Biederman Cc: Neil Horman Cc: Vivek Goyal Signed-off-by: Chris Wright Signed-off-by: Joerg Roedel --- arch/x86/kernel/crash.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index a4849c1..ebd4c51 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -27,7 +27,6 @@ #include #include #include -#include #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) @@ -103,10 +102,5 @@ void native_machine_crash_shutdown(struct pt_regs *regs) #ifdef CONFIG_HPET_TIMER hpet_disable(); #endif - -#ifdef CONFIG_X86_64 - x86_platform.iommu_shutdown(); -#endif - crash_save_cpu(regs, safe_smp_processor_id()); } -- cgit v1.1 From d18c69d3898985c66cd6e878b8f576fd9a21ab39 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Fri, 2 Apr 2010 18:27:55 -0700 Subject: x86/amd-iommu: use for_each_pci_dev Replace open coded version with for_each_pci_dev Signed-off-by: Chris Wright Signed-off-by: Joerg Roedel --- arch/x86/kernel/amd_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 71dfc0a..4949568 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2187,7 +2187,7 @@ static void prealloc_protection_domains(void) struct dma_ops_domain *dma_dom; u16 devid; - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + for_each_pci_dev(dev) { /* Do we handle this device? */ if (!check_device(&dev->dev)) -- cgit v1.1 From 20a1cfba340f23a7ca62391e199c40c86b762ea3 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 7 Apr 2010 14:28:26 +0200 Subject: x86/amd-iommu: Remove obsolete parameter documentation Support for the share and fullflush parameters was removed. Remove the documentation about them too. Signed-off-by: Joerg Roedel --- Documentation/kernel-parameters.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e7848a0..ccea846 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -323,11 +323,6 @@ and is between 256 and 4096 characters. It is defined in the file amd_iommu= [HW,X86-84] Pass parameters to the AMD IOMMU driver in the system. Possible values are: - isolate - enable device isolation (each device, as far - as possible, will get its own protection - domain) [default] - share - put every device behind one IOMMU into the - same protection domain fullflush - enable flushing of IO/TLB entries when they are unmapped. Otherwise they are flushed before they will be reused, which -- cgit v1.1 From 39a37ce1cc5eef420604fa68b776ff5dab400340 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 6 Apr 2010 19:45:12 +0300 Subject: dma-debug: Cleanup for copy-loop in filter_write() Earlier in this function we set the last byte of "buf" to NULL so we always hit the break statement and "i" is never equal to NAME_MAX_LEN. This patch doesn't change how the driver works but it silences a Smatch warning and it makes it clearer that we don't write past the end of the array. Signed-off-by: Dan Carpenter Signed-off-by: Joerg Roedel --- lib/dma-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dma-debug.c b/lib/dma-debug.c index ba8b670..01e6427 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -570,7 +570,7 @@ static ssize_t filter_write(struct file *file, const char __user *userbuf, * Now parse out the first token and use it as the name for the * driver to filter for. */ - for (i = 0; i < NAME_MAX_LEN; ++i) { + for (i = 0; i < NAME_MAX_LEN - 1; ++i) { current_driver_name[i] = buf[i]; if (isspace(buf[i]) || buf[i] == ' ' || buf[i] == 0) break; -- cgit v1.1 From 4b83873d3da0704987cb116833818ed96214ee29 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 7 Apr 2010 12:57:35 +0200 Subject: x86/gart: Disable GART explicitly before initialization If we boot into a crash-kernel the gart might still be enabled and its caches might be dirty. This can result in undefined behavior later. Fix it by explicitly disabling the gart hardware before initialization and flushing the caches after enablement. Signed-off-by: Joerg Roedel --- arch/x86/kernel/aperture_64.c | 15 ++++++++++++++- arch/x86/kernel/pci-gart_64.c | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 3704997..b5d8b0b 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -393,6 +393,7 @@ void __init gart_iommu_hole_init(void) for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) { int bus; int dev_base, dev_limit; + u32 ctl; bus = bus_dev_ranges[i].bus; dev_base = bus_dev_ranges[i].dev_base; @@ -406,7 +407,19 @@ void __init gart_iommu_hole_init(void) gart_iommu_aperture = 1; x86_init.iommu.iommu_init = gart_iommu_init; - aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7; + ctl = read_pci_config(bus, slot, 3, + AMD64_GARTAPERTURECTL); + + /* + * Before we do anything else disable the GART. It may + * still be enabled if we boot into a crash-kernel here. + * Reconfiguring the GART while it is enabled could have + * unknown side-effects. + */ + ctl &= ~GARTEN; + write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl); + + aper_order = (ctl >> 1) & 7; aper_size = (32 * 1024 * 1024) << aper_order; aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff; aper_base <<= 25; diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index f3af115..0ae24d9b 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -564,6 +564,9 @@ static void enable_gart_translations(void) enable_gart_translation(dev, __pa(agp_gatt_table)); } + + /* Flush the GART-TLB to remove stale entries */ + k8_flush_garts(); } /* -- cgit v1.1 From 7ad7b218f4aae4f395b3b4cef261572556bbd20a Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Tue, 6 Apr 2010 18:12:52 +0200 Subject: ALSA: hda: Add support for Medion WIM2160 This adds support for the Medion WIM2160 soundcard. There's no PCI quirk added because it has the same PCI id as the Medion MD2. Signed-off-by: Maurus Cuelenaere Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c7730db..2971e48 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -230,6 +230,7 @@ enum { ALC888_ACER_ASPIRE_7730G, ALC883_MEDION, ALC883_MEDION_MD2, + ALC883_MEDION_WIM2160, ALC883_LAPTOP_EAPD, ALC883_LENOVO_101E_2ch, ALC883_LENOVO_NB0763, @@ -8455,6 +8456,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), + { } /* end */ +}; + +static struct hda_verb alc883_medion_wim2160_verbs[] = { + /* Unmute front mixer */ + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + /* Set speaker pin to front mixer */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + + /* Init headphone pin */ + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + + { } /* end */ +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc883_medion_wim2160_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + spec->autocfg.hp_pins[0] = 0x1a; + spec->autocfg.speaker_pins[0] = 0x15; +} + static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -9164,6 +9201,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", [ALC883_MEDION] = "medion", [ALC883_MEDION_MD2] = "medion-md2", + [ALC883_MEDION_WIM2160] = "medion-wim2160", [ALC883_LAPTOP_EAPD] = "laptop-eapd", [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_LENOVO_NB0763] = "lenovo-nb0763", @@ -9818,6 +9856,21 @@ static struct alc_config_preset alc882_presets[] = { .setup = alc883_medion_md2_setup, .init_hook = alc_automute_amp, }, + [ALC883_MEDION_WIM2160] = { + .mixers = { alc883_medion_wim2160_mixer }, + .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC883_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .adc_nids = alc883_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), + .channel_mode = alc883_3ST_2ch_modes, + .input_mux = &alc883_capture_source, + .unsol_event = alc_automute_amp_unsol_event, + .setup = alc883_medion_wim2160_setup, + .init_hook = alc_automute_amp, + }, [ALC883_LAPTOP_EAPD] = { .mixers = { alc883_base_mixer }, .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, -- cgit v1.1 From 76708ab83962732ba3191ce8a61d8410406c8358 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Thu, 1 Apr 2010 19:13:19 +0100 Subject: ARM: 6024/1: bcmring: fix missing down on semaphore in dma.c Added missing down on the memMap->lock semaphore. Also fixed a return statement so that we always exit with an up (i.e. early exit via return is not allowed) Signed-off-by: Leo Hao Chen Signed-off-by: Russell King --- arch/arm/mach-bcmring/dma.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c index 2ccf670..29c0a91 100644 --- a/arch/arm/mach-bcmring/dma.c +++ b/arch/arm/mach-bcmring/dma.c @@ -2221,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_ring); int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ int dirtied /* non-zero if any of the pages were modified */ ) { + + int rc = 0; int regionIdx; int segmentIdx; DMA_Region_t *region; DMA_Segment_t *segment; + down(&memMap->lock); + for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { region = &memMap->region[regionIdx]; @@ -2239,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ printk(KERN_ERR "%s: vmalloc'd pages are not yet supported\n", __func__); - return -EINVAL; + rc = -EINVAL; + goto out; } case DMA_MEM_TYPE_KMALLOC: @@ -2276,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ printk(KERN_ERR "%s: Unsupported memory type: %d\n", __func__, region->memType); - return -EINVAL; + rc = -EINVAL; + goto out; } } @@ -2314,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ memMap->numRegionsUsed = 0; memMap->inUse = 0; +out: up(&memMap->lock); - return 0; + return rc; } EXPORT_SYMBOL(dma_unmap); -- cgit v1.1 From 54274d71d9358321f7773b820de37496a05fae7f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 4 Apr 2010 10:58:03 +0100 Subject: ARM: 6028/1: ARM: add MAINTAINERS for U300 This adds myself as maintainer of the U300 machine and associated system-on-chip drivers. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3d29fa3..6eb978e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -971,6 +971,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.mcuos.com S: Maintained +ARM/U300 MACHINE SUPPORT +M: Linus Walleij +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Supported +F: arch/arm/mach-u300/ +F: drivers/i2c/busses/i2c-stu300.c +F: drivers/rtc/rtc-coh901331.c +F: drivers/watchdog/coh901327_wdt.c +F: drivers/dma/coh901318* + ARM/U8500 ARM ARCHITECTURE M: Srinidhi Kasagar L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- cgit v1.1 From 4742723cbce519773e4560f5cab11163eaa0c889 Mon Sep 17 00:00:00 2001 From: Hartley Sweeten Date: Tue, 6 Apr 2010 22:46:16 +0100 Subject: ARM: 6029/1: ep93xx: gpio.c: local functions should be static The functions ep93xx_gpio_update_int_params and ep93xx_gpio_int_mask are not exported and should be static. This was overlooked when moving the code from core.c. Also, change a comment to better indicate what the code is for. Signed-off-by: H Hartley Sweeten Acked-by: Ryan Mallon Signed-off-by: Russell King --- arch/arm/mach-ep93xx/gpio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index cc377ae..cf547ad 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c @@ -25,7 +25,7 @@ #include /************************************************************************* - * GPIO handling for EP93xx + * Interrupt handling for EP93xx on-chip GPIOs *************************************************************************/ static unsigned char gpio_int_unmasked[3]; static unsigned char gpio_int_enabled[3]; @@ -40,7 +40,7 @@ static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 }; static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 }; static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 }; -void ep93xx_gpio_update_int_params(unsigned port) +static void ep93xx_gpio_update_int_params(unsigned port) { BUG_ON(port > 2); @@ -56,7 +56,7 @@ void ep93xx_gpio_update_int_params(unsigned port) EP93XX_GPIO_REG(int_en_register_offset[port])); } -void ep93xx_gpio_int_mask(unsigned line) +static inline void ep93xx_gpio_int_mask(unsigned line) { gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); } -- cgit v1.1 From d4d9959c099751158c5cf14813fe378e206339c6 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 7 Apr 2010 18:10:20 +0100 Subject: ARM: 6031/1: fix Thumb-2 decompressor 98e12b5a6e05413 ("ARM: Fix decompressor's kernel size estimation for ROM=y") broke the Thumb-2 decompressor because it added an entry in the LC0 table but didn't adjust the offset the Thumb-2 code uses to load the SP from that table. Fix it. Cc: stable Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/boot/compressed/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 0f23009..6ab6b33 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -172,7 +172,7 @@ not_angel: adr r0, LC0 ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp}) THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} ) - THUMB( ldr sp, [r0, #28] ) + THUMB( ldr sp, [r0, #32] ) subs r0, r0, r1 @ calculate the delta offset @ if delta is zero, we are -- cgit v1.1 From 69ecbbedac8e353bbd924fad16fed0c7c54e6382 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 15 Mar 2010 11:21:13 +0300 Subject: udf: potential integer overflow bloc->logicalBlockNum is unsigned so it's never less than zero. When I saw that, it made me worry that "bloc->logicalBlockNum + count" could overflow. That's why I changed the check for less than zero to an overflow check. (The test works because "count" is also unsigned.) Signed-off-by: Dan Carpenter Signed-off-by: Jan Kara --- fs/udf/balloc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 19626e2..9a9378b 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -125,9 +125,8 @@ static void udf_bitmap_free_blocks(struct super_block *sb, mutex_lock(&sbi->s_alloc_mutex); partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; - if (bloc->logicalBlockNum < 0 || - (bloc->logicalBlockNum + count) > - partmap->s_partition_len) { + if (bloc->logicalBlockNum + count < count || + (bloc->logicalBlockNum + count) > partmap->s_partition_len) { udf_debug("%d < %d || %d + %d > %d\n", bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count, partmap->s_partition_len); @@ -393,9 +392,8 @@ static void udf_table_free_blocks(struct super_block *sb, mutex_lock(&sbi->s_alloc_mutex); partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; - if (bloc->logicalBlockNum < 0 || - (bloc->logicalBlockNum + count) > - partmap->s_partition_len) { + if (bloc->logicalBlockNum + count < count || + (bloc->logicalBlockNum + count) > partmap->s_partition_len) { udf_debug("%d < %d || %d + %d > %d\n", bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count, partmap->s_partition_len); -- cgit v1.1 From c15d0fc0fc399d2639240b35ad7ed93ed5a59412 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Mon, 29 Mar 2010 11:05:21 +0400 Subject: udf: add speciffic ->setattr callback generic setattr not longer responsible for quota transfer. use udf_setattr for all udf's inodes. Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara --- fs/udf/file.c | 2 +- fs/udf/inode.c | 2 +- fs/udf/namei.c | 9 ++++++++- fs/udf/udfdecl.h | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/udf/file.c b/fs/udf/file.c index 1eb0677..4b6a46c 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -218,7 +218,7 @@ const struct file_operations udf_file_operations = { .llseek = generic_file_llseek, }; -static int udf_setattr(struct dentry *dentry, struct iattr *iattr) +int udf_setattr(struct dentry *dentry, struct iattr *iattr) { struct inode *inode = dentry->d_inode; int error; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index bb863fe..8a3fbd1 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1314,7 +1314,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) break; case ICBTAG_FILE_TYPE_SYMLINK: inode->i_data.a_ops = &udf_symlink_aops; - inode->i_op = &page_symlink_inode_operations; + inode->i_op = &udf_symlink_inode_operations; inode->i_mode = S_IFLNK | S_IRWXUGO; break; case ICBTAG_FILE_TYPE_MAIN: diff --git a/fs/udf/namei.c b/fs/udf/namei.c index db423ab..7581602 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -925,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, iinfo = UDF_I(inode); inode->i_mode = S_IFLNK | S_IRWXUGO; inode->i_data.a_ops = &udf_symlink_aops; - inode->i_op = &page_symlink_inode_operations; + inode->i_op = &udf_symlink_inode_operations; if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { struct kernel_lb_addr eloc; @@ -1393,6 +1393,7 @@ const struct export_operations udf_export_ops = { const struct inode_operations udf_dir_inode_operations = { .lookup = udf_lookup, .create = udf_create, + .setattr = udf_setattr, .link = udf_link, .unlink = udf_unlink, .symlink = udf_symlink, @@ -1401,3 +1402,9 @@ const struct inode_operations udf_dir_inode_operations = { .mknod = udf_mknod, .rename = udf_rename, }; +const struct inode_operations udf_symlink_inode_operations = { + .readlink = generic_readlink, + .follow_link = page_follow_link_light, + .put_link = page_put_link, + .setattr = udf_setattr, +}; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 4223ac8..702a114 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -76,6 +76,7 @@ extern const struct inode_operations udf_dir_inode_operations; extern const struct file_operations udf_dir_operations; extern const struct inode_operations udf_file_inode_operations; extern const struct file_operations udf_file_operations; +extern const struct inode_operations udf_symlink_inode_operations; extern const struct address_space_operations udf_aops; extern const struct address_space_operations udf_adinicb_aops; extern const struct address_space_operations udf_symlink_aops; @@ -131,7 +132,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, /* file.c */ extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - +extern int udf_setattr(struct dentry *dentry, struct iattr *iattr); /* inode.c */ extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); extern int udf_sync_inode(struct inode *); -- cgit v1.1 From 78e4fd26ef8b85c8cbb6803e18b6b1f970420e06 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 8 Apr 2010 19:50:08 +0800 Subject: ASoC: wm2000: remove unused #include Remove unused #include ('s) in sound/soc/codecs/wm2000.c Signed-off-by: Huang Weiyi Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm2000.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 217b026..8de8666 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include -- cgit v1.1 From 206b60e189c7cc2b4675687d66f167299a13a4d4 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 8 Apr 2010 11:31:24 +0200 Subject: ASoC: imx-ssi: honor IMX_SSI_DMA flag When checking if we are DMA capable we have to check for the IMX_SSI_DMA flag which is already set from platform_data instead of setting it again when we want to do DMA. Signed-off-by: Sascha Hauer Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/imx/imx-ssi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 28e55c7..1bf9dc8 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -655,7 +655,8 @@ static int imx_ssi_probe(struct platform_device *pdev) dai->private_data = ssi; if ((cpu_is_mx27() || cpu_is_mx21()) && - !(ssi->flags & IMX_SSI_USE_AC97)) { + !(ssi->flags & IMX_SSI_USE_AC97) && + (ssi->flags & IMX_SSI_DMA)) { ssi->flags |= IMX_SSI_DMA; platform = imx_ssi_dma_mx2_init(pdev, ssi); } else -- cgit v1.1 From 671999cb5d8817611f865f3877f5a5b81372f61e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 8 Apr 2010 11:31:25 +0200 Subject: ASoC: imx-pcm-dma-mx2: restart DMA after an error Signed-off-by: Sascha Hauer Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/imx/imx-pcm-dma-mx2.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index c78c000..9327296 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -70,7 +70,12 @@ static void imx_ssi_dma_callback(int channel, void *data) static void snd_imx_dma_err_callback(int channel, void *data, int err) { - pr_err("DMA error callback called\n"); + struct snd_pcm_substream *substream = data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; + int ret; pr_err("DMA timeout on channel %d -%s%s%s%s\n", channel, @@ -78,6 +83,14 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) err & IMX_DMA_ERR_REQUEST ? " request" : "", err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); + + imx_dma_disable(iprtd->dma); + ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, + IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + DMA_MODE_WRITE : DMA_MODE_READ); + if (!ret) + imx_dma_enable(iprtd->dma); } static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) -- cgit v1.1 From 43a3cec01354573517f1348383e0ab6e6067076b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 8 Apr 2010 11:31:26 +0200 Subject: ASoC: imx-ssi: Use a hrtimer in FIQ mode Using a regular timer results in poll times < 1 jiffie with small buffers, so we loaded the timer with the actual jiffie value. We can be more accurate using a hrtimer. Also, we have to call snd_pcm_period_elapsed after playing period_bytes and not runtime->period_size (which is in samples and not in bytes). Signed-off-by: Sascha Hauer Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/imx/imx-pcm-fiq.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index d9cb984..64df813 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c @@ -38,20 +38,17 @@ struct imx_pcm_runtime_data { unsigned long offset; unsigned long last_offset; unsigned long size; - struct timer_list timer; - int poll_time; + struct hrtimer hrt; + int poll_time_ns; + struct snd_pcm_substream *substream; }; -static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) +static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) { - iprtd->timer.expires = jiffies + iprtd->poll_time; -} - -static void imx_ssi_timer_callback(unsigned long data) -{ - struct snd_pcm_substream *substream = (void *)data; + struct imx_pcm_runtime_data *iprtd = + container_of(hrt, struct imx_pcm_runtime_data, hrt); + struct snd_pcm_substream *substream = iprtd->substream; struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct pt_regs regs; unsigned long delta; @@ -71,16 +68,14 @@ static void imx_ssi_timer_callback(unsigned long data) /* If we've transferred at least a period then report it and * reset our poll time */ - if (delta >= runtime->period_size) { + if (delta >= iprtd->period) { snd_pcm_period_elapsed(substream); iprtd->last_offset = iprtd->offset; - - imx_ssi_set_next_poll(iprtd); } - /* Restart the timer; if we didn't report we'll run on the next tick */ - add_timer(&iprtd->timer); + hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns)); + return HRTIMER_RESTART; } static struct fiq_handler fh = { @@ -98,8 +93,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, iprtd->period = params_period_bytes(params) ; iprtd->offset = 0; iprtd->last_offset = 0; - iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); - + iprtd->poll_time_ns = 1000000000 / params_rate(params) * + params_period_size(params); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); return 0; @@ -134,8 +129,8 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - imx_ssi_set_next_poll(iprtd); - add_timer(&iprtd->timer); + hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), + HRTIMER_MODE_REL); if (++fiq_enable == 1) enable_fiq(imx_pcm_fiq); @@ -144,7 +139,7 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - del_timer(&iprtd->timer); + hrtimer_cancel(&iprtd->hrt); if (--fiq_enable == 0) disable_fiq(imx_pcm_fiq); @@ -193,9 +188,10 @@ static int snd_imx_open(struct snd_pcm_substream *substream) iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); runtime->private_data = iprtd; - init_timer(&iprtd->timer); - iprtd->timer.data = (unsigned long)substream; - iprtd->timer.function = imx_ssi_timer_callback; + iprtd->substream = substream; + + hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + iprtd->hrt.function = snd_hrtimer_callback; ret = snd_pcm_hw_constraint_integer(substream->runtime, SNDRV_PCM_HW_PARAM_PERIODS); @@ -211,7 +207,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; - del_timer_sync(&iprtd->timer); + hrtimer_cancel(&iprtd->hrt); + kfree(iprtd); return 0; -- cgit v1.1 From ab285f2b5290d92b7ec1a6f9aad54308dadf6157 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 8 Apr 2010 14:05:50 +0200 Subject: perf: Fix unsafe frame rewinding with hot regs fetching When we fetch the hot regs and rewind to the nth caller, it might happen that we dereference a frame pointer outside the kernel stack boundaries, like in this example: perf_trace_sched_switch+0xd5/0x120 schedule+0x6b5/0x860 retint_careful+0xd/0x21 Since we directly dereference a userspace frame pointer here while rewinding behind retint_careful, this may end up in a crash. Fix this by simply using probe_kernel_address() when we rewind the frame pointer. This issue will have a much more proper fix in the next version of the perf_arch_fetch_caller_regs() API that will only need to rewind to the first caller. Reported-by: Eric Dumazet Signed-off-by: Frederic Weisbecker Tested-by: Eric Dumazet Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: David Miller Cc: Archs --- arch/x86/kernel/dumpstack.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/dumpstack.h b/arch/x86/kernel/dumpstack.h index e39e771..e1a93be 100644 --- a/arch/x86/kernel/dumpstack.h +++ b/arch/x86/kernel/dumpstack.h @@ -14,6 +14,8 @@ #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :) #endif +#include + extern void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, unsigned long bp, char *log_lvl); @@ -42,8 +44,10 @@ static inline unsigned long rewind_frame_pointer(int n) get_bp(frame); #ifdef CONFIG_FRAME_POINTER - while (n--) - frame = frame->next_frame; + while (n--) { + if (probe_kernel_address(&frame->next_frame, frame)) + break; + } #endif return (unsigned long)frame; -- cgit v1.1 From 9823f1a8463fb631fe965110fe19adeb3df239c4 Mon Sep 17 00:00:00 2001 From: Anders Larsen Date: Thu, 8 Apr 2010 11:48:16 +0100 Subject: ARM: 6043/1: AT91 slow-clock resume: Don't wait for a disabled PLL to lock at91 slow-clock resume: Don't wait for a disabled PLL to lock. We run into this problem with the PLLB on the at91: ohci-at91 disables the PLLB when going to suspend. The slowclock code however tries to do the same: It saves the PLLB register value and when restoring the value during resume, it waits for the PLLB to lock again. However the PLL will never lock and the loop would run into its timeout because the slowclock code just stored and restored an empty register. This fixes the problem by only restoring PLLA/PLLB when they were enabled at suspend time. Cc: Andrew Victor Signed-off-by: Anders Larsen Signed-off-by: Russell King --- arch/arm/mach-at91/pm_slowclock.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 987fab3..9fcbd6c 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -205,13 +205,25 @@ ENTRY(at91_slow_clock) ldr r3, .saved_pllbr str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] + tst r3, #(AT91_PMC_MUL & 0xff0000) + bne 1f + tst r3, #(AT91_PMC_MUL & ~0xff0000) + beq 2f +1: wait_pllblock +2: /* Restore PLLA setting */ ldr r3, .saved_pllar str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] + tst r3, #(AT91_PMC_MUL & 0xff0000) + bne 3f + tst r3, #(AT91_PMC_MUL & ~0xff0000) + beq 4f +3: wait_pllalock +4: #ifdef SLOWDOWN_MASTER_CLOCK /* -- cgit v1.1 From 531d8791accf1464bc6854ff69d08dd866189d17 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Fri, 9 Apr 2010 10:57:33 +0200 Subject: ALSA: hda - Fix auto-parser of ALC269vb for HP pin NID 0x21 ALC269vb has an alternative HP pin 0x21 in addition. Fix the parser to recognize it. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2971e48..fbbdfbc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12869,6 +12869,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, dac = 0x02; break; case 0x15: + case 0x21: /* ALC269vb has this pin, too */ dac = 0x03; break; default: -- cgit v1.1 From 226b1ec8c18bcb6d1aa448a29b2c8aeae1946228 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Fri, 9 Apr 2010 11:01:20 +0200 Subject: ALSA: hda - Fix setup for ALC269vb amic and dmic models Corrected HP and mic pins for ALC269vb amic and dmic models. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fbbdfbc..9b58f29 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -13789,19 +13789,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec, } } -static void alc269_laptop_dmic_setup(struct hda_codec *codec) +static void alc269_laptop_amic_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; - spec->int_mic.pin = 0x12; - spec->int_mic.mux_idx = 5; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; spec->auto_mic = 1; } -static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) +static void alc269_laptop_dmic_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x15; @@ -13809,14 +13809,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; - spec->int_mic.mux_idx = 6; + spec->int_mic.mux_idx = 5; spec->auto_mic = 1; } -static void alc269_laptop_amic_setup(struct hda_codec *codec) +static void alc269vb_laptop_amic_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.hp_pins[0] = 0x21; spec->autocfg.speaker_pins[0] = 0x14; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; @@ -13825,6 +13825,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec) spec->auto_mic = 1; } +static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.speaker_pins[0] = 0x14; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x12; + spec->int_mic.mux_idx = 6; + spec->auto_mic = 1; +} + static void alc269_laptop_inithook(struct hda_codec *codec) { alc269_speaker_automute(codec); @@ -14162,7 +14174,7 @@ static struct alc_config_preset alc269_presets[] = { .num_channel_mode = ARRAY_SIZE(alc269_modes), .channel_mode = alc269_modes, .unsol_event = alc269_laptop_unsol_event, - .setup = alc269_laptop_amic_setup, + .setup = alc269vb_laptop_amic_setup, .init_hook = alc269_laptop_inithook, }, [ALC269VB_DMIC] = { -- cgit v1.1 From 85b3cce880a19e78286570d5fd004cc3cac06f57 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 9 Apr 2010 15:00:11 +0100 Subject: ARM: Fix ioremap_cached()/ioremap_wc() for SMP platforms Write combining/cached device mappings are not setting the shared bit, which could potentially cause problems on SMP systems since the cache lines won't participate in the cache coherency protocol. Signed-off-by: Russell King Tested-by: Santosh Shilimkar --- arch/arm/mm/mmu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9d4da6a..4223d08 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -420,6 +420,10 @@ static void __init build_mem_type_table(void) user_pgprot |= L_PTE_SHARED; kern_pgprot |= L_PTE_SHARED; vecs_pgprot |= L_PTE_SHARED; + mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S; + mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; + mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; + mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; #endif -- cgit v1.1 From 7f311a46916a3be00a1a8e3f1bdf461d08f1d263 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 Apr 2010 17:32:23 +0200 Subject: ALSA: hda - Fix initial capture source connections of ALC880/260 The widget connections of ADC of ALC880 and ALC2260 aren't initialized, thus it might point to invalid pin. This can be a problem when mode=auto and there is only one input pin. Then user can't change the connection at all. This patch adds the code to initialize the input pin connection of these codecs. Reference: Novell bnc#594363 https://bugzilla.novell.com/show_bug.cgi?id=594363 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9b58f29..8d60b1f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4809,6 +4809,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) } } +static void alc880_auto_init_input_src(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int c; + + for (c = 0; c < spec->num_adc_nids; c++) { + unsigned int mux_idx; + const struct hda_input_mux *imux; + mux_idx = c >= spec->num_mux_defs ? 0 : c; + imux = &spec->input_mux[mux_idx]; + if (!imux->num_items && mux_idx > 0) + imux = &spec->input_mux[0]; + if (imux) + snd_hda_codec_write(codec, spec->adc_nids[c], 0, + AC_VERB_SET_CONNECT_SEL, + imux->items[0].index); + } +} + /* parse the BIOS configuration and set up the alc_spec */ /* return 1 if successful, 0 if the proper config is not found, * or a negative error code @@ -4887,6 +4906,7 @@ static void alc880_auto_init(struct hda_codec *codec) alc880_auto_init_multi_out(codec); alc880_auto_init_extra_out(codec); alc880_auto_init_analog_input(codec); + alc880_auto_init_input_src(codec); if (spec->unsol_event) alc_inithook(codec); } @@ -6398,6 +6418,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) } } +#define alc260_auto_init_input_src alc880_auto_init_input_src + /* * generic initialization of ADC, input mixers and output mixers */ @@ -6484,6 +6506,7 @@ static void alc260_auto_init(struct hda_codec *codec) struct alc_spec *spec = codec->spec; alc260_auto_init_multi_out(codec); alc260_auto_init_analog_input(codec); + alc260_auto_init_input_src(codec); if (spec->unsol_event) alc_inithook(codec); } -- cgit v1.1 From 2844a76a25a2fc2f5025cf128c95a14d86146d33 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 9 Apr 2010 15:46:42 -0700 Subject: ceph: decode v5 of osdmap (pool names) [protocol change] Teach the client to decode an updated format for the osdmap. The new format includes pool names, which will be useful shortly. Get this change in earlier rather than later. Signed-off-by: Sage Weil --- fs/ceph/osdmap.c | 180 +++++++++++++++++++++++++++++++++---------------------- fs/ceph/osdmap.h | 1 + fs/ceph/rados.h | 6 +- 3 files changed, 114 insertions(+), 73 deletions(-) diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index d82fe87..7526d6d 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -312,71 +312,6 @@ bad: return ERR_PTR(err); } - -/* - * osd map - */ -void ceph_osdmap_destroy(struct ceph_osdmap *map) -{ - dout("osdmap_destroy %p\n", map); - if (map->crush) - crush_destroy(map->crush); - while (!RB_EMPTY_ROOT(&map->pg_temp)) { - struct ceph_pg_mapping *pg = - rb_entry(rb_first(&map->pg_temp), - struct ceph_pg_mapping, node); - rb_erase(&pg->node, &map->pg_temp); - kfree(pg); - } - while (!RB_EMPTY_ROOT(&map->pg_pools)) { - struct ceph_pg_pool_info *pi = - rb_entry(rb_first(&map->pg_pools), - struct ceph_pg_pool_info, node); - rb_erase(&pi->node, &map->pg_pools); - kfree(pi); - } - kfree(map->osd_state); - kfree(map->osd_weight); - kfree(map->osd_addr); - kfree(map); -} - -/* - * adjust max osd value. reallocate arrays. - */ -static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) -{ - u8 *state; - struct ceph_entity_addr *addr; - u32 *weight; - - state = kcalloc(max, sizeof(*state), GFP_NOFS); - addr = kcalloc(max, sizeof(*addr), GFP_NOFS); - weight = kcalloc(max, sizeof(*weight), GFP_NOFS); - if (state == NULL || addr == NULL || weight == NULL) { - kfree(state); - kfree(addr); - kfree(weight); - return -ENOMEM; - } - - /* copy old? */ - if (map->osd_state) { - memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); - memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); - memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); - kfree(map->osd_state); - kfree(map->osd_addr); - kfree(map->osd_weight); - } - - map->osd_state = state; - map->osd_weight = weight; - map->osd_addr = addr; - map->max_osd = max; - return 0; -} - /* * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid * to a set of osds) @@ -480,6 +415,13 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id) return NULL; } +static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi) +{ + rb_erase(&pi->node, root); + kfree(pi->name); + kfree(pi); +} + void __decode_pool(void **p, struct ceph_pg_pool_info *pi) { ceph_decode_copy(p, &pi->v, sizeof(pi->v)); @@ -488,6 +430,98 @@ void __decode_pool(void **p, struct ceph_pg_pool_info *pi) *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; } +static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map) +{ + struct ceph_pg_pool_info *pi; + u32 num, len, pool; + + ceph_decode_32_safe(p, end, num, bad); + dout(" %d pool names\n", num); + while (num--) { + ceph_decode_32_safe(p, end, pool, bad); + ceph_decode_32_safe(p, end, len, bad); + dout(" pool %d len %d\n", pool, len); + pi = __lookup_pg_pool(&map->pg_pools, pool); + if (pi) { + kfree(pi->name); + pi->name = kmalloc(len + 1, GFP_NOFS); + if (pi->name) { + memcpy(pi->name, *p, len); + pi->name[len] = '\0'; + dout(" name is %s\n", pi->name); + } + } + *p += len; + } + return 0; + +bad: + return -EINVAL; +} + +/* + * osd map + */ +void ceph_osdmap_destroy(struct ceph_osdmap *map) +{ + dout("osdmap_destroy %p\n", map); + if (map->crush) + crush_destroy(map->crush); + while (!RB_EMPTY_ROOT(&map->pg_temp)) { + struct ceph_pg_mapping *pg = + rb_entry(rb_first(&map->pg_temp), + struct ceph_pg_mapping, node); + rb_erase(&pg->node, &map->pg_temp); + kfree(pg); + } + while (!RB_EMPTY_ROOT(&map->pg_pools)) { + struct ceph_pg_pool_info *pi = + rb_entry(rb_first(&map->pg_pools), + struct ceph_pg_pool_info, node); + __remove_pg_pool(&map->pg_pools, pi); + } + kfree(map->osd_state); + kfree(map->osd_weight); + kfree(map->osd_addr); + kfree(map); +} + +/* + * adjust max osd value. reallocate arrays. + */ +static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) +{ + u8 *state; + struct ceph_entity_addr *addr; + u32 *weight; + + state = kcalloc(max, sizeof(*state), GFP_NOFS); + addr = kcalloc(max, sizeof(*addr), GFP_NOFS); + weight = kcalloc(max, sizeof(*weight), GFP_NOFS); + if (state == NULL || addr == NULL || weight == NULL) { + kfree(state); + kfree(addr); + kfree(weight); + return -ENOMEM; + } + + /* copy old? */ + if (map->osd_state) { + memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); + memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); + memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); + kfree(map->osd_state); + kfree(map->osd_addr); + kfree(map->osd_weight); + } + + map->osd_state = state; + map->osd_weight = weight; + map->osd_addr = addr; + map->max_osd = max; + return 0; +} + /* * decode a full map. */ @@ -524,7 +558,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_32_safe(p, end, max, bad); while (max--) { ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad); - pi = kmalloc(sizeof(*pi), GFP_NOFS); + pi = kzalloc(sizeof(*pi), GFP_NOFS); if (!pi) goto bad; pi->id = ceph_decode_32(p); @@ -537,6 +571,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) __decode_pool(p, pi); __insert_pg_pool(&map->pg_pools, pi); } + + if (version >= 5 && __decode_pool_names(p, end, map) < 0) + goto bad; + ceph_decode_32_safe(p, end, map->pool_max, bad); ceph_decode_32_safe(p, end, map->flags, bad); @@ -710,7 +748,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, } pi = __lookup_pg_pool(&map->pg_pools, pool); if (!pi) { - pi = kmalloc(sizeof(*pi), GFP_NOFS); + pi = kzalloc(sizeof(*pi), GFP_NOFS); if (!pi) { err = -ENOMEM; goto bad; @@ -720,6 +758,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, } __decode_pool(p, pi); } + if (version >= 5 && __decode_pool_names(p, end, map) < 0) + goto bad; /* old_pool */ ceph_decode_32_safe(p, end, len, bad); @@ -728,10 +768,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, ceph_decode_32_safe(p, end, pool, bad); pi = __lookup_pg_pool(&map->pg_pools, pool); - if (pi) { - rb_erase(&pi->node, &map->pg_pools); - kfree(pi); - } + if (pi) + __remove_pg_pool(&map->pg_pools, pi); } /* new_up */ diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h index 1fb55af..8bc9f1e 100644 --- a/fs/ceph/osdmap.h +++ b/fs/ceph/osdmap.h @@ -23,6 +23,7 @@ struct ceph_pg_pool_info { int id; struct ceph_pg_pool v; int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask; + char *name; }; struct ceph_pg_mapping { diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index 26ac8b8..a1fc1d0 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h @@ -11,8 +11,10 @@ /* * osdmap encoding versions */ -#define CEPH_OSDMAP_INC_VERSION 4 -#define CEPH_OSDMAP_VERSION 4 +#define CEPH_OSDMAP_INC_VERSION 5 +#define CEPH_OSDMAP_INC_VERSION_EXT 5 +#define CEPH_OSDMAP_VERSION 5 +#define CEPH_OSDMAP_VERSION_EXT 5 /* * fs id -- cgit v1.1 From 65384a1d41c4e91f0b49d90d11b7f424d6e5c58e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 9 Apr 2010 15:01:25 -0400 Subject: drm/radeon/kms: more atom parser fixes (v2) shr/shl ops need the full dst rather than the pre-masked version. Fixes fdo bug 27478 and kernel bug 15738. v2: remove some unsed vars, add comments Signed-off-by: Alex Deucher Cc: stable Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atom.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 58845e0..a8bf500 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -907,11 +907,16 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) uint8_t attr = U8((*ptr)++), shift; uint32_t saved, dst; int dptr = *ptr; + uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3]; SDEBUG(" dst: "); dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); + /* op needs to full dst value */ + dst = saved; shift = atom_get_src(ctx, attr, ptr); SDEBUG(" shift: %d\n", shift); dst <<= shift; + dst &= atom_arg_mask[dst_align]; + dst >>= atom_arg_shift[dst_align]; SDEBUG(" dst: "); atom_put_dst(ctx, arg, attr, &dptr, dst, saved); } @@ -921,11 +926,16 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) uint8_t attr = U8((*ptr)++), shift; uint32_t saved, dst; int dptr = *ptr; + uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3]; SDEBUG(" dst: "); dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); + /* op needs to full dst value */ + dst = saved; shift = atom_get_src(ctx, attr, ptr); SDEBUG(" shift: %d\n", shift); dst >>= shift; + dst &= atom_arg_mask[dst_align]; + dst >>= atom_arg_shift[dst_align]; SDEBUG(" dst: "); atom_put_dst(ctx, arg, attr, &dptr, dst, saved); } -- cgit v1.1 From 80e60639f1b7c121a7fea53920c5a4b94009361a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 25 Mar 2010 13:51:05 -0400 Subject: NFSv4: Fall back to ordinary lookup if nfs4_atomic_open() returns EISDIR Signed-off-by: Trond Myklebust Cc: stable@kernel.org --- fs/nfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c6f2750..be46f26 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1025,12 +1025,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry res = NULL; goto out; /* This turned out not to be a regular file */ + case -EISDIR: case -ENOTDIR: goto no_open; case -ELOOP: if (!(nd->intent.open.flags & O_NOFOLLOW)) goto no_open; - /* case -EISDIR: */ /* case -EINVAL: */ default: goto out; -- cgit v1.1 From 1544fa0f7a46241582abc48f07b74f3d846379e4 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 25 Mar 2010 13:54:49 -0400 Subject: NFS: Fix the mode calculation in nfs_find_open_context Signed-off-by: Trond Myklebust --- fs/nfs/inode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 737128f..50a56ed 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -623,10 +623,10 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c list_for_each_entry(pos, &nfsi->open_files, list) { if (cred != NULL && pos->cred != cred) continue; - if ((pos->mode & mode) == mode) { - ctx = get_nfs_open_context(pos); - break; - } + if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode) + continue; + ctx = get_nfs_open_context(pos); + break; } spin_unlock(&inode->i_lock); return ctx; -- cgit v1.1 From b80c3cb628f0ebc241b02e38dd028969fb8026a2 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 9 Apr 2010 19:07:07 -0400 Subject: NFS: Ensure that writeback_single_inode() calls write_inode() when syncing Since writeback_single_inode() checks the inode->i_state flags _before_ it flushes out the data, we need to ensure that the I_DIRTY_DATASYNC flag is already set. Otherwise we risk not seeing a call to write_inode(), which again means that we break fsync() et al... Signed-off-by: Trond Myklebust --- fs/nfs/write.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 53ff70e..7f40ea3 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -421,6 +421,7 @@ static void nfs_mark_request_dirty(struct nfs_page *req) { __set_page_dirty_nobuffers(req->wb_page); + __mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC); } #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) @@ -660,6 +661,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, req = nfs_setup_write_request(ctx, page, offset, count); if (IS_ERR(req)) return PTR_ERR(req); + nfs_mark_request_dirty(req); /* Update file length */ nfs_grow_file(page, offset, count); nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); @@ -739,8 +741,6 @@ int nfs_updatepage(struct file *file, struct page *page, status = nfs_writepage_setup(ctx, page, offset, count); if (status < 0) nfs_set_pageerror(page); - else - __set_page_dirty_nobuffers(page); dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n", status, (long long)i_size_read(inode)); -- cgit v1.1 From a6305ddb080fb483ca41ca56cacb6f96089f0c8e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 9 Apr 2010 19:07:08 -0400 Subject: NFS: Fix a race with the new commit code This patch fixes a race which occurs due to the fact that we release the PG_writeback flag while still holding the nfs_page locked. Signed-off-by: Trond Myklebust --- fs/nfs/write.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 7f40ea3..40297c4 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -201,6 +201,7 @@ static int nfs_set_page_writeback(struct page *page) struct inode *inode = page->mapping->host; struct nfs_server *nfss = NFS_SERVER(inode); + page_cache_get(page); if (atomic_long_inc_return(&nfss->writeback) > NFS_CONGESTION_ON_THRESH) { set_bdi_congested(&nfss->backing_dev_info, @@ -216,6 +217,7 @@ static void nfs_end_page_writeback(struct page *page) struct nfs_server *nfss = NFS_SERVER(inode); end_page_writeback(page); + page_cache_release(page); if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC); } @@ -665,6 +667,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, /* Update file length */ nfs_grow_file(page, offset, count); nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); + nfs_mark_request_dirty(req); nfs_clear_page_tag_locked(req); return 0; } @@ -749,13 +752,12 @@ int nfs_updatepage(struct file *file, struct page *page, static void nfs_writepage_release(struct nfs_page *req) { + struct page *page = req->wb_page; - if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) { - nfs_end_page_writeback(req->wb_page); + if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) nfs_inode_remove_request(req); - } else - nfs_end_page_writeback(req->wb_page); nfs_clear_page_tag_locked(req); + nfs_end_page_writeback(page); } static int flush_task_priority(int how) @@ -847,9 +849,11 @@ static int nfs_write_rpcsetup(struct nfs_page *req, */ static void nfs_redirty_request(struct nfs_page *req) { + struct page *page = req->wb_page; + nfs_mark_request_dirty(req); - nfs_end_page_writeback(req->wb_page); nfs_clear_page_tag_locked(req); + nfs_end_page_writeback(page); } /* @@ -1084,16 +1088,15 @@ static void nfs_writeback_release_full(void *calldata) if (nfs_write_need_commit(data)) { memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); nfs_mark_request_commit(req); - nfs_end_page_writeback(page); dprintk(" marked for commit\n"); goto next; } dprintk(" OK\n"); remove_request: - nfs_end_page_writeback(page); nfs_inode_remove_request(req); next: nfs_clear_page_tag_locked(req); + nfs_end_page_writeback(page); } nfs_writedata_release(calldata); } -- cgit v1.1 From 2c61be0a9478258f77b66208a0c4b1f5f8161c3c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 9 Apr 2010 19:54:50 -0400 Subject: NFS: Ensure that the WRITE and COMMIT RPC calls are always uninterruptible We always want to ensure that WRITE and COMMIT completes, whether or not the user presses ^C. Do this by making the call asynchronous, and allowing the user to do an interruptible wait for rpc_task completion. Signed-off-by: Trond Myklebust --- fs/nfs/write.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 40297c4..de38d63 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -781,7 +781,6 @@ static int nfs_write_rpcsetup(struct nfs_page *req, int how) { struct inode *inode = req->wb_context->path.dentry->d_inode; - int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; int priority = flush_task_priority(how); struct rpc_task *task; struct rpc_message msg = { @@ -796,9 +795,10 @@ static int nfs_write_rpcsetup(struct nfs_page *req, .callback_ops = call_ops, .callback_data = data, .workqueue = nfsiod_workqueue, - .flags = flags, + .flags = RPC_TASK_ASYNC, .priority = priority, }; + int ret = 0; /* Set up the RPC argument and reply structs * NB: take care not to mess about with data->commit et al. */ @@ -837,10 +837,18 @@ static int nfs_write_rpcsetup(struct nfs_page *req, (unsigned long long)data->args.offset); task = rpc_run_task(&task_setup_data); - if (IS_ERR(task)) - return PTR_ERR(task); + if (IS_ERR(task)) { + ret = PTR_ERR(task); + goto out; + } + if (how & FLUSH_SYNC) { + ret = rpc_wait_for_completion_task(task); + if (ret == 0) + ret = task->tk_status; + } rpc_put_task(task); - return 0; +out: + return ret; } /* If a nfs_flush_* function fails, it should remove reqs from @head and @@ -1210,7 +1218,6 @@ static int nfs_commit_rpcsetup(struct list_head *head, { struct nfs_page *first = nfs_list_entry(head->next); struct inode *inode = first->wb_context->path.dentry->d_inode; - int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; int priority = flush_task_priority(how); struct rpc_task *task; struct rpc_message msg = { @@ -1225,7 +1232,7 @@ static int nfs_commit_rpcsetup(struct list_head *head, .callback_ops = &nfs_commit_ops, .callback_data = data, .workqueue = nfsiod_workqueue, - .flags = flags, + .flags = RPC_TASK_ASYNC, .priority = priority, }; @@ -1255,6 +1262,8 @@ static int nfs_commit_rpcsetup(struct list_head *head, task = rpc_run_task(&task_setup_data); if (IS_ERR(task)) return PTR_ERR(task); + if (how & FLUSH_SYNC) + rpc_wait_for_completion_task(task); rpc_put_task(task); return 0; } -- cgit v1.1 From bfac4d6725baacbfc085c38e231b8582a1b8f62b Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 7 Apr 2010 17:11:22 +0800 Subject: drm/i915: Ignore LVDS EDID when it is unavailabe or invalid This trys to shut up complains about invalid LVDS EDID during mode probe, but uses fixed panel mode directly for panels with broken EDID. https://bugs.freedesktop.org/show_bug.cgi?id=23099 https://bugs.freedesktop.org/show_bug.cgi?id=26395 Signed-off-by: Zhao Yakui Tested-by: Sitsofe Wheeler Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_lvds.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b7cb4aa..6960849 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -611,6 +611,8 @@ typedef struct drm_i915_private { /* Reclocking support */ bool render_reclock_avail; bool lvds_downclock_avail; + /* indicate whether the LVDS EDID is OK */ + bool lvds_edid_good; /* indicates the reduced downclock for LVDS*/ int lvds_downclock; struct work_struct idle_work; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 8238b40..527cfa2 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -638,10 +638,12 @@ static int intel_lvds_get_modes(struct drm_connector *connector) struct drm_i915_private *dev_priv = dev->dev_private; int ret = 0; - ret = intel_ddc_get_modes(intel_encoder); + if (dev_priv->lvds_edid_good) { + ret = intel_ddc_get_modes(intel_encoder); - if (ret) - return ret; + if (ret) + return ret; + } /* Didn't get an EDID, so * Set wide sync ranges so we get all modes @@ -1062,7 +1064,10 @@ void intel_lvds_init(struct drm_device *dev) * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. */ - intel_ddc_get_modes(intel_encoder); + dev_priv->lvds_edid_good = true; + + if (!intel_ddc_get_modes(intel_encoder)) + dev_priv->lvds_edid_good = false; list_for_each_entry(scan, &connector->probed_modes, head) { mutex_lock(&dev->mode_config.mutex); -- cgit v1.1 From 4ba1d9c0c22947a9207029e7184733252e6135f1 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 31 Mar 2010 16:26:39 +0200 Subject: firewire: cdev: disallow receive packets without header In receive contexts, reject packets with header_length==0. This would be an instruction to queue zero packets which would not make sense. This prevents a division by zero in the OHCI driver. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core-cdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 8be720b..bbb8160 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -968,7 +968,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg) if (ctx->header_size == 0) { if (u.packet.header_length > 0) return -EINVAL; - } else if (u.packet.header_length % ctx->header_size != 0) { + } else if (u.packet.header_length == 0 || + u.packet.header_length % ctx->header_size != 0) { return -EINVAL; } header_length = 0; -- cgit v1.1 From 385ab5bcd4be586dffdba550b310308d89eade71 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 31 Mar 2010 16:26:46 +0200 Subject: firewire: cdev: require quadlet-aligned headers for transmit packets The definition of struct fw_cdev_iso_packet seems to imply that the header_length must be quadlet-aligned, and in fact, specifying an unaligned header has never really worked when using multiple packet structures, because the position of the next control word is computed by rounding the header_length _down_, so the last one to three bytes of the header would overlap the next control word. To avoid this problem, check that the header length is properly aligned. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core-cdev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index bbb8160..5eba9e0 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -959,6 +959,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg) u.packet.header_length = GET_HEADER_LENGTH(control); if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { + if (u.packet.header_length % 4 != 0) + return -EINVAL; header_length = u.packet.header_length; } else { /* -- cgit v1.1 From 9cac00b8f0079d5d3d54ec4dae453d58dec30e7c Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 7 Apr 2010 08:30:50 +0200 Subject: firewire: cdev: fix information leak A userspace client got to see uninitialized stack-allocated memory if it specified an _IOC_READ type of ioctl and an argument size larger than expected by firewire-core's ioctl handlers (but not larger than the core's union ioctl_arg). Fix this by clearing the requested buffer size to zero, but only at _IOR ioctls. This way, there is almost no runtime penalty to legitimate ioctls. The only legitimate _IOR is FW_CDEV_IOC_GET_CYCLE_TIMER with 12 or 16 bytes to memset. [Another way to fix this would be strict checking of argument size (and possibly direction) vs. command number. However, we then need a lookup table, and we need to allow for slight size deviations in case of 32bit userland on 64bit kernel.] Reported-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core-cdev.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 5eba9e0..0d3df09 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -1356,24 +1356,24 @@ static int dispatch_ioctl(struct client *client, return -ENODEV; if (_IOC_TYPE(cmd) != '#' || - _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers)) + _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) || + _IOC_SIZE(cmd) > sizeof(buffer)) return -EINVAL; - if (_IOC_DIR(cmd) & _IOC_WRITE) { - if (_IOC_SIZE(cmd) > sizeof(buffer) || - copy_from_user(&buffer, arg, _IOC_SIZE(cmd))) + if (_IOC_DIR(cmd) == _IOC_READ) + memset(&buffer, 0, _IOC_SIZE(cmd)); + + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd))) return -EFAULT; - } ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer); if (ret < 0) return ret; - if (_IOC_DIR(cmd) & _IOC_READ) { - if (_IOC_SIZE(cmd) > sizeof(buffer) || - copy_to_user(arg, &buffer, _IOC_SIZE(cmd))) + if (_IOC_DIR(cmd) & _IOC_READ) + if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd))) return -EFAULT; - } return ret; } -- cgit v1.1 From aa6fec3cdeb14ecc916eb78c4cd9ed79e4f7fe8d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 31 Mar 2010 16:26:52 +0200 Subject: firewire: cdev: iso packet documentation Add the missing documentation for iso packets. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- include/linux/firewire-cdev.h | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 40b1101..011fdf1 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h @@ -438,7 +438,7 @@ struct fw_cdev_remove_descriptor { * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE * @header_size: Header size to strip for receive contexts * @channel: Channel to bind to - * @speed: Speed to transmit at + * @speed: Speed for transmit contexts * @closure: To be returned in &fw_cdev_event_iso_interrupt * @handle: Handle to context, written back by kernel * @@ -451,6 +451,9 @@ struct fw_cdev_remove_descriptor { * If a context was successfully created, the kernel writes back a handle to the * context, which must be passed in for subsequent operations on that context. * + * For receive contexts, @header_size must be at least 4 and must be a multiple + * of 4. + * * Note that the effect of a @header_size > 4 depends on * &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt. */ @@ -481,10 +484,34 @@ struct fw_cdev_create_iso_context { * * &struct fw_cdev_iso_packet is used to describe isochronous packet queues. * - * Use the FW_CDEV_ISO_ macros to fill in @control. The sy and tag fields are - * specified by IEEE 1394a and IEC 61883. - * - * FIXME - finish this documentation + * Use the FW_CDEV_ISO_ macros to fill in @control. + * + * For transmit packets, the header length must be a multiple of 4 and specifies + * the numbers of bytes in @header that will be prepended to the packet's + * payload; these bytes are copied into the kernel and will not be accessed + * after the ioctl has returned. The sy and tag fields are copied to the iso + * packet header (these fields are specified by IEEE 1394a and IEC 61883-1). + * The skip flag specifies that no packet is to be sent in a frame; when using + * this, all other fields except the interrupt flag must be zero. + * + * For receive packets, the header length must be a multiple of the context's + * header size; if the header length is larger than the context's header size, + * multiple packets are queued for this entry. The sy and tag fields are + * ignored. If the sync flag is set, the context drops all packets until + * a packet with a matching sy field is received (the sync value to wait for is + * specified in the &fw_cdev_start_iso structure). The payload length defines + * how many payload bytes can be received for one packet (in addition to payload + * quadlets that have been defined as headers and are stripped and returned in + * the &fw_cdev_event_iso_interrupt structure). If more bytes are received, the + * additional bytes are dropped. If less bytes are received, the remaining + * bytes in this part of the payload buffer will not be written to, not even by + * the next packet, i.e., packets received in consecutive frames will not + * necessarily be consecutive in memory. If an entry has queued multiple + * packets, the payload length is divided equally among them. + * + * When a packet with the interrupt flag set has been completed, the + * &fw_cdev_event_iso_interrupt event will be sent. An entry that has queued + * multiple receive packets is completed when its last packet is completed. */ struct fw_cdev_iso_packet { __u32 control; @@ -501,7 +528,7 @@ struct fw_cdev_iso_packet { * Queue a number of isochronous packets for reception or transmission. * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs, * which describe how to transmit from or receive into a contiguous region - * of a mmap()'ed payload buffer. As part of the packet descriptors, + * of a mmap()'ed payload buffer. As part of transmit packet descriptors, * a series of headers can be supplied, which will be prepended to the * payload during DMA. * -- cgit v1.1 From ca658b1e29d6be939207532e337fb640eb697f71 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 10 Apr 2010 12:23:09 +0200 Subject: firewire: cdev: comment fixlet Signed-off-by: Stefan Richter --- include/linux/firewire-cdev.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 011fdf1..6ffb24a 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h @@ -647,8 +647,8 @@ struct fw_cdev_get_cycle_timer2 { * instead of allocated. * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation. * - * To summarize, %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE allocates iso resources - * for the lifetime of the fd or handle. + * To summarize, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE allocates iso resources + * for the lifetime of the fd or @handle. * In contrast, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE allocates iso resources * for the duration of a bus generation. * -- cgit v1.1 From 29aac005ff4dc8a5f50b80f4e5c4f59b21c0fb50 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 10 Apr 2010 21:27:23 +0200 Subject: ALSA: usb - Fix Oops after usb-midi disconnection usb-midi causes sometimes Oops at snd_usbmidi_output_drain() after disconnection. This is due to the access to the endpoints which have been already released at disconnection while the files are still alive. This patch fixes the problem by checking disconnection state at snd_usbmidi_output_drain() and by releasing urbs but keeping the endpoint instances until really all freed. Tested-by: Tvrtko Ursulin Cc: Signed-off-by: Takashi Iwai --- sound/usb/usbmidi.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 2c59afd..9e28b20 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) DEFINE_WAIT(wait); long timeout = msecs_to_jiffies(50); + if (ep->umidi->disconnected) + return; /* * The substream buffer is empty, but some data might still be in the * currently active URBs, so we have to wait for those to complete. @@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, * Frees an output endpoint. * May be called when ep hasn't been initialized completely. */ -static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) +static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep) { unsigned int i; for (i = 0; i < OUTPUT_URBS; ++i) - if (ep->urbs[i].urb) + if (ep->urbs[i].urb) { free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, ep->max_transfer); + ep->urbs[i].urb = NULL; + } +} + +static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep) +{ + snd_usbmidi_out_endpoint_clear(ep); kfree(ep); } @@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p) usb_kill_urb(ep->out->urbs[j].urb); if (umidi->usb_protocol_ops->finish_out_endpoint) umidi->usb_protocol_ops->finish_out_endpoint(ep->out); + ep->out->active_urbs = 0; + if (ep->out->drain_urbs) { + ep->out->drain_urbs = 0; + wake_up(&ep->out->drain_wait); + } } if (ep->in) for (j = 0; j < INPUT_URBS; ++j) usb_kill_urb(ep->in->urbs[j]); /* free endpoints here; later call can result in Oops */ - if (ep->out) { - snd_usbmidi_out_endpoint_delete(ep->out); - ep->out = NULL; - } + if (ep->out) + snd_usbmidi_out_endpoint_clear(ep->out); if (ep->in) { snd_usbmidi_in_endpoint_delete(ep->in); ep->in = NULL; -- cgit v1.1 From d88d4050dcaf09e417aaa9a5024dd9449ef71b2e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sat, 10 Apr 2010 22:28:56 +0200 Subject: PM / Hibernate: user.c, fix SNAPSHOT_SET_SWAP_AREA handling When CONFIG_DEBUG_BLOCK_EXT_DEVT is set we decode the device improperly by old_decode_dev and it results in an error while hibernating with s2disk. All users already pass the new device number, so switch to new_decode_dev(). Signed-off-by: Jiri Slaby Reported-and-tested-by: Jiri Kosina Signed-off-by: "Rafael J. Wysocki" --- kernel/power/user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/power/user.c b/kernel/power/user.c index 4d22896..a8c9621 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -420,7 +420,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, * User space encodes device types as two-byte values, * so we need to recode them */ - swdev = old_decode_dev(swap_area.dev); + swdev = new_decode_dev(swap_area.dev); if (swdev) { offset = swap_area.offset; data->swap = swap_type_of(swdev, offset, NULL); -- cgit v1.1 From d3e03f4ea81456d52810a03a17dd88f78a080818 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 7 Apr 2010 14:12:56 +0200 Subject: pcmcia: use previously assigned IRQ for all card functions Use a previously assigned IRQ for all card functions, not only if CONFIG_PCMCIA_PROBE is set. Reported-by: Alexander Kurz Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_resource.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index caec1de..7c3d03b 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -755,12 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) else printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n"); -#ifdef CONFIG_PCMCIA_PROBE - - if (s->irq.AssignedIRQ != 0) { - /* If the interrupt is already assigned, it must be the same */ + /* If the interrupt is already assigned, it must be the same */ + if (s->irq.AssignedIRQ != 0) irq = s->irq.AssignedIRQ; - } else { + +#ifdef CONFIG_PCMCIA_PROBE + if (!irq) { int try; u32 mask = s->irq_mask; void *data = p_dev; /* something unique to this device */ -- cgit v1.1 From 509b0865fbd8ab6c820397706dde980c1c285538 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 8 Apr 2010 19:23:07 +0200 Subject: pcmcia: fix io_probe due to parent (PCI) resources Similar to commit 7a96e87d, we need to be aware of any parent PCI device when requesting IO regions, even only for testing ("probing"). Reported-by: Komuro Signed-off-by: Dominik Brodowski --- drivers/pcmcia/rsrc_nonstatic.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 559069a..1178a82 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, return; } for (i = base, most = 0; i < base+num; i += 8) { - res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); + res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); if (!res) continue; hole = inb(i); @@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, bad = any = 0; for (i = base; i < base+num; i += 8) { - res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); - if (!res) + res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); + if (!res) { + if (!any) + printk(" excluding"); + if (!bad) + bad = any = i; continue; + } for (j = 0; j < 8; j++) if (inb(i+j) != most) break; @@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, } if (bad) { if ((num > 16) && (bad == base) && (i == base+num)) { + sub_interval(&s_data->io_db, bad, i-bad); printk(" nothing: probe failed.\n"); return; } else { -- cgit v1.1 From b1095afe6fd6ea4c0d9e75489b955f898d6617d9 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 8 Apr 2010 20:10:21 +0200 Subject: pcmcia: re-start on MFC override If there are changes to the number of socket devices, we need to start over in all cases: else pcmcia_request_configuration() might get confused. Reported-by: Alexander Kurz Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index cb6036d..4014cf8 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -687,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s) new_funcs = mfc.nfn; else new_funcs = 1; - if (old_funcs > new_funcs) { + if (old_funcs != new_funcs) { + /* we need to re-start */ pcmcia_card_remove(s, NULL); pcmcia_card_add(s); - } else if (new_funcs > old_funcs) { - s->functions = new_funcs; - pcmcia_device_add(s, 1); } } @@ -728,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) struct pcmcia_socket *s = dev->socket; const struct firmware *fw; int ret = -ENOMEM; + cistpl_longlink_mfc_t mfc; + int old_funcs, new_funcs = 1; if (!filename) return -EINVAL; @@ -750,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) goto release; } + /* we need to re-start if the number of functions changed */ + old_funcs = s->functions; + if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, + &mfc)) + new_funcs = mfc.nfn; + + if (old_funcs != new_funcs) + ret = -EBUSY; /* update information */ pcmcia_device_query(dev); @@ -858,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { dev_dbg(&dev->dev, "device needs a fake CIS\n"); if (!dev->socket->fake_cis) - pcmcia_load_firmware(dev, did->cisfile); - - if (!dev->socket->fake_cis) - return 0; + if (pcmcia_load_firmware(dev, did->cisfile)) + return 0; } if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { -- cgit v1.1 From be3bd2223b89d270853302ab0a5909fa875fd831 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 12 Apr 2010 01:51:03 +0900 Subject: nilfs2: fix typo "numer" -> "number" in alloc.c Fixes the typo found in a warning message of a persistent object allocator function. Signed-off-by: Ryusuke Konishi --- fs/nilfs2/alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index 3f959f1..c2a1387 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c @@ -425,7 +425,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode, bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh); if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), group_offset, bitmap)) - printk(KERN_WARNING "%s: entry numer %llu already freed\n", + printk(KERN_WARNING "%s: entry number %llu already freed\n", __func__, (unsigned long long)req->pr_entry_nr); nilfs_palloc_group_desc_add_entries(inode, group, desc, 1); -- cgit v1.1 From ce227c4183a2c18c9e5467b7e92d47140e763ab9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 9 Apr 2010 06:27:00 +0000 Subject: drm/radeon/kms: only change mode when coherent value changes. On X startup we were getting a flicker where there shouldn't have been one. the X DDX calls the kernel to set the properties to the same values (yes it could be smarter), however the kernel was doing a pointless modeset then, making my nice smooth boot ugly. Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_connectors.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 3fba505..3bc2040 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -287,6 +287,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr if (property == rdev->mode_info.coherent_mode_property) { struct radeon_encoder_atom_dig *dig; + bool new_coherent_mode; /* need to find digital encoder on connector */ encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); @@ -299,8 +300,11 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr return 0; dig = radeon_encoder->enc_priv; - dig->coherent_mode = val ? true : false; - radeon_property_change_mode(&radeon_encoder->base); + new_coherent_mode = val ? true : false; + if (dig->coherent_mode != new_coherent_mode) { + dig->coherent_mode = new_coherent_mode; + radeon_property_change_mode(&radeon_encoder->base); + } } if (property == rdev->mode_info.tv_std_property) { -- cgit v1.1 From b73c5f8b2f85a7041e045e0009d046780416948d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 11 Apr 2010 03:18:52 +0200 Subject: drm/radeon/kms: fix calculation of mipmapped 3D texture sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 3rd dimension should be minified too. Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 3ae51ad..e40dbdc 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2890,7 +2890,7 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, { struct radeon_bo *robj; unsigned long size; - unsigned u, i, w, h; + unsigned u, i, w, h, d; int ret; for (u = 0; u < track->num_texture; u++) { @@ -2922,20 +2922,25 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, h = h / (1 << i); if (track->textures[u].roundup_h) h = roundup_pow_of_two(h); + if (track->textures[u].tex_coord_type == 1) { + d = (1 << track->textures[u].txdepth) / (1 << i); + if (!d) + d = 1; + } else { + d = 1; + } if (track->textures[u].compress_format) { - size += r100_track_compress_size(track->textures[u].compress_format, w, h); + size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d; /* compressed textures are block based */ } else - size += w * h; + size += w * h * d; } size *= track->textures[u].cpp; switch (track->textures[u].tex_coord_type) { case 0: - break; case 1: - size *= (1 << track->textures[u].txdepth); break; case 2: if (track->separate_cube) { -- cgit v1.1 From 7fa90e873f520dad5ec58f47340996cda083e875 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 12 Apr 2010 08:49:00 +0200 Subject: ALSA: hda - Enhance fix-up table for Realtek codecs A few enhancement / fixes for fix-up table of some Realtek codecs: - Apply fix-ups only for the auto model - Apply additional verbs after normal init verbs - Add a debug print to show the fix-up application This is basically a preliminary work for the next fix for Sony VAIO. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8d60b1f..cff5771 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1390,22 +1390,31 @@ struct alc_fixup { static void alc_pick_fixup(struct hda_codec *codec, const struct snd_pci_quirk *quirk, - const struct alc_fixup *fix) + const struct alc_fixup *fix, + int pre_init) { const struct alc_pincfg *cfg; quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); if (!quirk) return; - fix += quirk->value; cfg = fix->pins; - if (cfg) { + if (pre_init && cfg) { +#ifdef CONFIG_SND_DEBUG_VERBOSE + snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", + codec->chip_name, quirk->name); +#endif for (; cfg->nid; cfg++) snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); } - if (fix->verbs) + if (!pre_init && fix->verbs) { +#ifdef CONFIG_SND_DEBUG_VERBOSE + snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", + codec->chip_name, quirk->name); +#endif add_verb(codec->spec, fix->verbs); + } } static int alc_read_coef_idx(struct hda_codec *codec, @@ -10439,7 +10448,8 @@ static int patch_alc882(struct hda_codec *codec) board_config = ALC882_AUTO; } - alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups); + if (board_config == ALC882_AUTO) + alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); if (board_config == ALC882_AUTO) { /* automatic parse from the BIOS config */ @@ -10512,6 +10522,9 @@ static int patch_alc882(struct hda_codec *codec) set_capture_mixer(codec); set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (board_config == ALC882_AUTO) + alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); + spec->vmaster_nid = 0x0c; codec->patch_ops = alc_patch_ops; @@ -15417,7 +15430,8 @@ static int patch_alc861(struct hda_codec *codec) board_config = ALC861_AUTO; } - alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups); + if (board_config == ALC861_AUTO) + alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); if (board_config == ALC861_AUTO) { /* automatic parse from the BIOS config */ @@ -15454,6 +15468,9 @@ static int patch_alc861(struct hda_codec *codec) spec->vmaster_nid = 0x03; + if (board_config == ALC861_AUTO) + alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); + codec->patch_ops = alc_patch_ops; if (board_config == ALC861_AUTO) { spec->init_hook = alc861_auto_init; @@ -16388,7 +16405,8 @@ static int patch_alc861vd(struct hda_codec *codec) board_config = ALC861VD_AUTO; } - alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups); + if (board_config == ALC861VD_AUTO) + alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); if (board_config == ALC861VD_AUTO) { /* automatic parse from the BIOS config */ @@ -16436,6 +16454,9 @@ static int patch_alc861vd(struct hda_codec *codec) spec->vmaster_nid = 0x02; + if (board_config == ALC861VD_AUTO) + alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); + codec->patch_ops = alc_patch_ops; if (board_config == ALC861VD_AUTO) -- cgit v1.1 From ff818c24c2af370153646d302d831b69b023816f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 12 Apr 2010 08:59:25 +0200 Subject: ALSA: hda - Add fix-up for Sony VAIO with ALC269 Sony VAIO models with ALC269 need to initialize the pin 0x19 to VREF ground or Hi-Z to make the headphone working. Other than that, model=auto works fine, so let's use model=auto with a specific fix-up table. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cff5771..4b35176 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14077,6 +14077,27 @@ static void alc269_auto_init(struct hda_codec *codec) alc_inithook(codec); } +enum { + ALC269_FIXUP_SONY_VAIO, +}; + +const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = { + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, + {} +}; + +static const struct alc_fixup alc269_fixups[] = { + [ALC269_FIXUP_SONY_VAIO] = { + .verbs = alc269_sony_vaio_fixup_verbs + }, +}; + +static struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), + {} +}; + + /* * configuration and preset */ @@ -14136,7 +14157,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { ALC269_DMIC), SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), - SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC), + SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), @@ -14290,6 +14311,9 @@ static int patch_alc269(struct hda_codec *codec) board_config = ALC269_AUTO; } + if (board_config == ALC269_AUTO) + alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); + if (board_config == ALC269_AUTO) { /* automatic parse from the BIOS config */ err = alc269_parse_auto_config(codec); @@ -14342,6 +14366,9 @@ static int patch_alc269(struct hda_codec *codec) set_capture_mixer(codec); set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); + if (board_config == ALC269_AUTO) + alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); + spec->vmaster_nid = 0x02; codec->patch_ops = alc_patch_ops; -- cgit v1.1 From 0df5dd4aae211edeeeb84f7f84f6d093406d7c22 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 11 Apr 2010 16:48:44 -0400 Subject: NFSv4: fix delegated locking Arnaud Giersch reports that NFSv4 locking is broken when we hold a delegation since commit 8e469ebd6dc32cbaf620e134d79f740bf0ebab79 (NFSv4: Don't allow posix locking against servers that don't support it). According to Arnaud, the lock succeeds the first time he opens the file (since we cannot do a delegated open) but then fails after we start using delegated opens. The following patch fixes it by ensuring that locking behaviour is governed by a per-filesystem capability flag that is initially set, but gets cleared if the server ever returns an OPEN without the NFS4_OPEN_RESULT_LOCKTYPE_POSIX flag being set. Reported-by: Arnaud Giersch Signed-off-by: Trond Myklebust Cc: stable@kernel.org --- fs/nfs/client.c | 3 ++- fs/nfs/nfs4proc.c | 4 +++- include/linux/nfs_fs_sb.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 2a3d352..a8766c4 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -1294,7 +1294,8 @@ static int nfs4_init_server(struct nfs_server *server, /* Initialise the client representation from the mount data */ server->flags = data->flags; - server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR; + server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR| + NFS_CAP_POSIX_LOCK; server->options = data->options; /* Get a client record */ diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index fe0cd9e..6380670 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1523,6 +1523,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) nfs_post_op_update_inode(dir, o_res->dir_attr); } else nfs_refresh_inode(dir, o_res->dir_attr); + if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0) + server->caps &= ~NFS_CAP_POSIX_LOCK; if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { status = _nfs4_proc_open_confirm(data); if (status != 0) @@ -1664,7 +1666,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in status = PTR_ERR(state); if (IS_ERR(state)) goto err_opendata_put; - if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0) + if (server->caps & NFS_CAP_POSIX_LOCK) set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); nfs4_opendata_put(opendata); nfs4_put_state_owner(sp); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 717a5e5..e82957a 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -176,6 +176,7 @@ struct nfs_server { #define NFS_CAP_ATIME (1U << 11) #define NFS_CAP_CTIME (1U << 12) #define NFS_CAP_MTIME (1U << 13) +#define NFS_CAP_POSIX_LOCK (1U << 14) /* maximum number of slots to use */ -- cgit v1.1 From c948aca4f49d94b08c425f65acdaca1d679d6fa7 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 8 Mar 2010 19:38:13 +0100 Subject: MIPS: Fix build breakage if CONFIG_DEBUG_FS is enabled. Caused by 38b7827fcdd660f591d645bd3ae6644456a4773c - no, cpu_local_* was not unused. Signed-off-by: Ralf Baechle Cc: Christoph Lameter Acked-by: David Daney --- arch/mips/include/asm/fpu_emulator.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index aecada6..3b40927 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h @@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats { DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); #define MIPS_FPU_EMU_INC_STATS(M) \ - cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M)) +do { \ + preempt_disable(); \ + __local_inc(&__get_cpu_var(fpuemustats).M); \ + preempt_enable(); \ +} while (0) #else #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0) -- cgit v1.1 From 1874a0886076fbb26665f93a8999c05e389bae22 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 9 Mar 2010 20:16:15 +0100 Subject: MIPS: Cavium: Remove unused watchdog code. Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/smp.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 51e9802..6d99b9d 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu) uint32_t avail_coremask; struct cvmx_bootmem_named_block_desc *block_desc; -#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG - /* Disable the watchdog */ - cvmx_ciu_wdogx_t ciu_wdog; - ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu)); - ciu_wdog.s.mode = 0; - cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64); -#endif - while (per_cpu(cpu_state, cpu) != CPU_DEAD) cpu_relax(); -- cgit v1.1 From 1ef2887030dbeb42282a99f8a8e3d7ad07ef70ee Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 3 Mar 2010 11:07:07 -0800 Subject: MIPS: Octeon: Remove vestiges of CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB The config option CAVIUM_RESERVE32_USE_WIRED_TLB is not supported. Remove the dead code controlled by it. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1028/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/setup.c | 67 +---------------------------------------- 1 file changed, 1 insertion(+), 66 deletions(-) diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index b321d3b..26a9699 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -186,54 +186,6 @@ void octeon_check_cpu_bist(void) write_octeon_c0_dcacheerr(0); } -#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB -/** - * Called on every core to setup the wired tlb entry needed - * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set. - * - */ -static void octeon_hal_setup_per_cpu_reserved32(void *unused) -{ - /* - * The config has selected to wire the reserve32 memory for all - * userspace applications. We need to put a wired TLB entry in for each - * 512MB of reserve32 memory. We only handle double 256MB pages here, - * so reserve32 must be multiple of 512MB. - */ - uint32_t size = CONFIG_CAVIUM_RESERVE32; - uint32_t entrylo0 = - 0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6); - uint32_t entrylo1 = entrylo0 + (256 << 14); - uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20)); - while (size >= 512) { -#if 0 - pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n", - smp_processor_id(), entryhi); -#endif - add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M); - entrylo0 += 512 << 14; - entrylo1 += 512 << 14; - entryhi += 512 << 20; - size -= 512; - } -} -#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */ - -/** - * Called to release the named block which was used to made sure - * that nobody used the memory for something else during - * init. Now we'll free it so userspace apps can use this - * memory region with bootmem_alloc. - * - * This function is called only once from prom_free_prom_memory(). - */ -void octeon_hal_setup_reserved32(void) -{ -#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB - on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1); -#endif -} - /** * Reboot Octeon * @@ -502,25 +454,13 @@ void __init prom_init(void) * memory when it is getting memory from the * bootloader. Later, after the memory allocations are * complete, the reserve32 will be freed. - */ -#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB - if (CONFIG_CAVIUM_RESERVE32 & 0x1ff) - pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. " - "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB " - "is set\n"); - else - addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20, - 0, 0, 512 << 20, - "CAVIUM_RESERVE32", 0); -#else - /* + * * Allocate memory for RESERVED32 aligned on 2MB boundary. This * is in case we later use hugetlb entries with it. */ addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20, 0, 0, 2 << 20, "CAVIUM_RESERVE32", 0); -#endif if (addr < 0) pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n"); else @@ -817,9 +757,4 @@ void prom_free_prom_memory(void) panic("Unable to request_irq(OCTEON_IRQ_RML)\n"); } #endif - - /* This call is here so that it is performed after any TLB - initializations. It needs to be after these in case the - CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */ - octeon_hal_setup_reserved32(); } -- cgit v1.1 From b1cea3bab575af386618baba0db3c5fae7ce521f Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 3 Mar 2010 11:07:43 -0800 Subject: MIPS: Octeon: Remove #if 0 code. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1029/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/setup.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 26a9699..e07c540 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -246,18 +246,6 @@ static void octeon_halt(void) octeon_kill_core(NULL); } -#if 0 -/** - * Platform time init specifics. - * Returns - */ -void __init plat_time_init(void) -{ - /* Nothing special here, but we are required to have one */ -} - -#endif - /** * Handle all the error condition interrupts that might occur. * -- cgit v1.1 From abe5b417fb4a52e9510fdb5a16e722e91bf89e92 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 10 Mar 2010 16:16:04 +0100 Subject: MIPS: delay: Fix use of current_cpu_data in preemptable code. This may lead to warnings like: BUG: using smp_processor_id() in preemptible [00000000] code: reboot/1989 caller is __udelay+0x14/0x70 Call Trace: [] dump_stack+0x8/0x34 [] debug_smp_processor_id+0xf4/0x110 [] __udelay+0x14/0x70 [] md_notify_reboot+0x12c/0x148 [] notifier_call_chain+0x64/0xc8 [] __blocking_notifier_call_chain+0x64/0xc0 [] kernel_restart_prepare+0x1c/0x38 [] kernel_restart+0x14/0x50 [] SyS_reboot+0x10c/0x1f0 [] handle_sysn32+0x44/0x84 Signed-off-by: Ralf Baechle --- arch/mips/lib/delay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 6b3b1de9..5995969 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c @@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay); void __udelay(unsigned long us) { - unsigned int lpj = current_cpu_data.udelay_val; + unsigned int lpj = raw_current_cpu_data.udelay_val; __delay((us * 0x000010c7ull * HZ * lpj) >> 32); } @@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay); void __ndelay(unsigned long ns) { - unsigned int lpj = current_cpu_data.udelay_val; + unsigned int lpj = raw_current_cpu_data.udelay_val; __delay((ns * 0x00000005ull * HZ * lpj) >> 32); } -- cgit v1.1 From 7a7ac952d5217b2f568e5ef91ac39b572e166f24 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 10 Mar 2010 00:27:28 +0800 Subject: MIPS: Trace: Don't trace irqsoff for the idle process Like x86 did in arch/x86/kernel/{process_32.c,process_64.c}, also don't trace irqsoff for idle. If there's no useful work to be done, we don't care about the irqsoff duration. If we trace the idle process, the max duration of irqsoff will be the idle time and make the irqsoff tracer useless. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Patchwork: http://patchwork.linux-mips.org/patch/1044/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/process.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 463b71b..9996094 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -63,8 +63,13 @@ void __noreturn cpu_idle(void) smtc_idle_loop_hook(); #endif - if (cpu_wait) + + if (cpu_wait) { + /* Don't trace irqs off for idle */ + stop_critical_timings(); (*cpu_wait)(); + start_critical_timings(); + } } #ifdef CONFIG_HOTPLUG_CPU if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) && -- cgit v1.1 From 7ea4a6891b68fe60bf4eee41a7ef38d524b0aebd Mon Sep 17 00:00:00 2001 From: Yang Shi Date: Wed, 3 Mar 2010 16:43:20 +0800 Subject: MIPS: Octeon: Remove redundant declaration of octeon_reserve32_memory octeon_reserve32_memory is defined In Octeon's setup.c, so remove the redundant extern declaration of this variable. Signed-off-by: Yang Shi To: f.fainelli@gmail.com Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1022/ Acked-by: David Daney Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/setup.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index e07c540..9a06fa9 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops; extern void pci_console_init(const char *arg); #endif -#ifdef CONFIG_CAVIUM_RESERVE32 -extern uint64_t octeon_reserve32_memory; -#endif static unsigned long long MAX_MEMORY = 512ull << 20; struct octeon_boot_descriptor *octeon_boot_desc_ptr; -- cgit v1.1 From d5d3102b9adec0a34eb5899324b62a4a3d34183e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 11 Mar 2010 08:48:14 +0100 Subject: MIPS: Fix elfcore.c build warning kernel/elfcore.c includes which includes the . In , struct pt_regs is declared inside the parameter list of the elf_dump_regs function which causes a kernel build warning. Fixed by adding a forward declaration of struct pt_regs. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/elf.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index e53d7be..1184f6e 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -310,6 +310,7 @@ do { \ #endif /* CONFIG_64BIT */ +struct pt_regs; struct task_struct; extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs); -- cgit v1.1 From 52553664033078102f5f430c861ccd0863b1b708 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 27 Feb 2010 12:02:51 -0500 Subject: MIPS: Initialize an atomic_t properly with ATOMIC_INIT(0). Signed-off-by: Robert P. J. Day To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1008/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/smtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 25e825a..a95dea5 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -182,7 +182,7 @@ static int vpemask[2][8] = { {0, 0, 0, 0, 0, 0, 0, 1} }; int tcnoprog[NR_CPUS]; -static atomic_t idle_hook_initialized = {0}; +static atomic_t idle_hook_initialized = ATOMIC_INIT(0); static int clock_hang_reported[NR_CPUS]; #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */ -- cgit v1.1 From b846c10da5d6a5c159ab4dea92c1080d5add9fb1 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Thu, 11 Mar 2010 11:30:50 +0800 Subject: MIPS: Lemote 2F: Ensure atomic execution of _rdmsr and _wrmsr On Lemote 2F CS5536 MSRs are accessed through a index / data register pair. The access sequence must be protected by a spinlock to be atomic. Without this rebooting in fs2f_reboot() may fail. Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: David Daney Patchwork: http://patchwork.linux-mips.org/patch/1058/ Signed-off-by: Ralf Baechle --- arch/mips/pci/ops-loongson2.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/mips/pci/ops-loongson2.c b/arch/mips/pci/ops-loongson2.c index 2bb4057..d657ee0 100644 --- a/arch/mips/pci/ops-loongson2.c +++ b/arch/mips/pci/ops-loongson2.c @@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = { }; #ifdef CONFIG_CS5536 +DEFINE_RAW_SPINLOCK(msr_lock); + void _rdmsr(u32 msr, u32 *hi, u32 *lo) { struct pci_bus bus = { .number = PCI_BUS_CS5536 }; u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); + unsigned long flags; + + raw_spin_lock_irqsave(&msr_lock, flags); loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); + raw_spin_unlock_irqrestore(&msr_lock, flags); } EXPORT_SYMBOL(_rdmsr); @@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo) .number = PCI_BUS_CS5536 }; u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); + unsigned long flags; + + raw_spin_lock_irqsave(&msr_lock, flags); loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); + raw_spin_unlock_irqrestore(&msr_lock, flags); } EXPORT_SYMBOL(_wrmsr); #endif -- cgit v1.1 From 582b65e4d3f9664f87661359af99def304bc68bb Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 10 Mar 2010 00:53:21 +0800 Subject: MIPS: Loongson: Add module info to the loongson2_clock driver This patch fixes a kernel warning when loading the the loongson2_clock driver: "Feb 25 23:42:27 localhost kernel: [ 4.965000] loongson2_clock: module license 'unspecified' taints kernel." Signed-off-by: Wu Zhangjin Reported-by: Liu Shiwei Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1045/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpufreq/loongson2_clock.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/kernel/cpufreq/loongson2_clock.c b/arch/mips/kernel/cpufreq/loongson2_clock.c index d7ca256..cefc6e2 100644 --- a/arch/mips/kernel/cpufreq/loongson2_clock.c +++ b/arch/mips/kernel/cpufreq/loongson2_clock.c @@ -164,3 +164,7 @@ void loongson2_cpu_wait(void) spin_unlock_irqrestore(&loongson2_wait_lock, flags); } EXPORT_SYMBOL_GPL(loongson2_cpu_wait); + +MODULE_AUTHOR("Yanhua "); +MODULE_DESCRIPTION("cpufreq driver for Loongson 2F"); +MODULE_LICENSE("GPL"); -- cgit v1.1 From 1e3fb3778be3c0a56626eba4a84f7d2fa991aa93 Mon Sep 17 00:00:00 2001 From: Alexander Clouter Date: Fri, 12 Mar 2010 19:39:48 +0000 Subject: MIPS: AR7: Fix phat finger of reset bit in vlynq_high_data Seems in my whitespace cleanup 0f2536082d01448daeced8d9e82c3ba1751fefa3 (lmo) rsp. 8c2961da46abd85a71d20f2b169bf80618e (kernel.org) caused AR7 to no longer get as far as init. Fixed my phat fingering. Signed-off-by: Alexander Clouter To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1064/ Signed-off-by: Ralf Baechle --- arch/mips/ar7/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 246df7a..0bd5f67 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = { .on = vlynq_on, .off = vlynq_off, }, - .reset_bit = 26, + .reset_bit = 16, .gpio_bit = 19, }; -- cgit v1.1 From 727c0075c80005e2012be113a91e5976abec4f9d Mon Sep 17 00:00:00 2001 From: Alexander Clouter Date: Sat, 13 Mar 2010 00:09:15 +0000 Subject: MIPS: AR7: Fix phat finger of cpmac fixed_phy_add Seems I trimmed one too many lines in 29ca2d81bd2a62fa86bc9a72ddadcf03d7daf795 (lmo) rsp 7084338eb8eb0cc021ba86c340157bad397f3f0b (kernel.org) which led to no functioning Ethernet on my WAG54Gv2. This patch restores the AWOL line. Signed-off-by: Alexander Clouter To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1065/ Signed-off-by: Ralf Baechle --- arch/mips/ar7/platform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 0bd5f67..2fafc78 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -600,6 +600,7 @@ static int __init ar7_register_devices(void) } if (ar7_has_high_cpmac()) { + res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status); if (!res) { cpmac_get_mac(1, cpmac_high_data.dev_addr); -- cgit v1.1 From 86f7d75eb7c43a54a7b37a2287787004f4310de6 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 10 Mar 2010 09:51:09 +0100 Subject: MIPS: make CAC_ADDR and UNCAC_ADDR account for PHYS_OFFSET On AR7, we already redefine PHYS_OFFSET to match the system specifities, it is however not sufficient when unsing dma_{map,unmap}_single, specifically in the ethernet driver, we must also adjust CAC_ADDR and UNCAC_ADDR for DMA to work correctly. This patch fixes the following issue, seen in cpmac_open: ops[#1]: Cpu 0 $ 0 : 00000000 10008400 a0f5b120 00000000 $ 4 : 94c59000 94270f64 00000020 00000010 $ 8 : 00000010 94103ce0 0000000a 94c03400 $12 : ffffffff 94c03408 94c03410 00000001 $16 : a0f5ba20 00000041 94c592c0 94c59200 $20 : 94c59000 000005ee 00002000 9438c8f0 $24 : 00000010 00000000 $28 : 94fac000 94fadd58 94390000 942724a8 Hi : 00000000 Lo : 00000001 epc : 94272518 cpmac_open+0x208/0x3f8 Not tainted ra : 942724a8 cpmac_open+0x198/0x3f8 Status: 10008403 KERNEL EXL IE Cause : 3080000c BadVA : 00000000 PrId : 00018448 (MIPS 4KEc) Modules linked in: Process ifconfig (pid: 278, threadinfo=94fac000, task=94e79590, tls=00000000) Stack : 7f8da120 2ab05cb0 94c59000 943356f0 00000000 943d0000 94c59000 943356f0 94c59030 943d0000 943c27c0 94fade10 00000000 94fade20 94c59000 9428e5a4 00000000 94c59000 00000041 94289768 94c59000 00000041 00001002 00001043 00000000 9428d810 00000000 94fade10 7f8da4e8 9428e6b8 00000000 7f8da4a8 7f8da4e8 00008914 00000000 942f7f2c 00000000 00000008 00408000 00008913 ... Call Trace: [<94272518>] cpmac_open+0x208/0x3f8 [<9428e5a4>] dev_open+0x164/0x264 [<9428d810>] dev_change_flags+0xd0/0x1bc [<942f7f2c>] devinet_ioctl+0x2d8/0x908 [<942771f8>] sock_ioctl+0x29c/0x2fc [<941a0fb4>] vfs_ioctl+0x2c/0x7c [<941a16ec>] do_vfs_ioctl+0x5dc/0x630 [<941a1790>] sys_ioctl+0x50/0x88 [<94101e10>] stack_done+0x20/0x3c Signed-off-by: peter fuerst Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1050/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/page.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index ac32572..a16beaf 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE) -#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET) +#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \ + PHYS_OFFSET) +#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \ + PHYS_OFFSET) #include #include -- cgit v1.1 From 847253b9483f713b3797877034e0940fd45ce375 Mon Sep 17 00:00:00 2001 From: Andreas Ferber Date: Tue, 16 Mar 2010 12:35:51 +0100 Subject: MIPS: Fix SSB PCIcore IO resource management The SSB PCIcore code reused the IO resource fixup code from the original 2.4.x Broadcom patch for BCM47xx based devices, which was a quick hack for doing PCI IO resource configuration back then (the boot loader doesn't configure PCI devices on this platform). However, this code is no longer necessary since the kernel now can do PCI resource management fine all by itself, so remove the old code. When removing the code, it becomes obvious that the mem_offset setting in the PCIcore driver was wrong, however this was masked by the fixup code before, except in a few cases involving yenta_socket. For BCM47xx, the correct offset is 0, and since this is the only device using PCIcore in host mode, the offset can simply be removed unconditionally. Signed-off-by: Andreas Ferber Signed-off-by: Michael Buesch Cc: Markus Wigge Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1070/ Signed-off-by: Ralf Baechle --- drivers/ssb/driver_pcicore.c | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index f1dcd79..0e8d352 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore_controller = { .pci_ops = &ssb_pcicore_pciops, .io_resource = &ssb_pcicore_io_resource, .mem_resource = &ssb_pcicore_mem_resource, - .mem_offset = 0x24000000, }; -static u32 ssb_pcicore_pcibus_iobase = 0x100; -static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA; - /* This function is called when doing a pci_enable_device(). * We must first check if the device is a device on the PCI-core bridge. */ int ssb_pcicore_plat_dev_init(struct pci_dev *d) { - struct resource *res; - int pos, size; - u32 *base; - if (d->bus->ops != &ssb_pcicore_pciops) { /* This is not a device on the PCI-core bridge. */ return -ENODEV; @@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d) ssb_printk(KERN_INFO "PCI: Fixing up device %s\n", pci_name(d)); - /* Fix up resource bases */ - for (pos = 0; pos < 6; pos++) { - res = &d->resource[pos]; - if (res->flags & IORESOURCE_IO) - base = &ssb_pcicore_pcibus_iobase; - else - base = &ssb_pcicore_pcibus_membase; - res->flags |= IORESOURCE_PCI_FIXED; - if (res->end) { - size = res->end - res->start + 1; - if (*base & (size - 1)) - *base = (*base + size) & ~(size - 1); - res->start = *base; - res->end = res->start + size - 1; - *base += size; - pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start); - } - /* Fix up PCI bridge BAR0 only */ - if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0) - break; - } /* Fix up interrupt lines */ d->irq = ssb_mips_irq(extpci_core->dev) + 2; pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); -- cgit v1.1 From 58b9e2239fa63c7c470acb4a77e9da17e6a6fa4f Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 18 Feb 2010 16:13:03 -0800 Subject: MIPS: Add SYSCALL to uasm. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/976/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/uasm.h | 1 + arch/mips/mm/uasm.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index b99bd07..32fe2ec 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h @@ -102,6 +102,7 @@ Ip_0(_tlbwr); Ip_u3u1u2(_xor); Ip_u2u1u3(_xori); Ip_u2u1msbu3(_dins); +Ip_u1(_syscall); /* Handle labels. */ struct uasm_label { diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 1581e98..d22d7bc 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -31,7 +31,8 @@ enum fields { BIMM = 0x040, JIMM = 0x080, FUNC = 0x100, - SET = 0x200 + SET = 0x200, + SCIMM = 0x400 }; #define OP_MASK 0x3f @@ -52,6 +53,8 @@ enum fields { #define FUNC_SH 0 #define SET_MASK 0x7 #define SET_SH 0 +#define SCIMM_MASK 0xfffff +#define SCIMM_SH 6 enum opcode { insn_invalid, @@ -64,7 +67,7 @@ enum opcode { insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, - insn_dins + insn_dins, insn_syscall }; struct insn { @@ -136,6 +139,7 @@ static struct insn insn_table[] __cpuinitdata = { { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, + { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, { insn_invalid, 0, 0 } }; @@ -208,6 +212,14 @@ static inline __cpuinit u32 build_jimm(u32 arg) return (arg >> 2) & JIMM_MASK; } +static inline __cpuinit u32 build_scimm(u32 arg) +{ + if (arg & ~SCIMM_MASK) + printk(KERN_WARNING "Micro-assembler field overflow\n"); + + return (arg & SCIMM_MASK) << SCIMM_SH; +} + static inline __cpuinit u32 build_func(u32 arg) { if (arg & ~FUNC_MASK) @@ -266,6 +278,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...) op |= build_func(va_arg(ap, u32)); if (ip->fields & SET) op |= build_set(va_arg(ap, u32)); + if (ip->fields & SCIMM) + op |= build_scimm(va_arg(ap, u32)); va_end(ap); **buf = op; @@ -391,6 +405,7 @@ I_0(_tlbwr) I_u3u1u2(_xor) I_u2u1u3(_xori) I_u2u1msbu3(_dins); +I_u1(_syscall); /* Handle labels. */ void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) -- cgit v1.1 From c52d0d30aef84aa8893b34e5254716c8ab5c4472 Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 18 Feb 2010 16:13:04 -0800 Subject: MIPS: Preliminary VDSO This is a preliminary patch to add a vdso to all user processes. Still missing are ELF headers and .eh_frame information. But it is enough to allow us to move signal trampolines off of the stack. Note that emulation of branch delay slots in the FPU emulator still requires the stack. We allocate a single page (the vdso) and write all possible signal trampolines into it. The stack is moved down by one page and the vdso is mapped into this space. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/975/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/elf.h | 4 ++ arch/mips/include/asm/mmu.h | 5 +- arch/mips/include/asm/mmu_context.h | 2 +- arch/mips/include/asm/processor.h | 11 +++- arch/mips/include/asm/vdso.h | 29 ++++++++++ arch/mips/kernel/Makefile | 2 +- arch/mips/kernel/syscall.c | 6 +- arch/mips/kernel/vdso.c | 112 ++++++++++++++++++++++++++++++++++++ 8 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 arch/mips/include/asm/vdso.h create mode 100644 arch/mips/kernel/vdso.c diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 1184f6e..ea77a42 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -368,4 +368,8 @@ extern const char *__elf_platform; #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) #endif +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 +struct linux_binprm; +extern int arch_setup_additional_pages(struct linux_binprm *bprm, + int uses_interp); #endif /* _ASM_ELF_H */ diff --git a/arch/mips/include/asm/mmu.h b/arch/mips/include/asm/mmu.h index 4063edd..c436138 100644 --- a/arch/mips/include/asm/mmu.h +++ b/arch/mips/include/asm/mmu.h @@ -1,6 +1,9 @@ #ifndef __ASM_MMU_H #define __ASM_MMU_H -typedef unsigned long mm_context_t[NR_CPUS]; +typedef struct { + unsigned long asid[NR_CPUS]; + void *vdso; +} mm_context_t; #endif /* __ASM_MMU_H */ diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 145bb81..d959273 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask; #endif -#define cpu_context(cpu, mm) ((mm)->context[cpu]) +#define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) #define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) #define asid_cache(cpu) (cpu_data[cpu].asid_cache) diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 087a888..ab38791 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -33,13 +33,19 @@ extern void (*cpu_wait)(void); extern unsigned int vced_count, vcei_count; +/* + * A special page (the vdso) is mapped into all processes at the very + * top of the virtual memory space. + */ +#define SPECIAL_PAGES_SIZE PAGE_SIZE + #ifdef CONFIG_32BIT /* * User space process size: 2GB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. */ #define TASK_SIZE 0x7fff8000UL -#define STACK_TOP TASK_SIZE +#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE) /* * This decides where the kernel will search for a free chunk of vm @@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count; #define TASK_SIZE32 0x7fff8000UL #define TASK_SIZE 0x10000000000UL #define STACK_TOP \ - (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE) + (((test_thread_flag(TIF_32BIT_ADDR) ? \ + TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE) /* * This decides where the kernel will search for a free chunk of vm diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h new file mode 100644 index 0000000..cca56aa --- /dev/null +++ b/arch/mips/include/asm/vdso.h @@ -0,0 +1,29 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2009 Cavium Networks + */ + +#ifndef __ASM_VDSO_H +#define __ASM_VDSO_H + +#include + + +#ifdef CONFIG_32BIT +struct mips_vdso { + u32 signal_trampoline[2]; + u32 rt_signal_trampoline[2]; +}; +#else /* !CONFIG_32BIT */ +struct mips_vdso { + u32 o32_signal_trampoline[2]; + u32 o32_rt_signal_trampoline[2]; + u32 rt_signal_trampoline[2]; + u32 n32_rt_signal_trampoline[2]; +}; +#endif /* CONFIG_32BIT */ + +#endif /* __ASM_VDSO_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index ef20957..7a6ac50 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o setup.o signal.o syscall.o \ - time.o topology.o traps.o unaligned.o watch.o + time.o topology.o traps.o unaligned.o watch.o vdso.o ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_ftrace.o = -pg diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 9587abc..dd81b0f 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, int do_color_align; unsigned long task_size; - task_size = STACK_TOP; +#ifdef CONFIG_32BIT + task_size = TASK_SIZE; +#else /* Must be CONFIG_64BIT*/ + task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE; +#endif if (len > task_size) return -ENOMEM; diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c new file mode 100644 index 0000000..b773c11 --- /dev/null +++ b/arch/mips/kernel/vdso.c @@ -0,0 +1,112 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2009, 2010 Cavium Networks, Inc. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * Including would give use the 64-bit syscall numbers ... + */ +#define __NR_O32_sigreturn 4119 +#define __NR_O32_rt_sigreturn 4193 +#define __NR_N32_rt_sigreturn 6211 + +static struct page *vdso_page; + +static void __init install_trampoline(u32 *tramp, unsigned int sigreturn) +{ + uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */ + uasm_i_syscall(&tramp, 0); +} + +static int __init init_vdso(void) +{ + struct mips_vdso *vdso; + + vdso_page = alloc_page(GFP_KERNEL); + if (!vdso_page) + panic("Cannot allocate vdso"); + + vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL); + if (!vdso) + panic("Cannot map vdso"); + clear_page(vdso); + + install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn); +#ifdef CONFIG_32BIT + install_trampoline(vdso->signal_trampoline, __NR_sigreturn); +#else + install_trampoline(vdso->n32_rt_signal_trampoline, + __NR_N32_rt_sigreturn); + install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn); + install_trampoline(vdso->o32_rt_signal_trampoline, + __NR_O32_rt_sigreturn); +#endif + + vunmap(vdso); + + pr_notice("init_vdso successfull\n"); + + return 0; +} +device_initcall(init_vdso); + +static unsigned long vdso_addr(unsigned long start) +{ + return STACK_TOP; +} + +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +{ + int ret; + unsigned long addr; + struct mm_struct *mm = current->mm; + + down_write(&mm->mmap_sem); + + addr = vdso_addr(mm->start_stack); + + addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; + } + + ret = install_special_mapping(mm, addr, PAGE_SIZE, + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| + VM_ALWAYSDUMP, + &vdso_page); + + if (ret) + goto up_fail; + + mm->context.vdso = (void *)addr; + +up_fail: + up_write(&mm->mmap_sem); + return ret; +} + +const char *arch_vma_name(struct vm_area_struct *vma) +{ + if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) + return "[vdso]"; + return NULL; +} -- cgit v1.1 From d814c28ceca8f659c0012eaec8e21eee43710716 Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 18 Feb 2010 16:13:05 -0800 Subject: MIPS: Move signal trampolines off of the stack. This is a follow on to the vdso patch. Since all processes now have signal trampolines permanently mapped, we can use those instead of putting the trampoline on the stack and invalidating the corresponding icache across all CPUs. We also get rid of a bunch of ICACHE_REFILLS_WORKAROUND_WAR code. [Ralf: GDB 7.1 which has the necessary modifications to allow backtracing over signal frames will supposedly be released tomorrow. The old signal frame format obsoleted by this patch exists in two variations, for sane processors and for those requiring ICACHE_REFILLS_WORKAROUND_WAR. So there was never a GDB which did support backtracing over signal frames on all MIPS systems. This convinved me this series should be applied and pushed upstream as soon as possible.] Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/974/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/abi.h | 6 ++- arch/mips/kernel/signal-common.h | 5 --- arch/mips/kernel/signal.c | 86 +++++++++------------------------------- arch/mips/kernel/signal32.c | 55 +++++++------------------ arch/mips/kernel/signal_n32.c | 26 +++--------- 5 files changed, 43 insertions(+), 135 deletions(-) diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h index 1dd74fb..9252d9b 100644 --- a/arch/mips/include/asm/abi.h +++ b/arch/mips/include/asm/abi.h @@ -13,12 +13,14 @@ #include struct mips_abi { - int (* const setup_frame)(struct k_sigaction * ka, + int (* const setup_frame)(void *sig_return, struct k_sigaction *ka, struct pt_regs *regs, int signr, sigset_t *set); - int (* const setup_rt_frame)(struct k_sigaction * ka, + const unsigned long signal_return_offset; + int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); + const unsigned long rt_signal_return_offset; const unsigned long restart; }; diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 6c8e8c4..10263b4 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h @@ -26,11 +26,6 @@ */ extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size); -/* - * install trampoline code to get back from the sig handler - */ -extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall); - /* Check and clear pending FPU exceptions in saved CSR */ extern int fpcsr_pending(unsigned int __user *fpcsr); diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index d0c68b5..2099d5a 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "signal-common.h" @@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc); extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc); extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc); -/* - * Horribly complicated - with the bloody RM9000 workarounds enabled - * the signal trampolines is moving to the end of the structure so we can - * increase the alignment without breaking software compatibility. - */ -#if ICACHE_REFILLS_WORKAROUND_WAR == 0 - struct sigframe { u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_code[2]; /* signal trampoline */ + u32 sf_pad[2]; /* Was: signal trampoline */ struct sigcontext sf_sc; sigset_t sf_mask; }; struct rt_sigframe { u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_code[2]; /* signal trampoline */ + u32 rs_pad[2]; /* Was: signal trampoline */ struct siginfo rs_info; struct ucontext rs_uc; }; -#else - -struct sigframe { - u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_pad[2]; - struct sigcontext sf_sc; /* hw context */ - sigset_t sf_mask; - u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ -}; - -struct rt_sigframe { - u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_pad[2]; - struct siginfo rs_info; - struct ucontext rs_uc; - u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ -}; - -#endif - /* * Helper routines */ @@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK)); } -int install_sigtramp(unsigned int __user *tramp, unsigned int syscall) -{ - int err; - - /* - * Set up the return code ... - * - * li v0, __NR__foo_sigreturn - * syscall - */ - - err = __put_user(0x24020000 + syscall, tramp + 0); - err |= __put_user(0x0000000c , tramp + 1); - if (ICACHE_REFILLS_WORKAROUND_WAR) { - err |= __put_user(0, tramp + 2); - err |= __put_user(0, tramp + 3); - err |= __put_user(0, tramp + 4); - err |= __put_user(0, tramp + 5); - err |= __put_user(0, tramp + 6); - err |= __put_user(0, tramp + 7); - } - flush_cache_sigtramp((unsigned long) tramp); - - return err; -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ @@ -484,8 +432,8 @@ badframe: } #ifdef CONFIG_TRAD_SIGNALS -static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set) +static int setup_frame(void *sig_return, struct k_sigaction *ka, + struct pt_regs *regs, int signr, sigset_t *set) { struct sigframe __user *frame; int err = 0; @@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - err |= install_sigtramp(frame->sf_code, __NR_sigreturn); - err |= setup_sigcontext(regs, &frame->sf_sc); err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); if (err) @@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, regs->regs[ 5] = 0; regs->regs[ 6] = (unsigned long) &frame->sf_sc; regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->sf_code; + regs->regs[31] = (unsigned long) sig_return; regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", @@ -529,8 +475,9 @@ give_sigsegv: } #endif -static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set, siginfo_t *info) +static int setup_rt_frame(void *sig_return, struct k_sigaction *ka, + struct pt_regs *regs, int signr, sigset_t *set, + siginfo_t *info) { struct rt_sigframe __user *frame; int err = 0; @@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn); - /* Create siginfo. */ err |= copy_siginfo_to_user(&frame->rs_info, info); @@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, regs->regs[ 5] = (unsigned long) &frame->rs_info; regs->regs[ 6] = (unsigned long) &frame->rs_uc; regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->rs_code; + regs->regs[31] = (unsigned long) sig_return; regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", @@ -590,8 +535,11 @@ give_sigsegv: struct mips_abi mips_abi = { #ifdef CONFIG_TRAD_SIGNALS .setup_frame = setup_frame, + .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline), #endif .setup_rt_frame = setup_rt_frame, + .rt_signal_return_offset = + offsetof(struct mips_vdso, rt_signal_trampoline), .restart = __NR_restart_syscall }; @@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) { int ret; + struct mips_abi *abi = current->thread.abi; + void *vdso = current->mm->context.vdso; switch(regs->regs[0]) { case ERESTART_RESTARTBLOCK: @@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info, regs->regs[0] = 0; /* Don't deal with this again. */ if (sig_uses_siginfo(ka)) - ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info); + ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, + ka, regs, sig, oldset, info); else - ret = current->thread.abi->setup_frame(ka, regs, sig, oldset); + ret = abi->setup_frame(vdso + abi->signal_return_offset, + ka, regs, sig, oldset); spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 03abaf0..a0ed0e0 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "signal-common.h" @@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user /* * Including would give use the 64-bit syscall numbers ... */ -#define __NR_O32_sigreturn 4119 -#define __NR_O32_rt_sigreturn 4193 #define __NR_O32_restart_syscall 4253 /* 32-bit compatibility types */ @@ -77,47 +76,20 @@ struct ucontext32 { compat_sigset_t uc_sigmask; /* mask last for extensibility */ }; -/* - * Horribly complicated - with the bloody RM9000 workarounds enabled - * the signal trampolines is moving to the end of the structure so we can - * increase the alignment without breaking software compatibility. - */ -#if ICACHE_REFILLS_WORKAROUND_WAR == 0 - struct sigframe32 { u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_code[2]; /* signal trampoline */ + u32 sf_pad[2]; /* Was: signal trampoline */ struct sigcontext32 sf_sc; compat_sigset_t sf_mask; }; struct rt_sigframe32 { u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_code[2]; /* signal trampoline */ + u32 rs_pad[2]; /* Was: signal trampoline */ compat_siginfo_t rs_info; struct ucontext32 rs_uc; }; -#else /* ICACHE_REFILLS_WORKAROUND_WAR */ - -struct sigframe32 { - u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_pad[2]; - struct sigcontext32 sf_sc; /* hw context */ - compat_sigset_t sf_mask; - u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ -}; - -struct rt_sigframe32 { - u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_pad[2]; - compat_siginfo_t rs_info; - struct ucontext32 rs_uc; - u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */ -}; - -#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ - /* * sigcontext handlers */ @@ -598,8 +570,8 @@ badframe: force_sig(SIGSEGV, current); } -static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set) +static int setup_frame_32(void *sig_return, struct k_sigaction *ka, + struct pt_regs *regs, int signr, sigset_t *set) { struct sigframe32 __user *frame; int err = 0; @@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn); - err |= setup_sigcontext32(regs, &frame->sf_sc); err |= __copy_conv_sigset_to_user(&frame->sf_mask, set); @@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, regs->regs[ 5] = 0; regs->regs[ 6] = (unsigned long) &frame->sf_sc; regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->sf_code; + regs->regs[31] = (unsigned long) sig_return; regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", @@ -644,8 +614,9 @@ give_sigsegv: return -EFAULT; } -static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set, siginfo_t *info) +static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka, + struct pt_regs *regs, int signr, sigset_t *set, + siginfo_t *info) { struct rt_sigframe32 __user *frame; int err = 0; @@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn); - /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */ err |= copy_siginfo_to_user32(&frame->rs_info, info); @@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, regs->regs[ 5] = (unsigned long) &frame->rs_info; regs->regs[ 6] = (unsigned long) &frame->rs_uc; regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->rs_code; + regs->regs[31] = (unsigned long) sig_return; regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", @@ -709,7 +678,11 @@ give_sigsegv: */ struct mips_abi mips_abi_32 = { .setup_frame = setup_frame_32, + .signal_return_offset = + offsetof(struct mips_vdso, o32_signal_trampoline), .setup_rt_frame = setup_rt_frame_32, + .rt_signal_return_offset = + offsetof(struct mips_vdso, o32_rt_signal_trampoline), .restart = __NR_O32_restart_syscall }; diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index bb277e8..2c5df81 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -39,13 +39,13 @@ #include #include #include +#include #include "signal-common.h" /* * Including would give use the 64-bit syscall numbers ... */ -#define __NR_N32_rt_sigreturn 6211 #define __NR_N32_restart_syscall 6214 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); @@ -67,27 +67,13 @@ struct ucontextn32 { compat_sigset_t uc_sigmask; /* mask last for extensibility */ }; -#if ICACHE_REFILLS_WORKAROUND_WAR == 0 - -struct rt_sigframe_n32 { - u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_code[2]; /* signal trampoline */ - struct compat_siginfo rs_info; - struct ucontextn32 rs_uc; -}; - -#else /* ICACHE_REFILLS_WORKAROUND_WAR */ - struct rt_sigframe_n32 { u32 rs_ass[4]; /* argument save space for o32 */ - u32 rs_pad[2]; + u32 rs_pad[2]; /* Was: signal trampoline */ struct compat_siginfo rs_info; struct ucontextn32 rs_uc; - u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ }; -#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ - extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) @@ -173,7 +159,7 @@ badframe: force_sig(SIGSEGV, current); } -static int setup_rt_frame_n32(struct k_sigaction * ka, +static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) { struct rt_sigframe_n32 __user *frame; @@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka, if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn); - /* Create siginfo. */ err |= copy_siginfo_to_user32(&frame->rs_info, info); @@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka, regs->regs[ 5] = (unsigned long) &frame->rs_info; regs->regs[ 6] = (unsigned long) &frame->rs_uc; regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->rs_code; + regs->regs[31] = (unsigned long) sig_return; regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", @@ -235,5 +219,7 @@ give_sigsegv: struct mips_abi mips_abi_n32 = { .setup_rt_frame = setup_rt_frame_n32, + .rt_signal_return_offset = + offsetof(struct mips_vdso, n32_rt_signal_trampoline), .restart = __NR_N32_restart_syscall }; -- cgit v1.1 From f1df323924e2fde14cbcd51209a8cbfc33e0c232 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Sat, 13 Mar 2010 12:34:15 +0800 Subject: MIPS: Loongson-2F: Flush the branch target history in BTB and RAS As per chapter 15 "Errata: Issue of Out-of-order in loongson"[1] to work around the Loongson 2F erratum we need to do: "When switching from user mode to kernel mode, you should flush the branch target history such as BTB and RAS." [1] Chinese version: http://www.loongson.cn/uploadfile/file/200808211 [2] English version of chapter 15: http://groups.google.com.hk/group/loongson-dev/msg/e0d2e220958f10a6?dmode=source Signed-off-by: Wu Zhangjin Cc: linux-mips@linux-mips.org Cc: Shinya Kuribayashi Patchwork: http://patchwork.linux-mips.org/patch/1066/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/stackframe.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 3b6da33..c841912 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -121,6 +121,25 @@ .endm #else .macro get_saved_sp /* Uniprocessor variation */ +#ifdef CONFIG_CPU_LOONGSON2F + /* + * Clear BTB (branch target buffer), forbid RAS (return address + * stack) to workaround the Out-of-order Issue in Loongson2F + * via its diagnostic register. + */ + move k0, ra + jal 1f + nop +1: jal 1f + nop +1: jal 1f + nop +1: jal 1f + nop +1: move ra, k0 + li k0, 3 + mtc0 k0, $22 +#endif /* CONFIG_CPU_LOONGSON2F */ #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) #else -- cgit v1.1 From b44c779ae0dedf3a6503c253954e570361b33f2b Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 27 Feb 2010 17:51:23 +0100 Subject: MIPS: libgcc.h: Checkpatch cleanup arch/mips/lib/libgcc.h:21: ERROR: open brace '{' following union go on the same line Signed-off-by: Andrea Gelmini To: linux-kernel@vger.kernel.org Cc: Paul Mundt Cc: linux-mips@linux-mips.org Cc: linux-sh@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/1007/ Signed-off-by: Ralf Baechle --- arch/mips/lib/libgcc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h index 3f19d1c..05909d58 100644 --- a/arch/mips/lib/libgcc.h +++ b/arch/mips/lib/libgcc.h @@ -17,8 +17,7 @@ struct DWstruct { #error I feel sick. #endif -typedef union -{ +typedef union { struct DWstruct s; long long ll; } DWunion; -- cgit v1.1 From d1b28758c6b46f6d04ef6017b51f614aecdb4abe Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 1 Mar 2010 23:36:32 +0100 Subject: MIPS: BCM63xx: Fix BCM6338 and BCM6345 gpio count The number of GPIOs on BCM6338 is 8, while BCM6345 has only 16 GPIOs available. Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1016/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h index 76a0b72..43d4da0 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h @@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void) switch (bcm63xx_get_cpu_id()) { case BCM6358_CPU_ID: return 40; + case BCM6338_CPU_ID: + return 8; + case BCM6345_CPU_ID: + return 16; case BCM6348_CPU_ID: default: return 37; -- cgit v1.1 From 2e6ad9a9585b5520cddda4743bfbfdf7f11c5a50 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 1 Mar 2010 23:36:22 +0100 Subject: MIPS: BCM63xx: Add the RTA1025W-16 BCM6348-based board to suppported boards. Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1014/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/boards/board_bcm963xx.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index ea17941..874bbdb 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -368,6 +368,25 @@ static struct board_info __initdata board_FAST2404 = { .has_ehci0 = 1, }; +static struct board_info __initdata board_rta1025w_16 = { + .name = "RTA1025W_16", + .expected_cpu_id = 0x6348, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, +}; + + static struct board_info __initdata board_DV201AMR = { .name = "DV201AMR", .expected_cpu_id = 0x6348, @@ -552,6 +571,7 @@ static const struct board_info __initdata *bcm963xx_boards[] = { &board_FAST2404, &board_DV201AMR, &board_96348gw_a, + &board_rta1025w_16, #endif #ifdef CONFIG_BCM63XX_CPU_6358 -- cgit v1.1 From f29b7cac19ef5aa093fc9403d10735fa72cabf99 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 1 Mar 2010 23:36:27 +0100 Subject: MIPS: BCM63xx: Add DWVS0 board The DWVS0 board is a BCM6358-based board with an on-board OHCI controler. Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1015/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/boards/board_bcm963xx.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 874bbdb..a690afb 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -550,6 +550,27 @@ static struct board_info __initdata board_AGPFS0 = { .has_ohci0 = 1, .has_ehci0 = 1, }; + +static struct board_info __initdata board_DWVS0 = { + .name = "DWV-S0", + .expected_cpu_id = 0x6358, + + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + .has_ohci0 = 1, +}; #endif /* @@ -578,6 +599,7 @@ static const struct board_info __initdata *bcm963xx_boards[] = { &board_96358vw, &board_96358vw2, &board_AGPFS0, + &board_DWVS0, #endif }; -- cgit v1.1 From 97befcf4f0f42b1644b4b164ddc363685546edcd Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Sat, 30 Jan 2010 18:34:54 +0100 Subject: MIPS: BCM63xx: Fix double gpio registration. bcm63xx_gpio_init is already called from prom_init to allow board to use them early, so we can remove the unneeded arch_initcall. Signed-off-by: Maxime Bizon To: linux-mips@linux-mips.org Cc: Maxime Bizon Patchwork: http://patchwork.linux-mips.org/patch/899/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/gpio.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c index 87ca390..3725345 100644 --- a/arch/mips/bcm63xx/gpio.c +++ b/arch/mips/bcm63xx/gpio.c @@ -130,5 +130,3 @@ int __init bcm63xx_gpio_init(void) return gpiochip_add(&bcm63xx_gpio_chip); } - -arch_initcall(bcm63xx_gpio_init); -- cgit v1.1 From 524ef29cff593ab6635cda2a17b331bede58a396 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Sat, 30 Jan 2010 18:34:55 +0100 Subject: MIPS: BCM63xx: Add support for second uart. The BCm63xx SOC has two uarts. Some boards use the second one for bluetooth. This patch changes platform device registration code to handle this. Changes to the UART driver were already merged in 6a2c7eabfd09ca7986bf96b8958a87ca041a19d8. Signed-off-by: Maxime Bizon To: linux-mips@linux-mips.org Cc: Maxime Bizon Patchwork: http://patchwork.linux-mips.org/patch/900/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/boards/board_bcm963xx.c | 27 ++++++++- arch/mips/bcm63xx/cpu.c | 5 ++ arch/mips/bcm63xx/dev-uart.c | 66 ++++++++++++++++------ arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 15 +++++ .../include/asm/mach-bcm63xx/bcm63xx_dev_uart.h | 6 ++ .../mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 2 + 6 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index a690afb..8b0abcb 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = { .name = "96338GW", .expected_cpu_id = 0x6338, + .has_uart0 = 1, .has_enet0 = 1, .enet0 = { .force_speed_100 = 1, @@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = { .name = "96338W", .expected_cpu_id = 0x6338, + .has_uart0 = 1, .has_enet0 = 1, .enet0 = { .force_speed_100 = 1, @@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = { static struct board_info __initdata board_96345gw2 = { .name = "96345GW2", .expected_cpu_id = 0x6345, + + .has_uart0 = 1, }; #endif @@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = { .name = "96348R", .expected_cpu_id = 0x6348, + .has_uart0 = 1, .has_enet0 = 1, .has_pci = 1, @@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = { .name = "96348GW-10", .expected_cpu_id = 0x6348, + .has_uart0 = 1, .has_enet0 = 1, .has_enet1 = 1, .has_pci = 1, @@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = { .name = "96348GW-11", .expected_cpu_id = 0x6348, + .has_uart0 = 1, .has_enet0 = 1, .has_enet1 = 1, .has_pci = 1, @@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = { .name = "96348GW", .expected_cpu_id = 0x6348, + .has_uart0 = 1, .has_enet0 = 1, .has_enet1 = 1, .has_pci = 1, @@ -349,9 +358,10 @@ static struct board_info __initdata board_FAST2404 = { .name = "F@ST2404", .expected_cpu_id = 0x6348, - .has_enet0 = 1, - .has_enet1 = 1, - .has_pci = 1, + .has_uart0 = 1, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, .enet0 = { .has_phy = 1, @@ -391,6 +401,7 @@ static struct board_info __initdata board_DV201AMR = { .name = "DV201AMR", .expected_cpu_id = 0x6348, + .has_uart0 = 1, .has_pci = 1, .has_ohci0 = 1, @@ -410,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = { .name = "96348GW-A", .expected_cpu_id = 0x6348, + .has_uart0 = 1, .has_enet0 = 1, .has_enet1 = 1, .has_pci = 1, @@ -435,6 +447,7 @@ static struct board_info __initdata board_96358vw = { .name = "96358VW", .expected_cpu_id = 0x6358, + .has_uart0 = 1, .has_enet0 = 1, .has_enet1 = 1, .has_pci = 1, @@ -486,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = { .name = "96358VW2", .expected_cpu_id = 0x6358, + .has_uart0 = 1, .has_enet0 = 1, .has_enet1 = 1, .has_pci = 1, @@ -533,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = { .name = "AGPF-S0", .expected_cpu_id = 0x6358, + .has_uart0 = 1, .has_enet0 = 1, .has_enet1 = 1, .has_pci = 1, @@ -834,6 +849,12 @@ int __init board_register_devices(void) { u32 val; + if (board.has_uart0) + bcm63xx_uart_register(0); + + if (board.has_uart1) + bcm63xx_uart_register(1); + if (board.has_pccard) bcm63xx_pcmcia_register(); diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index 70378bb..cbb7caf 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c @@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = { [RSET_TIMER] = BCM_6338_TIMER_BASE, [RSET_WDT] = BCM_6338_WDT_BASE, [RSET_UART0] = BCM_6338_UART0_BASE, + [RSET_UART1] = BCM_6338_UART1_BASE, [RSET_GPIO] = BCM_6338_GPIO_BASE, [RSET_SPI] = BCM_6338_SPI_BASE, [RSET_OHCI0] = BCM_6338_OHCI0_BASE, @@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = { [RSET_TIMER] = BCM_6345_TIMER_BASE, [RSET_WDT] = BCM_6345_WDT_BASE, [RSET_UART0] = BCM_6345_UART0_BASE, + [RSET_UART1] = BCM_6345_UART1_BASE, [RSET_GPIO] = BCM_6345_GPIO_BASE, [RSET_SPI] = BCM_6345_SPI_BASE, [RSET_UDC0] = BCM_6345_UDC0_BASE, @@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = { [RSET_TIMER] = BCM_6348_TIMER_BASE, [RSET_WDT] = BCM_6348_WDT_BASE, [RSET_UART0] = BCM_6348_UART0_BASE, + [RSET_UART1] = BCM_6348_UART1_BASE, [RSET_GPIO] = BCM_6348_GPIO_BASE, [RSET_SPI] = BCM_6348_SPI_BASE, [RSET_OHCI0] = BCM_6348_OHCI0_BASE, @@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = { [RSET_TIMER] = BCM_6358_TIMER_BASE, [RSET_WDT] = BCM_6358_WDT_BASE, [RSET_UART0] = BCM_6358_UART0_BASE, + [RSET_UART1] = BCM_6358_UART1_BASE, [RSET_GPIO] = BCM_6358_GPIO_BASE, [RSET_SPI] = BCM_6358_SPI_BASE, [RSET_OHCI0] = BCM_6358_OHCI0_BASE, @@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = { static const int bcm96358_irqs[] = { [IRQ_TIMER] = BCM_6358_TIMER_IRQ, [IRQ_UART0] = BCM_6358_UART0_IRQ, + [IRQ_UART1] = BCM_6358_UART1_IRQ, [IRQ_DSL] = BCM_6358_DSL_IRQ, [IRQ_ENET0] = BCM_6358_ENET0_IRQ, [IRQ_ENET1] = BCM_6358_ENET1_IRQ, diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c index b051946..c2963da 100644 --- a/arch/mips/bcm63xx/dev-uart.c +++ b/arch/mips/bcm63xx/dev-uart.c @@ -11,31 +11,65 @@ #include #include -static struct resource uart_resources[] = { +static struct resource uart0_resources[] = { { - .start = -1, /* filled at runtime */ - .end = -1, /* filled at runtime */ + /* start & end filled at runtime */ .flags = IORESOURCE_MEM, }, { - .start = -1, /* filled at runtime */ + /* start filled at runtime */ .flags = IORESOURCE_IRQ, }, }; -static struct platform_device bcm63xx_uart_device = { - .name = "bcm63xx_uart", - .id = 0, - .num_resources = ARRAY_SIZE(uart_resources), - .resource = uart_resources, +static struct resource uart1_resources[] = { + { + /* start & end filled at runtime */ + .flags = IORESOURCE_MEM, + }, + { + /* start filled at runtime */ + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bcm63xx_uart_devices[] = { + { + .name = "bcm63xx_uart", + .id = 0, + .num_resources = ARRAY_SIZE(uart0_resources), + .resource = uart0_resources, + }, + + { + .name = "bcm63xx_uart", + .id = 1, + .num_resources = ARRAY_SIZE(uart1_resources), + .resource = uart1_resources, + } }; -int __init bcm63xx_uart_register(void) +int __init bcm63xx_uart_register(unsigned int id) { - uart_resources[0].start = bcm63xx_regset_address(RSET_UART0); - uart_resources[0].end = uart_resources[0].start; - uart_resources[0].end += RSET_UART_SIZE - 1; - uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0); - return platform_device_register(&bcm63xx_uart_device); + if (id >= ARRAY_SIZE(bcm63xx_uart_devices)) + return -ENODEV; + + if (id == 1 && !BCMCPU_IS_6358()) + return -ENODEV; + + if (id == 0) { + uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0); + uart0_resources[0].end = uart0_resources[0].start + + RSET_UART_SIZE - 1; + uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0); + } + + if (id == 1) { + uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1); + uart1_resources[0].end = uart1_resources[0].start + + RSET_UART_SIZE - 1; + uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1); + } + + return platform_device_register(&bcm63xx_uart_devices[id]); } -arch_initcall(bcm63xx_uart_register); diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h index b12c4ac..96a2391 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h @@ -85,6 +85,7 @@ enum bcm63xx_regs_set { RSET_TIMER, RSET_WDT, RSET_UART0, + RSET_UART1, RSET_GPIO, RSET_SPI, RSET_UDC0, @@ -123,6 +124,7 @@ enum bcm63xx_regs_set { #define BCM_6338_TIMER_BASE (0xfffe0200) #define BCM_6338_WDT_BASE (0xfffe021c) #define BCM_6338_UART0_BASE (0xfffe0300) +#define BCM_6338_UART1_BASE (0xdeadbeef) #define BCM_6338_GPIO_BASE (0xfffe0400) #define BCM_6338_SPI_BASE (0xfffe0c00) #define BCM_6338_UDC0_BASE (0xdeadbeef) @@ -153,6 +155,7 @@ enum bcm63xx_regs_set { #define BCM_6345_TIMER_BASE (0xfffe0200) #define BCM_6345_WDT_BASE (0xfffe021c) #define BCM_6345_UART0_BASE (0xfffe0300) +#define BCM_6345_UART1_BASE (0xdeadbeef) #define BCM_6345_GPIO_BASE (0xfffe0400) #define BCM_6345_SPI_BASE (0xdeadbeef) #define BCM_6345_UDC0_BASE (0xdeadbeef) @@ -182,6 +185,7 @@ enum bcm63xx_regs_set { #define BCM_6348_TIMER_BASE (0xfffe0200) #define BCM_6348_WDT_BASE (0xfffe021c) #define BCM_6348_UART0_BASE (0xfffe0300) +#define BCM_6348_UART1_BASE (0xdeadbeef) #define BCM_6348_GPIO_BASE (0xfffe0400) #define BCM_6348_SPI_BASE (0xfffe0c00) #define BCM_6348_UDC0_BASE (0xfffe1000) @@ -208,6 +212,7 @@ enum bcm63xx_regs_set { #define BCM_6358_TIMER_BASE (0xfffe0040) #define BCM_6358_WDT_BASE (0xfffe005c) #define BCM_6358_UART0_BASE (0xfffe0100) +#define BCM_6358_UART1_BASE (0xfffe0120) #define BCM_6358_GPIO_BASE (0xfffe0080) #define BCM_6358_SPI_BASE (0xdeadbeef) #define BCM_6358_UDC0_BASE (0xfffe0800) @@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) return BCM_6338_WDT_BASE; case RSET_UART0: return BCM_6338_UART0_BASE; + case RSET_UART1: + return BCM_6338_UART1_BASE; case RSET_GPIO: return BCM_6338_GPIO_BASE; case RSET_SPI: @@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) return BCM_6345_WDT_BASE; case RSET_UART0: return BCM_6345_UART0_BASE; + case RSET_UART1: + return BCM_6345_UART1_BASE; case RSET_GPIO: return BCM_6345_GPIO_BASE; case RSET_SPI: @@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) return BCM_6348_WDT_BASE; case RSET_UART0: return BCM_6348_UART0_BASE; + case RSET_UART1: + return BCM_6348_UART1_BASE; case RSET_GPIO: return BCM_6348_GPIO_BASE; case RSET_SPI: @@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) return BCM_6358_WDT_BASE; case RSET_UART0: return BCM_6358_UART0_BASE; + case RSET_UART1: + return BCM_6358_UART1_BASE; case RSET_GPIO: return BCM_6358_GPIO_BASE; case RSET_SPI: @@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) enum bcm63xx_irq { IRQ_TIMER = 0, IRQ_UART0, + IRQ_UART1, IRQ_DSL, IRQ_ENET0, IRQ_ENET1, @@ -510,6 +524,7 @@ enum bcm63xx_irq { */ #define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) #define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2) +#define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3) #define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5) #define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6) #define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h new file mode 100644 index 0000000..23c705b --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h @@ -0,0 +1,6 @@ +#ifndef BCM63XX_DEV_UART_H_ +#define BCM63XX_DEV_UART_H_ + +int bcm63xx_uart_register(unsigned int id); + +#endif /* BCM63XX_DEV_UART_H_ */ diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h index 6479090..474daaa 100644 --- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h @@ -45,6 +45,8 @@ struct board_info { unsigned int has_ohci0:1; unsigned int has_ehci0:1; unsigned int has_dsp:1; + unsigned int has_uart0:1; + unsigned int has_uart1:1; /* ethernet config */ struct bcm63xx_enet_platform_data enet0; -- cgit v1.1 From 4fe67e44a0e0cb6281cbaaf603111187d87fce57 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Sat, 30 Jan 2010 18:34:56 +0100 Subject: MIPS: BCM63xx: Fix typo in cpu-feature-overrides file. Fix typo: CONFIG_BCMCPU_IS_63xx does not exist; CONFIG_BCM63XX_CPU_63xx is the valid config option. Signed-off-by: Maxime Bizon To: linux-mips@linux-mips.org Cc: Maxime Bizon Patchwork: http://patchwork.linux-mips.org/patch/901/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h index 71742bac..f453c01 100644 --- a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h @@ -24,7 +24,7 @@ #define cpu_has_smartmips 0 #define cpu_has_vtag_icache 0 -#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345)) +#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338)) #define cpu_has_dc_aliases 0 #endif -- cgit v1.1 From e23a90eb736b18c16fd6d59e8c1fa6a16ac3bc0b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 2 Mar 2010 14:38:47 +0100 Subject: MIPS: BCM63xx: Register SSB SPROM fallback in board's first stage callback Signed-off-by: Florian Fainelli To: Maxime Bizon Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1017/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/boards/board_bcm963xx.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 8b0abcb..5addb9c 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -716,6 +716,17 @@ void __init board_prom_init(void) } bcm_gpio_writel(val, GPIO_MODE_REG); + + /* Generate MAC address for WLAN and + * register our SPROM */ +#ifdef CONFIG_SSB_PCIHOST + if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { + memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); + memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); + if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0) + printk(KERN_ERR "failed to register fallback SPROM\n"); + } +#endif } /* @@ -869,17 +880,6 @@ int __init board_register_devices(void) if (board.has_dsp) bcm63xx_dsp_register(&board.dsp); - /* Generate MAC address for WLAN and - * register our SPROM */ -#ifdef CONFIG_SSB_PCIHOST - if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { - memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); - memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); - if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0) - printk(KERN_ERR "failed to register fallback SPROM\n"); - } -#endif - /* read base address of boot chip select (0) */ if (BCMCPU_IS_6345()) val = 0x1fc00000; -- cgit v1.1 From 9538ca636f2fa28ae1514327328e2869f0215981 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Sat, 30 Jan 2010 18:34:58 +0100 Subject: MIPS: BCM63xx: Initialize gpio_out_low & out_high to current value at boot. To avoid a glitch during GPIO initialisation read GPIO output register values left by the firmware. Signed-off-by: Maxime Bizon To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/903/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c index 3725345..315bc7f 100644 --- a/arch/mips/bcm63xx/gpio.c +++ b/arch/mips/bcm63xx/gpio.c @@ -125,6 +125,8 @@ static struct gpio_chip bcm63xx_gpio_chip = { int __init bcm63xx_gpio_init(void) { + gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG); + gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG); bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count(); pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio); -- cgit v1.1 From 8d9df29db273ab9a330828f4f4f6669d293a730a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 23 Mar 2010 00:02:43 +0100 Subject: MIPS: Sibyte: Apply M3 workaround only on affected chip types and versions. Previously it was unconditionally used on all Sibyte family SOCs. The M3 bug has to be handled in the TLB exception handler which is extremly performance sensitive, so this modification is expected to deliver around 2-3% performance improvment. This is important as required changes to the M3 workaround will make it more costly. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-sibyte/war.h | 6 +++++- arch/mips/sibyte/sb1250/setup.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h index 7950ef4..743385d 100644 --- a/arch/mips/include/asm/mach-sibyte/war.h +++ b/arch/mips/include/asm/mach-sibyte/war.h @@ -16,7 +16,11 @@ #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \ defined(CONFIG_SB1_PASS_2_WORKAROUNDS) -#define BCM1250_M3_WAR 1 +#ifndef __ASSEMBLY__ +extern int sb1250_m3_workaround_needed(void); +#endif + +#define BCM1250_M3_WAR sb1250_m3_workaround_needed() #define SIBYTE_1956_WAR 1 #else diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index 0444da1..92da315 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c @@ -87,6 +87,21 @@ static int __init setup_bcm1250(void) return ret; } +int sb1250_m3_workaround_needed(void) +{ + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: + case K_SYS_SOC_TYPE_BCM1250_ALT2: + case K_SYS_SOC_TYPE_BCM1125: + case K_SYS_SOC_TYPE_BCM1125H: + return soc_pass < K_SYS_REVISION_BCM1250_C0; + + default: + return 0; + } +} + static int __init setup_bcm112x(void) { int ret = 0; -- cgit v1.1 From 5808184f1b2fe06ef8a54a2b7fb1596d58098acf Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 23 Mar 2010 15:54:50 +0100 Subject: MIPS: uasm: Add OR instruction. This is needed for the fix of the M3 workaround. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/uasm.h | 1 + arch/mips/mm/uasm.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index 32fe2ec..11a8b52 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h @@ -84,6 +84,7 @@ Ip_u2s3u1(_lw); Ip_u1u2u3(_mfc0); Ip_u1u2u3(_mtc0); Ip_u2u1u3(_ori); +Ip_u3u1u2(_or); Ip_u2s3u1(_pref); Ip_0(_rfe); Ip_u2s3u1(_sc); diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index d22d7bc..611d564 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -64,7 +64,7 @@ enum opcode { insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, - insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, + insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, insn_dins, insn_syscall @@ -120,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = { { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, + { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, @@ -387,6 +388,7 @@ I_u2s3u1(_lw) I_u1u2u3(_mfc0) I_u1u2u3(_mtc0) I_u2u1u3(_ori) +I_u3u1u2(_or) I_u2s3u1(_pref) I_0(_rfe) I_u2s3u1(_sc) -- cgit v1.1 From 5e3644a95db11e2e582ae3765ffad6e0cce5376e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 23 Mar 2010 10:30:08 +0100 Subject: MIPS: BCM63xx: Fix build failure in board_bcm963xx.c Since 2083e8327aeeaf818b0e4522a9d2539835c60423, the SPROM is now registered in the board_prom_init callback, but it references variables and functions which are declared below. Move the variables and functions above board_prom_init. Signed-off-by: Florian Fainelli To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1077/ Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/boards/board_bcm963xx.c | 140 +++++++++++++++--------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 5addb9c..8dba8cf 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -619,6 +619,76 @@ static const struct board_info __initdata *bcm963xx_boards[] = { }; /* + * Register a sane SPROMv2 to make the on-board + * bcm4318 WLAN work + */ +#ifdef CONFIG_SSB_PCIHOST +static struct ssb_sprom bcm63xx_sprom = { + .revision = 0x02, + .board_rev = 0x17, + .country_code = 0x0, + .ant_available_bg = 0x3, + .pa0b0 = 0x15ae, + .pa0b1 = 0xfa85, + .pa0b2 = 0xfe8d, + .pa1b0 = 0xffff, + .pa1b1 = 0xffff, + .pa1b2 = 0xffff, + .gpio0 = 0xff, + .gpio1 = 0xff, + .gpio2 = 0xff, + .gpio3 = 0xff, + .maxpwr_bg = 0x004c, + .itssi_bg = 0x00, + .boardflags_lo = 0x2848, + .boardflags_hi = 0x0000, +}; +#endif + +/* + * return board name for /proc/cpuinfo + */ +const char *board_get_name(void) +{ + return board.name; +} + +/* + * register & return a new board mac address + */ +static int board_get_mac_address(u8 *mac) +{ + u8 *p; + int count; + + if (mac_addr_used >= nvram.mac_addr_count) { + printk(KERN_ERR PFX "not enough mac address\n"); + return -ENODEV; + } + + memcpy(mac, nvram.mac_addr_base, ETH_ALEN); + p = mac + ETH_ALEN - 1; + count = mac_addr_used; + + while (count--) { + do { + (*p)++; + if (*p != 0) + break; + p--; + } while (p != mac); + } + + if (p == mac) { + printk(KERN_ERR PFX "unable to fetch mac address\n"); + return -ENODEV; + } + + mac_addr_used++; + return 0; +} + +/* * early init callback, read nvram data from flash and checksum it */ void __init board_prom_init(void) @@ -744,49 +814,6 @@ void __init board_setup(void) panic("unexpected CPU for bcm963xx board"); } -/* - * return board name for /proc/cpuinfo - */ -const char *board_get_name(void) -{ - return board.name; -} - -/* - * register & return a new board mac address - */ -static int board_get_mac_address(u8 *mac) -{ - u8 *p; - int count; - - if (mac_addr_used >= nvram.mac_addr_count) { - printk(KERN_ERR PFX "not enough mac address\n"); - return -ENODEV; - } - - memcpy(mac, nvram.mac_addr_base, ETH_ALEN); - p = mac + ETH_ALEN - 1; - count = mac_addr_used; - - while (count--) { - do { - (*p)++; - if (*p != 0) - break; - p--; - } while (p != mac); - } - - if (p == mac) { - printk(KERN_ERR PFX "unable to fetch mac address\n"); - return -ENODEV; - } - - mac_addr_used++; - return 0; -} - static struct mtd_partition mtd_partitions[] = { { .name = "cfe", @@ -818,33 +845,6 @@ static struct platform_device mtd_dev = { }, }; -/* - * Register a sane SPROMv2 to make the on-board - * bcm4318 WLAN work - */ -#ifdef CONFIG_SSB_PCIHOST -static struct ssb_sprom bcm63xx_sprom = { - .revision = 0x02, - .board_rev = 0x17, - .country_code = 0x0, - .ant_available_bg = 0x3, - .pa0b0 = 0x15ae, - .pa0b1 = 0xfa85, - .pa0b2 = 0xfe8d, - .pa1b0 = 0xffff, - .pa1b1 = 0xffff, - .pa1b2 = 0xffff, - .gpio0 = 0xff, - .gpio1 = 0xff, - .gpio2 = 0xff, - .gpio3 = 0xff, - .maxpwr_bg = 0x004c, - .itssi_bg = 0x00, - .boardflags_lo = 0x2848, - .boardflags_hi = 0x0000, -}; -#endif - static struct gpio_led_platform_data bcm63xx_led_data; static struct platform_device bcm63xx_gpio_leds = { -- cgit v1.1 From 3d45285dd1ff4d4a1361b95e2d6508579a4402b5 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 23 Mar 2010 17:56:38 +0100 Subject: MIPS: Sibyte: Fix M3 TLB exception handler workaround. The M3 workaround needs to cmpare the region and VPN2 fields only. Signed-off-by: Ralf Baechle --- arch/mips/mm/tlbex.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 0de0e41..d1f68aa 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -788,10 +788,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) * create the plain linear handler */ if (bcm1250_m3_war()) { - UASM_i_MFC0(&p, K0, C0_BADVADDR); - UASM_i_MFC0(&p, K1, C0_ENTRYHI); + unsigned int segbits = 44; + + uasm_i_dmfc0(&p, K0, C0_BADVADDR); + uasm_i_dmfc0(&p, K1, C0_ENTRYHI); uasm_i_xor(&p, K0, K0, K1); - UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1); + uasm_i_dsrl32(&p, K1, K0, 62 - 32); + uasm_i_dsrl(&p, K0, K0, 12 + 1); + uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32); + uasm_i_or(&p, K0, K0, K1); uasm_il_bnez(&p, &r, K0, label_leave); /* No need for uasm_i_nop */ } @@ -1312,10 +1317,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void) memset(relocs, 0, sizeof(relocs)); if (bcm1250_m3_war()) { - UASM_i_MFC0(&p, K0, C0_BADVADDR); - UASM_i_MFC0(&p, K1, C0_ENTRYHI); + unsigned int segbits = 44; + + uasm_i_dmfc0(&p, K0, C0_BADVADDR); + uasm_i_dmfc0(&p, K1, C0_ENTRYHI); uasm_i_xor(&p, K0, K0, K1); - UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1); + uasm_i_dsrl32(&p, K1, K0, 62 - 32); + uasm_i_dsrl(&p, K0, K0, 12 + 1); + uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32); + uasm_i_or(&p, K0, K0, K1); uasm_il_bnez(&p, &r, K0, label_leave); /* No need for uasm_i_nop */ } -- cgit v1.1 From 7b3e543ddb39b69b75c9c24bb54180eca152f541 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Thu, 25 Mar 2010 20:48:12 +0000 Subject: MIPS: Fix __vmalloc() etc. on MIPS for non-GPL modules Commit b3594a089f1c17ff919f8f78505c3f20e1f6f8ce (lmo) rsp. 351336929ccf222ae38ff0cb7a8dd5fd5c6236a0 (kernel.org) break non-GPL modules that use __vmalloc() or any of the vmap(), vm_map_ram(), etc functions on MIPS. All those functions are EXPORT_SYMBOL() so are meant to be allowed to be used by non-GPL kernel modules. These calls all take page protection as an argument which is normally a constant like PAGE_KERNEL. This commit causes all protection constants like PAGE_KERNEL to not be constants and instead to contain the GPL-only symbol _page_cachable_default. This means that all calls to __vmalloc(), vmap(), etc, cause non-GPL modules to fail to link with the complaint that they are trying to use the GPL-only symbol _page_cachable_default... Change EXPORT_SYMBOL_GPL(_page_cachable_default) to EXPORT_SYMBOL() for non-GPL modules that call __vmalloc(), vmap(), vm_map_ram() etc. Signed-off-by: Anton Altaparmakov Cc: Chris Dearman Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: http://patchwork.linux-mips.org/patch/1084/ Signed-off-by: Ralf Baechle --- arch/mips/mm/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index be8627b..12af739 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address, } unsigned long _page_cachable_default; -EXPORT_SYMBOL_GPL(_page_cachable_default); +EXPORT_SYMBOL(_page_cachable_default); static inline void setup_protection_map(void) { -- cgit v1.1 From 2844e49f5ea1ae75d2026ff128b145e3bd44134c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 3 Apr 2010 10:59:52 +0100 Subject: MIPS: Big Sur: Make defconfig more useful. Signed-off-by: Ralf Baechle --- arch/mips/configs/bigsur_defconfig | 680 ++++++++++++++++++++++++++----------- 1 file changed, 490 insertions(+), 190 deletions(-) diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index c2f06e3..0583bb2 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc8 -# Wed Jul 2 17:02:55 2008 +# Linux kernel version: 2.6.34-rc3 +# Sat Apr 3 16:32:11 2010 # CONFIG_MIPS=y @@ -9,20 +9,25 @@ CONFIG_MIPS=y # Machine selection # # CONFIG_MACH_ALCHEMY is not set +# CONFIG_AR7 is not set # CONFIG_BCM47XX is not set +# CONFIG_BCM63XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set -# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MACH_LOONGSON is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SIM is not set -# CONFIG_MARKEINS is not set +# CONFIG_NEC_MARKEINS is not set # CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +# CONFIG_NXP_STB225 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_PMC_MSP is not set # CONFIG_PMC_YOSEMITE is not set +# CONFIG_POWERTV is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP28 is not set @@ -36,10 +41,13 @@ CONFIG_MIPS=y # CONFIG_SIBYTE_SENTOSA is not set CONFIG_SIBYTE_BIGSUR=y # CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_MIKROTIK_RB532 is not set # CONFIG_WR_PPMC is not set +# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set +# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set +# CONFIG_ALCHEMY_GPIO_INDIRECT is not set CONFIG_SIBYTE_BCM1x80=y CONFIG_SIBYTE_SB1xxx_SOC=y # CONFIG_CPU_SB1_PASS_1 is not set @@ -48,14 +56,13 @@ CONFIG_SIBYTE_SB1xxx_SOC=y # CONFIG_CPU_SB1_PASS_4 is not set # CONFIG_CPU_SB1_PASS_2_112x is not set # CONFIG_CPU_SB1_PASS_3 is not set -# CONFIG_SIMULATION is not set # CONFIG_SB1_CEX_ALWAYS_FATAL is not set # CONFIG_SB1_CERR_STALL is not set -CONFIG_SIBYTE_CFE=y # CONFIG_SIBYTE_CFE_CONSOLE is not set # CONFIG_SIBYTE_BUS_WATCHER is not set # CONFIG_SIBYTE_TBPROF is not set CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y +CONFIG_LOONGSON_UART_BASE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -66,15 +73,13 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_CEVT_BCM1480=y CONFIG_CSRC_BCM1480=y CONFIG_CFE=y CONFIG_DMA_COHERENT=y -CONFIG_EARLY_PRINTK=y CONFIG_SYS_HAS_EARLY_PRINTK=y -# CONFIG_HOTPLUG_CPU is not set # CONFIG_NO_IOPORT is not set CONFIG_CPU_BIG_ENDIAN=y # CONFIG_CPU_LITTLE_ENDIAN is not set @@ -88,7 +93,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 # # CPU selection # -# CONFIG_CPU_LOONGSON2 is not set +# CONFIG_CPU_LOONGSON2E is not set +# CONFIG_CPU_LOONGSON2F is not set # CONFIG_CPU_MIPS32_R1 is not set # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set @@ -101,6 +107,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R5500 is not set # CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set # CONFIG_CPU_R8000 is not set @@ -108,6 +115,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set CONFIG_CPU_SB1=y +# CONFIG_CPU_CAVIUM_OCTEON is not set CONFIG_SYS_HAS_CPU_SB1=y CONFIG_WEAK_ORDERING=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y @@ -123,11 +131,13 @@ CONFIG_64BIT=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_32KB is not set # CONFIG_PAGE_SIZE_64KB is not set # CONFIG_SIBYTE_DMA_PAGEOPS is not set CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y @@ -142,18 +152,17 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y +CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_SMP=y CONFIG_SYS_SUPPORTS_SMP=y CONFIG_NR_CPUS_DEFAULT_4=y CONFIG_NR_CPUS=4 -# CONFIG_MIPS_CMP is not set CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -175,6 +184,7 @@ CONFIG_SECCOMP=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -188,6 +198,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y @@ -195,23 +206,39 @@ CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=64 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 # CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y -# CONFIG_NAMESPACES is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y CONFIG_EMBEDDED=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y @@ -222,29 +249,36 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y # CONFIG_PCSPKR_PLATFORM is not set -CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -# CONFIG_HAVE_KRETPROBES is not set -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_PROC_PAGE_MONITOR=y +CONFIG_HAVE_SYSCALL_WRAPPERS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -252,26 +286,52 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set CONFIG_BLOCK_COMPAT=y # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_INLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +CONFIG_INLINE_READ_UNLOCK=y +# CONFIG_INLINE_READ_UNLOCK_BH is not set +CONFIG_INLINE_READ_UNLOCK_IRQ=y +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +CONFIG_INLINE_WRITE_UNLOCK=y +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +# CONFIG_FREEZER is not set # # Bus options (PCI, PCMCIA, EISA, ISA, TC) @@ -280,8 +340,9 @@ CONFIG_HW_HAS_PCI=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y CONFIG_PCI_DEBUG=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set CONFIG_MMU=y CONFIG_ZONE_DMA32=y # CONFIG_PCCARD is not set @@ -291,6 +352,8 @@ CONFIG_ZONE_DMA32=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set CONFIG_MIPS32_COMPAT=y CONFIG_COMPAT=y @@ -304,23 +367,20 @@ CONFIG_BINFMT_ELF32=y # CONFIG_PM=y # CONFIG_PM_DEBUG is not set - -# -# Networking -# +# CONFIG_PM_RUNTIME is not set CONFIG_NET=y # # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m # CONFIG_XFRM_SUB_POLICY is not set CONFIG_XFRM_MIGRATE=y # CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=y CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y @@ -353,36 +413,6 @@ CONFIG_INET_TCP_DIAG=y CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -399,11 +429,13 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y # CONFIG_IPV6_MROUTE is not set +CONFIG_NETLABEL=y CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -421,19 +453,53 @@ CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CT_NETLINK=m CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m # # IP: Netfilter Configuration # +CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_PROC_COMPAT=y CONFIG_IP_NF_IPTABLES=m @@ -459,22 +525,44 @@ CONFIG_IP_NF_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m -# CONFIG_IP_DCCP is not set +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=y + +# +# DCCP Kernel Hacking +# +# CONFIG_IP_DCCP_DEBUG is not set CONFIG_IP_SCTP=m # CONFIG_SCTP_DBG_MSG is not set # CONFIG_SCTP_DBG_OBJCNT is not set # CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y +CONFIG_SCTP_HMAC_SHA1=y +# CONFIG_SCTP_HMAC_MD5 is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y # CONFIG_DECNET is not set +CONFIG_LLC=m # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -482,26 +570,47 @@ CONFIG_SCTP_HMAC_MD5=y # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_YAM=m # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set # -# Wireless +# CFG80211 needs to be enabled for MAC80211 # -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -513,9 +622,12 @@ CONFIG_FIB_RULES=y # Generic Driver Options # CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set @@ -530,33 +642,53 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_CRYPTOLOOP=m + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set CONFIG_SGI_IOC4=m # CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_DS1682 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +CONFIG_EEPROM_LEGACY=y +CONFIG_EEPROM_MAX6875=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_CB710_CORE is not set CONFIG_HAVE_IDE=y CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide/ide.txt for help/info on IDE drives # +CONFIG_IDE_XFER_MODE=y +CONFIG_IDE_TIMINGS=y +CONFIG_IDE_ATAPI=y # CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +# CONFIG_IDE_GD_ATAPI is not set CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y CONFIG_BLK_DEV_IDETAPE=y -CONFIG_BLK_DEV_IDEFLOPPY=y -# CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_IDE_TASK_IOCTL is not set CONFIG_IDE_PROC_FS=y @@ -581,14 +713,13 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_AMD74XX is not set CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5520 is not set # CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8172 is not set CONFIG_BLK_DEV_IT8213=m # CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set @@ -600,14 +731,12 @@ CONFIG_BLK_DEV_IT8213=m # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set CONFIG_BLK_DEV_TC86C001=m -# CONFIG_BLK_DEV_IDE_SWARM is not set CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_BLK_DEV_HD_ONLY is not set -# CONFIG_BLK_DEV_HD is not set # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -625,10 +754,6 @@ CONFIG_BLK_DEV_SR=m CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_CHR_DEV_SCH=m - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -645,27 +770,36 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_MVSAS is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set @@ -676,9 +810,15 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y CONFIG_SATA_PMP=y # CONFIG_SATA_AHCI is not set CONFIG_SATA_SIL24=y @@ -700,6 +840,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATP867X is not set # CONFIG_PATA_ATIIXP is not set # CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set @@ -715,6 +856,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set @@ -725,14 +867,16 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set # CONFIG_PATA_RZ1000 is not set # CONFIG_PATA_SC1200 is not set # CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set CONFIG_PATA_SIL680=y # CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # CONFIG_PATA_PLATFORM is not set @@ -745,13 +889,16 @@ CONFIG_PATA_SIL680=y # # -# Enable only one of the two stacks, unless you know what you are doing +# You can enable one or both FireWire driver stacks. +# + +# +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # CONFIG_I2O is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set @@ -774,6 +921,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -783,23 +933,33 @@ CONFIG_MII=y # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set # CONFIG_DM9000 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_NET_PCI is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_ATL2 is not set CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set -# CONFIG_E1000E_ENABLED is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -811,29 +971,42 @@ CONFIG_SB1250_MAC=y # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set +# CONFIG_CNIC is not set # CONFIG_QLA3XXX is not set # CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_JME is not set CONFIG_NETDEV_10000=y +CONFIG_MDIO=m # CONFIG_CHELSIO_T1 is not set +CONFIG_CHELSIO_T3_DEPENDS=y CONFIG_CHELSIO_T3=m +# CONFIG_ENIC is not set # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set CONFIG_NETXEN_NIC=m # CONFIG_NIU is not set +# CONFIG_MLX4_EN is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set # CONFIG_SFC is not set +# CONFIG_BE2NET is not set # CONFIG_TR is not set +CONFIG_WLAN=y +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -856,6 +1029,7 @@ CONFIG_SLIP_MODE_SLIP6=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -873,6 +1047,7 @@ CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_PCIPS2 is not set # CONFIG_SERIO_LIBPS2 is not set CONFIG_SERIO_RAW=m +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -893,8 +1068,6 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set -# CONFIG_SX is not set -# CONFIG_RIO is not set # CONFIG_STALDRV is not set # CONFIG_NOZOMI is not set @@ -911,7 +1084,9 @@ CONFIG_SERIAL_SB1250_DUART_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set @@ -923,89 +1098,99 @@ CONFIG_LEGACY_PTY_COUNT=256 CONFIG_DEVPORT=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y # # I2C Hardware Bus support # + +# +# PC SMBus host controller drivers +# # CONFIG_I2C_ALI1535 is not set # CONFIG_I2C_ALI1563 is not set # CONFIG_I2C_ALI15X3 is not set # CONFIG_I2C_AMD756 is not set # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISCH is not set # CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -CONFIG_I2C_SIBYTE=y -# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_STUB is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_PLATFORM is not set # -# Miscellaneous I2C Chip support +# I2C system bus drivers (mostly embedded / system-on-chip) # -# CONFIG_DS1682 is not set -CONFIG_EEPROM_LEGACY=y -CONFIG_SENSORS_PCF8574=y -# CONFIG_PCF8575 is not set -CONFIG_SENSORS_PCF8591=y -CONFIG_EEPROM_MAX6875=y -# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +CONFIG_I2C_SIBYTE=y +# CONFIG_I2C_STUB is not set CONFIG_I2C_DEBUG_CORE=y CONFIG_I2C_DEBUG_ALGO=y CONFIG_I2C_DEBUG_BUS=y -CONFIG_I2C_DEBUG_CHIP=y # CONFIG_SPI is not set + +# +# PPS support +# +# CONFIG_PPS is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # # Multifunction device drivers # +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_LPC_SCH is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support # +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -1016,10 +1201,6 @@ CONFIG_SSB_POSSIBLE=y # Display device support # # CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# # CONFIG_SOUND is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y @@ -1030,9 +1211,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB_OTG_BLACKLIST_HUB is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# Enable Host or Gadget support to see Inventra options +# + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +# CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -1040,41 +1230,66 @@ CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_INFINIBAND is not set CONFIG_RTC_LIB=y # CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# # File systems # CONFIG_EXT2_FS=m CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT2_FS_POSIX_ACL is not set -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XIP=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_FS_XIP=y +CONFIG_JBD=m +CONFIG_JBD2=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set +CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QUOTA_TREE=m # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=m CONFIG_QUOTACTL=y CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m +# CONFIG_CUSE is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set # # CD-ROM/DVD Filesystems @@ -1103,15 +1318,13 @@ CONFIG_NTFS_RW=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_ECRYPT_FS is not set @@ -1120,9 +1333,12 @@ CONFIG_CONFIGFS_FS=m # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set @@ -1133,16 +1349,17 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set -# CONFIG_NFSD is not set CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1205,12 +1422,18 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1219,23 +1442,53 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set # CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_LIST is not set +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_LIST=y # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_DETECTOR=y # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_EARLY_PRINTK=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_SB1XXX_CORELIS is not set @@ -1246,20 +1499,50 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_KEYS=y CONFIG_KEYS_DEBUG_PROC_KEYS=y -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +# CONFIG_SECURITY_PATH is not set +CONFIG_LSM_MMAP_MIN_ADDR=65536 +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_SELINUX_DISABLE=y +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # # Crypto core or helper # +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_AUTHENC=m # CONFIG_CRYPTO_TEST is not set @@ -1276,7 +1559,7 @@ CONFIG_CRYPTO_SEQIV=m # CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_CTR=m -# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m @@ -1287,14 +1570,20 @@ CONFIG_CRYPTO_XTS=m # CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m # # Digest # -# CONFIG_CRYPTO_CRC32C is not set +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_GHASH=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m @@ -1325,25 +1614,36 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m # Compression # CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=m CONFIG_CRC_ITU_T=m CONFIG_CRC32=y -# CONFIG_CRC7 is not set +CONFIG_CRC7=m CONFIG_LIBCRC32C=m CONFIG_AUDIT_GENERIC=y -CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v1.1 From d8000beef2cd10c16dc5f66af715f692f5992652 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Sat, 3 Apr 2010 17:07:03 +0200 Subject: MIPS: Alchemy: DB1200: Remove custom wait implementation While playing with the out-of-tree MAE driver module, the system would panic after a while in the db1200 custom wait code after wakeup due to a clobbered k0 register being used as target address of a store op. Remove the custom wait implementation and revert back to the Alchemy- recommended implementation already set as default. Signed-off-by: Manuel Lauss To: Linux-MIPS Patchwork: http://patchwork.linux-mips.org/patch/1092/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/devboards/db1200/setup.c | 40 ------------------------------ 1 file changed, 40 deletions(-) diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c index 379536e..be7e92e 100644 --- a/arch/mips/alchemy/devboards/db1200/setup.c +++ b/arch/mips/alchemy/devboards/db1200/setup.c @@ -60,43 +60,6 @@ void __init board_setup(void) wmb(); } -/* use the hexleds to count the number of times the cpu has entered - * wait, the dots to indicate whether the CPU is currently idle or - * active (dots off = sleeping, dots on = working) for cases where - * the number doesn't change for a long(er) period of time. - */ -static void db1200_wait(void) -{ - __asm__(" .set push \n" - " .set mips3 \n" - " .set noreorder \n" - " cache 0x14, 0(%0) \n" - " cache 0x14, 32(%0) \n" - " cache 0x14, 64(%0) \n" - /* dots off: we're about to call wait */ - " lui $26, 0xb980 \n" - " ori $27, $0, 3 \n" - " sb $27, 0x18($26) \n" - " sync \n" - " nop \n" - " wait \n" - " nop \n" - " nop \n" - " nop \n" - " nop \n" - " nop \n" - /* dots on: there's work to do, increment cntr */ - " lui $26, 0xb980 \n" - " sb $0, 0x18($26) \n" - " lui $26, 0xb9c0 \n" - " lb $27, 0($26) \n" - " addiu $27, $27, 1 \n" - " sb $27, 0($26) \n" - " sync \n" - " .set pop \n" - : : "r" (db1200_wait)); -} - static int __init db1200_arch_init(void) { /* GPIO7 is low-level triggered CPLD cascade */ @@ -110,9 +73,6 @@ static int __init db1200_arch_init(void) irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN; irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN; - if (cpu_wait) - cpu_wait = db1200_wait; - return 0; } arch_initcall(db1200_arch_init); -- cgit v1.1 From f6be75d03c8870be91e6e2a195648ece04b6bb16 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 6 Apr 2010 13:29:50 -0700 Subject: MIPS: Calculate proper ebase value for 64-bit kernels The ebase is relative to CKSEG0 not CAC_BASE. On a 32-bit kernel they are the same thing, for a 64-bit kernel they are not. It happens to kind of work on a 64-bit kernel as they both reference the same physical memory. However since the CPU uses the CKSEG0 base, determining if a J instruction will reach always gives the wrong result unless we use the same number the CPU uses. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/1093/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 4e00f9b..1a4dd65 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1599,7 +1599,7 @@ void __init trap_init(void) ebase = (unsigned long) __alloc_bootmem(size, 1 << fls(size), 0); } else { - ebase = CAC_BASE; + ebase = CKSEG0; if (cpu_has_mips_r2) ebase += (read_c0_ebase() & 0x3ffff000); } -- cgit v1.1 From fc7683a3c30c22131b1651271d6bf9ea113b77c5 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Fri, 26 Mar 2010 19:29:54 +0300 Subject: ext2: symlink must be handled via filesystem specific operation generic setattr implementation is no longer responsible for quota transfer so synlinks must be handled via ext2_setattr. Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara --- fs/ext2/symlink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 4e2426e..565cf81 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c @@ -32,6 +32,7 @@ const struct inode_operations ext2_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = page_follow_link_light, .put_link = page_put_link, + .setattr = ext2_setattr, #ifdef CONFIG_EXT2_FS_XATTR .setxattr = generic_setxattr, .getxattr = generic_getxattr, @@ -43,6 +44,7 @@ const struct inode_operations ext2_symlink_inode_operations = { const struct inode_operations ext2_fast_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = ext2_follow_link, + .setattr = ext2_setattr, #ifdef CONFIG_EXT2_FS_XATTR .setxattr = generic_setxattr, .getxattr = generic_getxattr, -- cgit v1.1 From 774f03fb2cf89951b5f5f363b7739a2835d5924e Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Fri, 26 Mar 2010 19:29:55 +0300 Subject: ext3: symlink must be handled via filesystem specific operation generic setattr implementation is no longer responsible for quota transfer so synlinks must be handled via ext3_setattr. Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara --- fs/ext3/symlink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c index ff7b4cc..7c48982 100644 --- a/fs/ext3/symlink.c +++ b/fs/ext3/symlink.c @@ -34,6 +34,7 @@ const struct inode_operations ext3_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = page_follow_link_light, .put_link = page_put_link, + .setattr = ext3_setattr, #ifdef CONFIG_EXT3_FS_XATTR .setxattr = generic_setxattr, .getxattr = generic_getxattr, @@ -45,6 +46,7 @@ const struct inode_operations ext3_symlink_inode_operations = { const struct inode_operations ext3_fast_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = ext3_follow_link, + .setattr = ext3_setattr, #ifdef CONFIG_EXT3_FS_XATTR .setxattr = generic_setxattr, .getxattr = generic_getxattr, -- cgit v1.1 From 4c5e6c0e70fd6ca2fa67184fd36a261b3b7b38d0 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 6 Apr 2010 18:52:47 +0200 Subject: quota: Hide warnings about writes to the filesystem before quota was turned on For a root filesystem write to the filesystem before quota is turned on happens regularly and there's no way around it because of writes to syslog, /etc/mtab, and similar. So the warning is rather pointless for ordinary users. It's still useful during development so we just hide the warning behind __DQUOT_PARANOIA config option. Signed-off-by: Jan Kara --- fs/quota/dquot.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index e0b870f..f9a3751 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -874,14 +874,18 @@ static int dqinit_needed(struct inode *inode, int type) static void add_dquot_ref(struct super_block *sb, int type) { struct inode *inode, *old_inode = NULL; +#ifdef __DQUOT_PARANOIA int reserved = 0; +#endif spin_lock(&inode_lock); list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) continue; +#ifdef __DQUOT_PARANOIA if (unlikely(inode_get_rsv_space(inode) > 0)) reserved = 1; +#endif if (!atomic_read(&inode->i_writecount)) continue; if (!dqinit_needed(inode, type)) @@ -903,11 +907,13 @@ static void add_dquot_ref(struct super_block *sb, int type) spin_unlock(&inode_lock); iput(old_inode); +#ifdef __DQUOT_PARANOIA if (reserved) { printk(KERN_WARNING "VFS (%s): Writes happened before quota" " was turned on thus quota information is probably " "inconsistent. Please run quotacheck(8).\n", sb->s_id); } +#endif } /* -- cgit v1.1 From 08261673cb6dc638c39f44d69b76fffb57b92a8b Mon Sep 17 00:00:00 2001 From: Andrew Perepechko Date: Mon, 12 Apr 2010 22:16:50 +0400 Subject: quota: Fix possible dq_flags corruption dq_flags are modified non-atomically in do_set_dqblk via __set_bit calls and atomically for example in mark_dquot_dirty or clear_dquot_dirty. Hence a change done by an atomic operation can be overwritten by a change done by a non-atomic one. Fix the problem by using atomic bitops even in do_set_dqblk. Signed-off-by: Andrew Perepechko Signed-off-by: Jan Kara --- fs/quota/dquot.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index f9a3751..a0a9405 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -2328,34 +2328,34 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) if (di->dqb_valid & QIF_SPACE) { dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; check_blim = 1; - __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); + set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); } if (di->dqb_valid & QIF_BLIMITS) { dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); check_blim = 1; - __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); + set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); } if (di->dqb_valid & QIF_INODES) { dm->dqb_curinodes = di->dqb_curinodes; check_ilim = 1; - __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); + set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); } if (di->dqb_valid & QIF_ILIMITS) { dm->dqb_isoftlimit = di->dqb_isoftlimit; dm->dqb_ihardlimit = di->dqb_ihardlimit; check_ilim = 1; - __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); + set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); } if (di->dqb_valid & QIF_BTIME) { dm->dqb_btime = di->dqb_btime; check_blim = 1; - __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); + set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); } if (di->dqb_valid & QIF_ITIME) { dm->dqb_itime = di->dqb_itime; check_ilim = 1; - __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); + set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); } if (check_blim) { -- cgit v1.1 From f5b066287c74b624583b993395a65d03a6487b3a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 12 Apr 2010 14:24:28 -0700 Subject: ceph: fix dentry reference leak in dcache readdir When filldir returned an error (e.g. buffer full for a large directory), we would leak a dentry reference, causing an oops on umount. Signed-off-by: Sage Weil --- fs/ceph/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index aed8fda..7505b4f1 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -170,11 +170,11 @@ more: spin_lock(&inode->i_lock); spin_lock(&dcache_lock); + last = dentry; + if (err < 0) goto out_unlock; - last = dentry; - p = p->prev; filp->f_pos++; -- cgit v1.1 From d0e9fe1758f222f13ec893f856552d81a10d266d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 10 Apr 2010 10:36:19 -0700 Subject: Simplify and comment on anon_vma re-use for anon_vma_prepare() This changes the anon_vma reuse case to require that we only reuse simple anon_vma's - ie the case when the vma only has a single anon_vma associated with it. This means that a reuse of an anon_vma from an adjacent vma will always guarantee that both vma's are associated not only with the same anon_vma, they will also have the same anon_vma chain (of just a single entry in this case). And since anon_vma re-use was the only case where the same anon_vma might be associated with different chains of anon_vma's, we now have the case that every vma that shares the same anon_vma will always also have the same chain. That makes it much easier to think about merging vma's that share the same anon_vma's: you can always just drop the other anon_vma chain in anon_vma_merge() since you know that they are always identical. This also splits up the function to validate the anon_vma re-use, and adds a lot of commentary about the possible races. Reviewed-by: Rik van Riel Acked-by: Johannes Weiner Tested-by: Borislav Petkov [ "That didn't fix it" ] Signed-off-by: Linus Torvalds --- mm/mmap.c | 86 +++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 75557c6..acb023e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -825,6 +825,61 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, } /* + * Rough compatbility check to quickly see if it's even worth looking + * at sharing an anon_vma. + * + * They need to have the same vm_file, and the flags can only differ + * in things that mprotect may change. + * + * NOTE! The fact that we share an anon_vma doesn't _have_ to mean that + * we can merge the two vma's. For example, we refuse to merge a vma if + * there is a vm_ops->close() function, because that indicates that the + * driver is doing some kind of reference counting. But that doesn't + * really matter for the anon_vma sharing case. + */ +static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *b) +{ + return a->vm_end == b->vm_start && + mpol_equal(vma_policy(a), vma_policy(b)) && + a->vm_file == b->vm_file && + !((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC)) && + b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT); +} + +/* + * Do some basic sanity checking to see if we can re-use the anon_vma + * from 'old'. The 'a'/'b' vma's are in VM order - one of them will be + * the same as 'old', the other will be the new one that is trying + * to share the anon_vma. + * + * NOTE! This runs with mm_sem held for reading, so it is possible that + * the anon_vma of 'old' is concurrently in the process of being set up + * by another page fault trying to merge _that_. But that's ok: if it + * is being set up, that automatically means that it will be a singleton + * acceptable for merging, so we can do all of this optimistically. But + * we do that ACCESS_ONCE() to make sure that we never re-load the pointer. + * + * IOW: that the "list_is_singular()" test on the anon_vma_chain only + * matters for the 'stable anon_vma' case (ie the thing we want to avoid + * is to return an anon_vma that is "complex" due to having gone through + * a fork). + * + * We also make sure that the two vma's are compatible (adjacent, + * and with the same memory policies). That's all stable, even with just + * a read lock on the mm_sem. + */ +static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_area_struct *a, struct vm_area_struct *b) +{ + if (anon_vma_compatible(a, b)) { + struct anon_vma *anon_vma = ACCESS_ONCE(old->anon_vma); + + if (anon_vma && list_is_singular(&old->anon_vma_chain)) + return anon_vma; + } + return NULL; +} + +/* * find_mergeable_anon_vma is used by anon_vma_prepare, to check * neighbouring vmas for a suitable anon_vma, before it goes off * to allocate a new anon_vma. It checks because a repetitive @@ -834,28 +889,16 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, */ struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma) { + struct anon_vma *anon_vma; struct vm_area_struct *near; - unsigned long vm_flags; near = vma->vm_next; if (!near) goto try_prev; - /* - * Since only mprotect tries to remerge vmas, match flags - * which might be mprotected into each other later on. - * Neither mlock nor madvise tries to remerge at present, - * so leave their flags as obstructing a merge. - */ - vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC); - vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC); - - if (near->anon_vma && vma->vm_end == near->vm_start && - mpol_equal(vma_policy(vma), vma_policy(near)) && - can_vma_merge_before(near, vm_flags, - NULL, vma->vm_file, vma->vm_pgoff + - ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT))) - return near->anon_vma; + anon_vma = reusable_anon_vma(near, vma, near); + if (anon_vma) + return anon_vma; try_prev: /* * It is potentially slow to have to call find_vma_prev here. @@ -868,14 +911,9 @@ try_prev: if (!near) goto none; - vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC); - vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC); - - if (near->anon_vma && near->vm_end == vma->vm_start && - mpol_equal(vma_policy(near), vma_policy(vma)) && - can_vma_merge_after(near, vm_flags, - NULL, vma->vm_file, vma->vm_pgoff)) - return near->anon_vma; + anon_vma = reusable_anon_vma(near, near, vma); + if (anon_vma) + return anon_vma; none: /* * There's no absolute need to look only at touching neighbours: -- cgit v1.1 From 287d97ac032136724143cde8d5964b414d562ee3 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 10 Apr 2010 15:22:30 -0700 Subject: vma_adjust: fix the copying of anon_vma chains When we move the boundaries between two vma's due to things like mprotect, we need to make sure that the anon_vma of the pages that got moved from one vma to another gets properly copied around. And that was not always the case, in this rather hard-to-follow code sequence. Clarify the code, and fix it so that it copies the anon_vma from the right source. Reviewed-by: Rik van Riel Acked-by: Johannes Weiner Tested-by: Borislav Petkov [ "Yeah, not so much this one either" ] Signed-off-by: Linus Torvalds --- mm/mmap.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index acb023e..f90ea92 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -507,11 +507,12 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start, struct address_space *mapping = NULL; struct prio_tree_root *root = NULL; struct file *file = vma->vm_file; - struct anon_vma *anon_vma = NULL; long adjust_next = 0; int remove_next = 0; if (next && !insert) { + struct vm_area_struct *exporter = NULL; + if (end >= next->vm_end) { /* * vma expands, overlapping all the next, and @@ -519,7 +520,7 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start, */ again: remove_next = 1 + (end > next->vm_end); end = next->vm_end; - anon_vma = next->anon_vma; + exporter = next; importer = vma; } else if (end > next->vm_start) { /* @@ -527,7 +528,7 @@ again: remove_next = 1 + (end > next->vm_end); * mprotect case 5 shifting the boundary up. */ adjust_next = (end - next->vm_start) >> PAGE_SHIFT; - anon_vma = next->anon_vma; + exporter = next; importer = vma; } else if (end < vma->vm_end) { /* @@ -536,28 +537,19 @@ again: remove_next = 1 + (end > next->vm_end); * mprotect case 4 shifting the boundary down. */ adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT); - anon_vma = next->anon_vma; + exporter = vma; importer = next; } - } - /* - * When changing only vma->vm_end, we don't really need anon_vma lock. - */ - if (vma->anon_vma && (insert || importer || start != vma->vm_start)) - anon_vma = vma->anon_vma; - if (anon_vma) { /* * Easily overlooked: when mprotect shifts the boundary, * make sure the expanding vma has anon_vma set if the * shrinking vma had, to cover any anon pages imported. */ - if (importer && !importer->anon_vma) { - /* Block reverse map lookups until things are set up. */ - if (anon_vma_clone(importer, vma)) { + if (exporter && exporter->anon_vma && !importer->anon_vma) { + if (anon_vma_clone(importer, exporter)) return -ENOMEM; - } - importer->anon_vma = anon_vma; + importer->anon_vma = exporter->anon_vma; } } -- cgit v1.1 From 646d87b481dab4ba8301716600dfd276605b0ab0 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 11 Apr 2010 17:15:03 -0700 Subject: anon_vma: clone the anon_vma chain in the right order We want to walk the chain in reverse order when cloning it, so that the order of the result chain will be the same as the order in the source chain. When we add entries to the chain, they go at the head of the chain, so we want to add the source head last. Reviewed-by: Rik van Riel Acked-by: Johannes Weiner Tested-by: Borislav Petkov [ "No, it still oopses" ] Signed-off-by: Linus Torvalds --- mm/rmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/rmap.c b/mm/rmap.c index eaa7a09..ee97d38 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -182,7 +182,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) { struct anon_vma_chain *avc, *pavc; - list_for_each_entry(pavc, &src->anon_vma_chain, same_vma) { + list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) { avc = anon_vma_chain_alloc(); if (!avc) goto enomem_failure; -- cgit v1.1 From ea90002b0fa7bdee86ec22eba1d951f30bf043a6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 12 Apr 2010 12:44:29 -0700 Subject: anonvma: when setting up page->mapping, we need to pick the _oldest_ anonvma Otherwise we might be mapping in a page in a new mapping, but that page (through the swapcache) would later be mapped into an old mapping too. The page->mapping must be the case that works for everybody, not just the mapping that happened to page it in first. Here's the scenario: - page gets allocated/mapped by process A. Let's call the anon_vma we associate the page with 'A' to keep it easy to track. - Process A forks, creating process B. The anon_vma in B is 'B', and has a chain that looks like 'B' -> 'A'. Everything is fine. - Swapping happens. The page (with mapping pointing to 'A') gets swapped out (perhaps not to disk - it's enough to assume that it's just not mapped any more, and lives entirely in the swap-cache) - Process B pages it in, which goes like this: do_swap_page -> page = lookup_swap_cache(entry); ... set_pte_at(mm, address, page_table, pte); page_add_anon_rmap(page, vma, address); And think about what happens here! In particular, what happens is that this will now be the "first" mapping of that page, so page_add_anon_rmap() used to do if (first) __page_set_anon_rmap(page, vma, address); and notice what anon_vma it will use? It will use the anon_vma for process B! What happens then? Trivial: process 'A' also pages it in (nothing happens, it's not the first mapping), and then process 'B' execve's or exits or unmaps, making anon_vma B go away. End result: process A has a page that points to anon_vma B, but anon_vma B does not exist any more. This can go on forever. Forget about RCU grace periods, forget about locking, forget anything like that. The bug is simply that page->mapping points to an anon_vma that was correct at one point, but was _not_ the one that was shared by all users of that possible mapping. Changing it to always use the deepest anon_vma in the anonvma chain gets us to the safest model. This can be improved in certain cases: if we know the page is private to just this particular mapping (for example, it's a new page, or it is the only swapcache entry), we could pick the top (most specific) anon_vma. But that's a future optimization. Make it _work_ reliably first. Reviewed-by: Rik van Riel Acked-by: Johannes Weiner Tested-by: Borislav Petkov [ "What do you know, I think you fixed it!" ] Signed-off-by: Linus Torvalds --- mm/rmap.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index ee97d38..4bad326 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -734,9 +734,20 @@ void page_move_anon_rmap(struct page *page, static void __page_set_anon_rmap(struct page *page, struct vm_area_struct *vma, unsigned long address) { - struct anon_vma *anon_vma = vma->anon_vma; + struct anon_vma_chain *avc; + struct anon_vma *anon_vma; + + BUG_ON(!vma->anon_vma); + + /* + * We must use the _oldest_ possible anon_vma for the page mapping! + * + * So take the last AVC chain entry in the vma, which is the deepest + * ancestor, and use the anon_vma from that. + */ + avc = list_entry(vma->anon_vma_chain.prev, struct anon_vma_chain, same_vma); + anon_vma = avc->anon_vma; - BUG_ON(!anon_vma); anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; page->mapping = (struct address_space *) anon_vma; page->index = linear_page_index(vma, address); -- cgit v1.1 From 0d0fb0f9c5fddef4a10242fe3337f00f528a3099 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 12 Apr 2010 18:41:35 -0700 Subject: Linux 2.6.34-rc4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 67c1001..9754615 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 34 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* -- cgit v1.1 From cb256aa60409efd803806cfb0528a4b3f8397dba Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 12 Apr 2010 22:16:22 -0700 Subject: sparc64: Use kstack_valid() in die_if_kernel(). This gets rid of a local function (is_kernel_stack()) which tries to do the same thing, yet poorly in that it doesn't handle IRQ stacks properly. Signed-off-by: David S. Miller --- arch/sparc/kernel/traps_64.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index bdc05a2..2ff178c 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -2202,27 +2202,6 @@ void dump_stack(void) EXPORT_SYMBOL(dump_stack); -static inline int is_kernel_stack(struct task_struct *task, - struct reg_window *rw) -{ - unsigned long rw_addr = (unsigned long) rw; - unsigned long thread_base, thread_end; - - if (rw_addr < PAGE_OFFSET) { - if (task != &init_task) - return 0; - } - - thread_base = (unsigned long) task_stack_page(task); - thread_end = thread_base + sizeof(union thread_union); - if (rw_addr >= thread_base && - rw_addr < thread_end && - !(rw_addr & 0x7UL)) - return 1; - - return 0; -} - static inline struct reg_window *kernel_stack_up(struct reg_window *rw) { unsigned long fp = rw->ins[6]; @@ -2251,6 +2230,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) show_regs(regs); add_taint(TAINT_DIE); if (regs->tstate & TSTATE_PRIV) { + struct thread_info *tp = current_thread_info(); struct reg_window *rw = (struct reg_window *) (regs->u_regs[UREG_FP] + STACK_BIAS); @@ -2258,8 +2238,8 @@ void die_if_kernel(char *str, struct pt_regs *regs) * find some badly aligned kernel stack. */ while (rw && - count++ < 30&& - is_kernel_stack(current, rw)) { + count++ < 30 && + kstack_valid(tp, (unsigned long) rw)) { printk("Caller[%016lx]: %pS\n", rw->ins[7], (void *) rw->ins[7]); -- cgit v1.1 From 0c25e9e6cbe7b233bb91d14d0e2c258bf8e6ec83 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 12 Apr 2010 22:21:52 -0700 Subject: sparc64: Adjust __raw_local_irq_save() to cooperate in NMIs. If we are in an NMI then doing a plain raw_local_irq_disable() will write PIL_NORMAL_MAX into %pil, which is lower than PIL_NMI, and thus we'll re-enable NMIs and recurse. Doing a simple: %pil = %pil | PIL_NORMAL_MAX does what we want, if we're already at PIL_NMI (15) we leave it at that setting, else we set it to PIL_NORMAL_MAX (14). This should get the function tracer working on sparc64. Signed-off-by: David S. Miller --- arch/sparc/include/asm/irqflags_64.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h index 8b49bf9..a16e94c 100644 --- a/arch/sparc/include/asm/irqflags_64.h +++ b/arch/sparc/include/asm/irqflags_64.h @@ -76,9 +76,19 @@ static inline int raw_irqs_disabled(void) */ static inline unsigned long __raw_local_irq_save(void) { - unsigned long flags = __raw_local_save_flags(); + unsigned long flags, tmp; - raw_local_irq_disable(); + /* Disable interrupts to PIL_NORMAL_MAX unless we already + * are using PIL_NMI, in which case PIL_NMI is retained. + */ + __asm__ __volatile__( + "rdpr %%pil, %0\n\t" + "or %0, %2, %1\n\t" + "wrpr %1, 0x0, %%pil" + : "=r" (flags), "=r" (tmp) + : "i" (PIL_NORMAL_MAX) + : "memory" + ); return flags; } -- cgit v1.1 From 63b754957371c23b7515399a977a2e1d361a036c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 12 Apr 2010 22:35:24 -0700 Subject: sparc64: Add HAVE_FUNCTION_TRACE_MCOUNT_TEST and tidy up. Check function_trace_stop at ftrace_caller Toss mcount_call and dummy call of ftrace_stub, unnecessary. Document problems we'll have if the final kernel image link ever turns on relaxation. Properly size 'ftrace_call' so it looks right when inspecting instructions under gdb et al. Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 1 + arch/sparc/lib/mcount.S | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 6db5136..035304c 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -37,6 +37,7 @@ config SPARC64 def_bool 64BIT select ARCH_SUPPORTS_MSI select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_KRETPROBES select HAVE_KPROBES select HAVE_LMB diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S index 24b8b12..7047997 100644 --- a/arch/sparc/lib/mcount.S +++ b/arch/sparc/lib/mcount.S @@ -96,13 +96,12 @@ mcount: #endif #ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE - mov %o7, %o0 - .globl mcount_call -mcount_call: - call ftrace_stub - mov %o0, %o7 + /* Do nothing, the retl/nop below is all we need. */ #else - sethi %hi(ftrace_trace_function), %g1 + sethi %hi(function_trace_stop), %g1 + lduw [%g1 + %lo(function_trace_stop)], %g2 + brnz,pn %g2, 1f + sethi %hi(ftrace_trace_function), %g1 sethi %hi(ftrace_stub), %g2 ldx [%g1 + %lo(ftrace_trace_function)], %g1 or %g2, %lo(ftrace_stub), %g2 @@ -131,14 +130,23 @@ ftrace_stub: .globl ftrace_caller .type ftrace_caller,#function ftrace_caller: + sethi %hi(function_trace_stop), %g1 mov %i7, %o1 - mov %o7, %o0 + lduw [%g1 + %lo(function_trace_stop)], %g2 + brnz,pn %g2, ftrace_stub + mov %o7, %o0 .globl ftrace_call ftrace_call: + /* If the final kernel link ever turns on relaxation, we'll need + * to do something about this tail call. Otherwise the linker + * will rewrite the call into a branch and nop out the move + * instruction. + */ call ftrace_stub mov %o0, %o7 retl nop + .size ftrace_call,.-ftrace_call .size ftrace_caller,.-ftrace_caller #endif #endif -- cgit v1.1 From ddacd0bc70fe724eba2b5967dd5b68e10d41486c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 12 Apr 2010 22:36:03 -0700 Subject: sparc64: Kill CONFIG_STACK_DEBUG code. The generic stack tracer does this job just as well. Signed-off-by: David S. Miller --- arch/sparc/Kconfig.debug | 5 +--- arch/sparc/lib/mcount.S | 74 ------------------------------------------------ 2 files changed, 1 insertion(+), 78 deletions(-) diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug index 9d3c889..1b4a831 100644 --- a/arch/sparc/Kconfig.debug +++ b/arch/sparc/Kconfig.debug @@ -19,13 +19,10 @@ config DEBUG_DCFLUSH bool "D-cache flush debugging" depends on SPARC64 && DEBUG_KERNEL -config STACK_DEBUG - bool "Stack Overflow Detection Support" - config MCOUNT bool depends on SPARC64 - depends on STACK_DEBUG || FUNCTION_TRACER + depends on FUNCTION_TRACER default y config FRAME_POINTER diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S index 7047997..73ed0f3 100644 --- a/arch/sparc/lib/mcount.S +++ b/arch/sparc/lib/mcount.S @@ -7,26 +7,11 @@ #include -#include -#include - /* * This is the main variant and is called by C code. GCC's -pg option * automatically instruments every C function with a call to this. */ -#ifdef CONFIG_STACK_DEBUG - -#define OVSTACKSIZE 4096 /* lets hope this is enough */ - - .data - .align 8 -panicstring: - .asciz "Stack overflow\n" - .align 8 -ovstack: - .skip OVSTACKSIZE -#endif .text .align 32 .globl _mcount @@ -35,65 +20,6 @@ ovstack: .type mcount,#function _mcount: mcount: -#ifdef CONFIG_STACK_DEBUG - /* - * Check whether %sp is dangerously low. - */ - ldub [%g6 + TI_FPDEPTH], %g1 - srl %g1, 1, %g3 - add %g3, 1, %g3 - sllx %g3, 8, %g3 ! each fpregs frame is 256b - add %g3, 192, %g3 - add %g6, %g3, %g3 ! where does task_struct+frame end? - sub %g3, STACK_BIAS, %g3 - cmp %sp, %g3 - bg,pt %xcc, 1f - nop - lduh [%g6 + TI_CPU], %g1 - sethi %hi(hardirq_stack), %g3 - or %g3, %lo(hardirq_stack), %g3 - sllx %g1, 3, %g1 - ldx [%g3 + %g1], %g7 - sub %g7, STACK_BIAS, %g7 - cmp %sp, %g7 - bleu,pt %xcc, 2f - sethi %hi(THREAD_SIZE), %g3 - add %g7, %g3, %g7 - cmp %sp, %g7 - blu,pn %xcc, 1f -2: sethi %hi(softirq_stack), %g3 - or %g3, %lo(softirq_stack), %g3 - ldx [%g3 + %g1], %g7 - sub %g7, STACK_BIAS, %g7 - cmp %sp, %g7 - bleu,pt %xcc, 3f - sethi %hi(THREAD_SIZE), %g3 - add %g7, %g3, %g7 - cmp %sp, %g7 - blu,pn %xcc, 1f - nop - /* If we are already on ovstack, don't hop onto it - * again, we are already trying to output the stack overflow - * message. - */ -3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough - or %g7, %lo(ovstack), %g7 - add %g7, OVSTACKSIZE, %g3 - sub %g3, STACK_BIAS + 192, %g3 - sub %g7, STACK_BIAS, %g7 - cmp %sp, %g7 - blu,pn %xcc, 2f - cmp %sp, %g3 - bleu,pn %xcc, 1f - nop -2: mov %g3, %sp - sethi %hi(panicstring), %g3 - call prom_printf - or %g3, %lo(panicstring), %o0 - call prom_halt - nop -1: -#endif #ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE /* Do nothing, the retl/nop below is all we need. */ -- cgit v1.1 From d96478d5a2dcfa3aba1ca4d71b07fef62b27d9c8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 6 Apr 2010 17:32:08 -0700 Subject: sparc64: Kill unnecessary static on local var in ftrace_call_replace(). Signed-off-by: David S. Miller --- arch/sparc/kernel/ftrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c index 9103a56..2ea6e4f 100644 --- a/arch/sparc/kernel/ftrace.c +++ b/arch/sparc/kernel/ftrace.c @@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000; static u32 ftrace_call_replace(unsigned long ip, unsigned long addr) { - static u32 call; + u32 call; s32 off; off = ((s32)addr - (s32)ip); -- cgit v1.1 From f8e8a8e8cba3359df2a16c17d59eedb08adf3b43 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 6 Apr 2010 17:34:15 -0700 Subject: sparc64: Remove profiling from some low-level bits. These include the timer implementation, perf events support, and the performance counter register (pcr) programming layer. Signed-off-by: David S. Miller --- arch/sparc/kernel/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index c631614..1b35ed6 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -13,6 +13,14 @@ extra-y += init_task.o CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS) extra-y += vmlinux.lds +ifdef CONFIG_FUNCTION_TRACER +# Do not profile debug and lowlevel utilities +CFLAGS_REMOVE_ftrace.o := -pg +CFLAGS_REMOVE_time_$(BITS).o := -pg +CFLAGS_REMOVE_perf_event.o := -pg +CFLAGS_REMOVE_pcr.o := -pg +endif + obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o obj-$(CONFIG_SPARC32) += etrap_32.o obj-$(CONFIG_SPARC32) += rtrap_32.o @@ -85,7 +93,6 @@ obj-$(CONFIG_KGDB) += kgdb_$(BITS).o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -CFLAGS_REMOVE_ftrace.o := -pg obj-$(CONFIG_EARLYFB) += btext.o obj-$(CONFIG_STACKTRACE) += stacktrace.o -- cgit v1.1 From daecbf58a509bc27c112647e825df763c3e3b0f4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 6 Apr 2010 17:38:52 -0700 Subject: sparc64: Use a seperate counter for timer interrupts and NMI checks, like x86. This keeps us from having to use kstat_irqs_cpu() from the NMI handler, the former of which is a profiled function. Instead we use a currently empty slot in the cpu_data Signed-off-by: David S. Miller --- arch/sparc/include/asm/cpudata_64.h | 2 +- arch/sparc/kernel/nmi.c | 3 +-- arch/sparc/kernel/time_64.c | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h index 926397d..050ef35 100644 --- a/arch/sparc/include/asm/cpudata_64.h +++ b/arch/sparc/include/asm/cpudata_64.h @@ -17,7 +17,7 @@ typedef struct { unsigned int __nmi_count; unsigned long clock_tick; /* %tick's per second */ unsigned long __pad; - unsigned int __pad1; + unsigned int irq0_irqs; unsigned int __pad2; /* Dcache line 2, rarely used */ diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index b287b62..75a3d1a 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c @@ -92,7 +92,6 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) { unsigned int sum, touched = 0; - int cpu = smp_processor_id(); clear_softint(1 << irq); @@ -106,7 +105,7 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) else pcr_ops->write(PCR_PIC_PRIV); - sum = kstat_irqs_cpu(0, cpu); + sum = local_cpu_data().irq0_irqs; if (__get_cpu_var(nmi_touch)) { __get_cpu_var(nmi_touch) = 0; touched = 1; diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 67e1651..f25858e 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -728,6 +728,7 @@ void timer_interrupt(int irq, struct pt_regs *regs) irq_enter(); + local_cpu_data().irq0_irqs++; kstat_incr_irqs_this_cpu(0, irq_to_desc(0)); if (unlikely(!evt->event_handler)) { -- cgit v1.1 From a71d1d6bb1b26e566e5c06c37857f4cdc1664780 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 6 Apr 2010 19:59:46 -0700 Subject: sparc64: Give a stack frame to the ftrace call sites. It's the only way we'll be able to implement the function graph tracer properly. A positive is that we no longer have to worry about the linker over-optimizing the tail call, since we don't use a tail call any more. Signed-off-by: David S. Miller --- arch/sparc/lib/mcount.S | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S index 73ed0f3..153c80e 100644 --- a/arch/sparc/lib/mcount.S +++ b/arch/sparc/lib/mcount.S @@ -33,9 +33,13 @@ mcount: or %g2, %lo(ftrace_stub), %g2 cmp %g1, %g2 be,pn %icc, 1f - mov %i7, %o1 - jmpl %g1, %g0 - mov %o7, %o0 + mov %i7, %g2 + save %sp, -128, %sp + mov %g2, %o1 + jmpl %g1, %o7 + mov %i7, %o0 + ret + restore /* not reached */ 1: #endif @@ -57,21 +61,18 @@ ftrace_stub: .type ftrace_caller,#function ftrace_caller: sethi %hi(function_trace_stop), %g1 - mov %i7, %o1 - lduw [%g1 + %lo(function_trace_stop)], %g2 - brnz,pn %g2, ftrace_stub - mov %o7, %o0 + mov %i7, %g2 + lduw [%g1 + %lo(function_trace_stop)], %g3 + brnz,pn %g3, ftrace_stub + nop + save %sp, -128, %sp + mov %g2, %o1 .globl ftrace_call ftrace_call: - /* If the final kernel link ever turns on relaxation, we'll need - * to do something about this tail call. Otherwise the linker - * will rewrite the call into a branch and nop out the move - * instruction. - */ call ftrace_stub - mov %o0, %o7 - retl - nop + mov %i7, %o0 + ret + restore .size ftrace_call,.-ftrace_call .size ftrace_caller,.-ftrace_caller #endif -- cgit v1.1 From 9960e9e8944f9b1ca6af5f7d26400ca45b429600 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 7 Apr 2010 04:41:33 -0700 Subject: sparc64: Add function graph tracer support. Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 2 ++ arch/sparc/kernel/Makefile | 1 + arch/sparc/kernel/ftrace.c | 58 ++++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/irq_64.c | 3 +- arch/sparc/kernel/kgdb_64.c | 3 +- arch/sparc/kernel/pcr.c | 3 +- arch/sparc/kernel/smp_64.c | 11 ++++---- arch/sparc/kernel/time_64.c | 3 +- arch/sparc/kernel/vmlinux.lds.S | 1 + arch/sparc/lib/mcount.S | 62 +++++++++++++++++++++++++++++++++++++---- 10 files changed, 132 insertions(+), 15 deletions(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 035304c..9908d47 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -37,6 +37,8 @@ config SPARC64 def_bool 64BIT select ARCH_SUPPORTS_MSI select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_FUNCTION_GRAPH_FP_TEST select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_KRETPROBES select HAVE_KPROBES diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 1b35ed6..0c2dc1f 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -93,6 +93,7 @@ obj-$(CONFIG_KGDB) += kgdb_$(BITS).o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o +obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_EARLYFB) += btext.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c index 2ea6e4f..03ab022 100644 --- a/arch/sparc/kernel/ftrace.c +++ b/arch/sparc/kernel/ftrace.c @@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data) return 0; } #endif + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + +#ifdef CONFIG_DYNAMIC_FTRACE +extern void ftrace_graph_call(void); + +int ftrace_enable_ftrace_graph_caller(void) +{ + unsigned long ip = (unsigned long)(&ftrace_graph_call); + u32 old, new; + + old = *(u32 *) &ftrace_graph_call; + new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller); + return ftrace_modify_code(ip, old, new); +} + +int ftrace_disable_ftrace_graph_caller(void) +{ + unsigned long ip = (unsigned long)(&ftrace_graph_call); + u32 old, new; + + old = *(u32 *) &ftrace_graph_call; + new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub); + + return ftrace_modify_code(ip, old, new); +} + +#endif /* !CONFIG_DYNAMIC_FTRACE */ + +/* + * Hook the return address and push it in the stack of return addrs + * in current thread info. + */ +unsigned long prepare_ftrace_return(unsigned long parent, + unsigned long self_addr, + unsigned long frame_pointer) +{ + unsigned long return_hooker = (unsigned long) &return_to_handler; + struct ftrace_graph_ent trace; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return parent + 8UL; + + if (ftrace_push_return_trace(parent, self_addr, &trace.depth, + frame_pointer) == -EBUSY) + return parent + 8UL; + + trace.func = self_addr; + + /* Only trace if the calling function expects to */ + if (!ftrace_graph_entry(&trace)) { + current->curr_ret_stack--; + return parent + 8UL; + } + + return return_hooker; +} +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index e1cbdb9..af5c76c 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -721,7 +722,7 @@ static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); } -void handler_irq(int irq, struct pt_regs *regs) +void __irq_entry handler_irq(int irq, struct pt_regs *regs) { unsigned long pstate, bucket_pa; struct pt_regs *old_regs; diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index f5a0fd4..0a2bd0f 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) } #ifdef CONFIG_SMP -void smp_kgdb_capture_client(int irq, struct pt_regs *regs) +void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs) { unsigned long flags; diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index 2d94e7a..c4a6a50 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -34,7 +35,7 @@ unsigned int picl_shift; * Therefore in such situations we defer the work by signalling * a lower level cpu IRQ. */ -void deferred_pcr_work_irq(int irq, struct pt_regs *regs) +void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs) { struct pt_regs *old_regs; diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index eb14844..1011fbf 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -822,13 +823,13 @@ void arch_send_call_function_single_ipi(int cpu) &cpumask_of_cpu(cpu)); } -void smp_call_function_client(int irq, struct pt_regs *regs) +void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs) { clear_softint(1 << irq); generic_smp_call_function_interrupt(); } -void smp_call_function_single_client(int irq, struct pt_regs *regs) +void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs) { clear_softint(1 << irq); generic_smp_call_function_single_interrupt(); @@ -964,7 +965,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page) put_cpu(); } -void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) +void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) { struct mm_struct *mm; unsigned long flags; @@ -1148,7 +1149,7 @@ void smp_release(void) */ extern void prom_world(int); -void smp_penguin_jailcell(int irq, struct pt_regs *regs) +void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs) { clear_softint(1 << irq); @@ -1364,7 +1365,7 @@ void smp_send_reschedule(int cpu) &cpumask_of_cpu(cpu)); } -void smp_receive_signal_client(int irq, struct pt_regs *regs) +void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) { clear_softint(1 << irq); } diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index f25858e..c7bbe6cf 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -717,7 +718,7 @@ static struct clock_event_device sparc64_clockevent = { }; static DEFINE_PER_CPU(struct clock_event_device, sparc64_events); -void timer_interrupt(int irq, struct pt_regs *regs) +void __irq_entry timer_interrupt(int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); unsigned long tick_mask = tick_ops->softint_mask; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 4e59925..c4f5758 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -46,6 +46,7 @@ SECTIONS SCHED_TEXT LOCK_TEXT KPROBES_TEXT + IRQENTRY_TEXT *(.gnu.warning) } = 0 _etext = .; diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S index 153c80e..3753e3c 100644 --- a/arch/sparc/lib/mcount.S +++ b/arch/sparc/lib/mcount.S @@ -26,22 +26,42 @@ mcount: #else sethi %hi(function_trace_stop), %g1 lduw [%g1 + %lo(function_trace_stop)], %g2 - brnz,pn %g2, 1f + brnz,pn %g2, 2f sethi %hi(ftrace_trace_function), %g1 sethi %hi(ftrace_stub), %g2 ldx [%g1 + %lo(ftrace_trace_function)], %g1 or %g2, %lo(ftrace_stub), %g2 cmp %g1, %g2 be,pn %icc, 1f - mov %i7, %g2 + mov %i7, %g3 save %sp, -128, %sp - mov %g2, %o1 + mov %g3, %o1 jmpl %g1, %o7 mov %i7, %o0 ret restore /* not reached */ 1: +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + sethi %hi(ftrace_graph_return), %g1 + ldx [%g1 + %lo(ftrace_graph_return)], %g3 + cmp %g2, %g3 + bne,pn %xcc, 5f + sethi %hi(ftrace_graph_entry_stub), %g2 + sethi %hi(ftrace_graph_entry), %g1 + or %g2, %lo(ftrace_graph_entry_stub), %g2 + ldx [%g1 + %lo(ftrace_graph_entry)], %g1 + cmp %g1, %g2 + be,pt %xcc, 2f + nop +5: mov %i7, %g2 + mov %fp, %g3 + save %sp, -128, %sp + mov %g2, %l0 + ba,pt %xcc, ftrace_graph_caller + mov %g3, %l1 +#endif +2: #endif #endif retl @@ -62,18 +82,48 @@ ftrace_stub: ftrace_caller: sethi %hi(function_trace_stop), %g1 mov %i7, %g2 - lduw [%g1 + %lo(function_trace_stop)], %g3 - brnz,pn %g3, ftrace_stub - nop + lduw [%g1 + %lo(function_trace_stop)], %g1 + brnz,pn %g1, ftrace_stub + mov %fp, %g3 save %sp, -128, %sp mov %g2, %o1 + mov %g2, %l0 + mov %g3, %l1 .globl ftrace_call ftrace_call: call ftrace_stub mov %i7, %o0 +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + .globl ftrace_graph_call +ftrace_graph_call: + call ftrace_stub + nop +#endif ret restore +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + .size ftrace_graph_call,.-ftrace_graph_call +#endif .size ftrace_call,.-ftrace_call .size ftrace_caller,.-ftrace_caller #endif #endif + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +ENTRY(ftrace_graph_caller) + mov %l0, %o0 + mov %i7, %o1 + call prepare_ftrace_return + mov %l1, %o2 + ret + restore %o0, -8, %i7 +END(ftrace_graph_caller) + +ENTRY(return_to_handler) + save %sp, -128, %sp + call ftrace_return_to_handler + mov %fp, %o0 + jmpl %o0 + 8, %g0 + restore +END(return_to_handler) +#endif -- cgit v1.1 From 8b8d8e2840a440d62e8dc0ef36ba433b26f70d32 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 9 Apr 2010 00:14:35 -0700 Subject: sparc64: Support kmemleak. Only missing thing was an _sdata marker in vmlinux.lds.S Signed-off-by: David S. Miller --- arch/sparc/kernel/vmlinux.lds.S | 4 ++++ lib/Kconfig.debug | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index c4f5758..0c1e678 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -52,6 +52,10 @@ SECTIONS _etext = .; RO_DATA(PAGE_SIZE) + + /* Start of data section */ + _sdata = .; + .data1 : { *(.data1) } diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1fafb4b..6c2be60 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -356,7 +356,7 @@ config SLUB_STATS config DEBUG_KMEMLEAK bool "Kernel memory leak detector" depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ - (X86 || ARM || PPC || S390 || SUPERH) + (X86 || ARM || PPC || S390 || SPARC64 || SUPERH) select DEBUG_FS if SYSFS select STACKTRACE if STACKTRACE_SUPPORT -- cgit v1.1 From 25ad403f67d7673f38a473ec138d240804785ae3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 10 Apr 2010 20:24:22 -0700 Subject: sparc64: Add kmemleak annotation to sun4v_build_virq() The only reference we store to this memory is in the form of a physical address, so kmemleak can't see it. Add a kmemleak_not_leak() annotation. It's probably useful to be able to look at a dump of these things either via debugfs or similar, and thus we could at some point store them in some kind of table and therefore get rid of this annotation. Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_64.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index af5c76c..454ce3a 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -648,6 +648,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); if (unlikely(!bucket)) return 0; + + /* The only reference we store to the IRQ bucket is + * by physical address which kmemleak can't see, tell + * it that this object explicitly is not a leak and + * should be scanned. + */ + kmemleak_not_leak(bucket); + __flush_dcache_range((unsigned long) bucket, ((unsigned long) bucket + sizeof(struct ino_bucket))); -- cgit v1.1 From e182c77cc291456eed127b1472952ddb59a81a9d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 10 Apr 2010 20:26:55 -0700 Subject: sparc64: Fix memory leak in pci_register_iommu_region(). Found by kmemleak. If request_resource() fails, we leak the struct resource we allocated to represent the IOMMU mapping area. This actually happens on sun4v machines because the IOMEM area is only reported sans the IOMMU region, unlike all previous systems. I'll need to fix that at some point, but for now fix the leak. Signed-off-by: David S. Miller --- arch/sparc/kernel/pci_common.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index b775658..8a00058 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -371,14 +371,19 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); if (!rp) { - prom_printf("Cannot allocate IOMMU resource.\n"); - prom_halt(); + pr_info("%s: Cannot allocate IOMMU resource.\n", + pbm->name); + return; } rp->name = "IOMMU"; rp->start = pbm->mem_space.start + (unsigned long) vdma[0]; rp->end = rp->start + (unsigned long) vdma[1] - 1UL; rp->flags = IORESOURCE_BUSY; - request_resource(&pbm->mem_space, rp); + if (request_resource(&pbm->mem_space, rp)) { + pr_info("%s: Unable to request IOMMU resource.\n", + pbm->name); + kfree(rp); + } } } -- cgit v1.1 From b68b58fd6a341c2115ff5fb466fe9fc0b581980e Mon Sep 17 00:00:00 2001 From: Philby John Date: Fri, 26 Mar 2010 21:37:51 +0530 Subject: ALSA: aaci - Fix alignment faults on ARM Cortex introduced by commit 29a4f2d3 The commit 29a4f2d3 used writel() at offset 0x26 which is half-word aligned causing unaligned exceptions on a Cortex-A8. The original patch solved the "aaci-pl041 fpga:04: ac97 read back fail" issue on a soft reset. Reading from any arbitrary aaci register seems to solve this issue. Signed-off-by: Philby John Acked-by: Russell King Signed-off-by: Takashi Iwai --- sound/arm/aaci.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 656e474..91acc9a 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci) struct snd_ac97 *ac97; int ret; - writel(0, aaci->base + AC97_POWERDOWN); /* * Assert AACIRESET for 2us */ @@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id) writel(0x1fff, aaci->base + AACI_INTCLR); writel(aaci->maincr, aaci->base + AACI_MAINCR); - + /* + * Fix: ac97 read back fail errors by reading + * from any arbitrary aaci register. + */ + readl(aaci->base + AACI_CSCH1); ret = aaci_probe_ac97(aaci); if (ret) goto out; -- cgit v1.1 From c011f80ba0912486fe51dd2b3f71d9b33a151188 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 13 Apr 2010 01:50:43 -0700 Subject: sparc64: Add some more commentary to __raw_local_irq_save() Suggested by Peter Zijlstra Signed-off-by: David S. Miller --- arch/sparc/include/asm/irqflags_64.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h index a16e94c..bfa1ea4 100644 --- a/arch/sparc/include/asm/irqflags_64.h +++ b/arch/sparc/include/asm/irqflags_64.h @@ -80,6 +80,13 @@ static inline unsigned long __raw_local_irq_save(void) /* Disable interrupts to PIL_NORMAL_MAX unless we already * are using PIL_NMI, in which case PIL_NMI is retained. + * + * The only values we ever program into the %pil are 0, + * PIL_NORMAL_MAX and PIL_NMI. + * + * Since PIL_NMI is the largest %pil value and all bits are + * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX + * actually is. */ __asm__ __volatile__( "rdpr %%pil, %0\n\t" -- cgit v1.1 From fc837c8f0446b73a1661339db406c0238dd1d184 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 13 Apr 2010 11:41:22 -0700 Subject: ceph: queue_cap_snap should always queue dirty context This simplifies the calling convention, and fixes a bug where we queue a capsnap with a context other than i_head_snapc (the one that matches the dirty pages). The result was a BUG at fs/ceph/caps.c:2178 on writeback completion when a capsnap matching the writeback snapc could not be found. Signed-off-by: Sage Weil --- fs/ceph/snap.c | 16 +++++++--------- fs/ceph/super.h | 3 +-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 7e3e5f9..d1974315 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -430,8 +430,7 @@ static int dup_array(u64 **dst, __le64 *src, int num) * Caller must hold snap_rwsem for read (i.e., the realm topology won't * change). */ -void ceph_queue_cap_snap(struct ceph_inode_info *ci, - struct ceph_snap_context *snapc) +void ceph_queue_cap_snap(struct ceph_inode_info *ci) { struct inode *inode = &ci->vfs_inode; struct ceph_cap_snap *capsnap; @@ -450,10 +449,11 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci, as no new writes are allowed to start when pending, so any writes in progress now were started before the previous cap_snap. lucky us. */ - dout("queue_cap_snap %p snapc %p seq %llu used %d" - " already pending\n", inode, snapc, snapc->seq, used); + dout("queue_cap_snap %p already pending\n", inode); kfree(capsnap); } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { + struct ceph_snap_context *snapc = ci->i_head_snapc; + igrab(inode); atomic_set(&capsnap->nref, 1); @@ -462,7 +462,6 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci, INIT_LIST_HEAD(&capsnap->flushing_item); capsnap->follows = snapc->seq - 1; - capsnap->context = ceph_get_snap_context(snapc); capsnap->issued = __ceph_caps_issued(ci, NULL); capsnap->dirty = __ceph_caps_dirty(ci); @@ -479,7 +478,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci, snapshot. */ capsnap->dirty_pages = ci->i_wrbuffer_ref_head; ci->i_wrbuffer_ref_head = 0; - ceph_put_snap_context(ci->i_head_snapc); + capsnap->context = snapc; ci->i_head_snapc = NULL; list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); @@ -603,7 +602,7 @@ more: if (lastinode) iput(lastinode); lastinode = inode; - ceph_queue_cap_snap(ci, realm->cached_context); + ceph_queue_cap_snap(ci); spin_lock(&realm->inodes_with_caps_lock); } spin_unlock(&realm->inodes_with_caps_lock); @@ -825,8 +824,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, spin_unlock(&realm->inodes_with_caps_lock); spin_unlock(&inode->i_lock); - ceph_queue_cap_snap(ci, - ci->i_snap_realm->cached_context); + ceph_queue_cap_snap(ci); iput(inode); continue; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 65d1203..4c07aca 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -714,8 +714,7 @@ extern int ceph_update_snap_trace(struct ceph_mds_client *m, extern void ceph_handle_snap(struct ceph_mds_client *mdsc, struct ceph_mds_session *session, struct ceph_msg *msg); -extern void ceph_queue_cap_snap(struct ceph_inode_info *ci, - struct ceph_snap_context *snapc); +extern void ceph_queue_cap_snap(struct ceph_inode_info *ci); extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci, struct ceph_cap_snap *capsnap); extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc); -- cgit v1.1 From e1e4dd0caa63e166afa46a1ccc947bebb4f66bcf Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 13 Apr 2010 11:45:56 -0700 Subject: ceph: reserve one more caps space when doing readdir We were missing space for the directory cap. The result was a BUG at fs/ceph/caps.c:2178. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil --- fs/ceph/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 7505b4f1..159f588 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -311,7 +311,7 @@ more: req->r_readdir_offset = fi->next_offset; req->r_args.readdir.frag = cpu_to_le32(frag); req->r_args.readdir.max_entries = cpu_to_le32(max_entries); - req->r_num_caps = max_entries; + req->r_num_caps = max_entries + 1; err = ceph_mdsc_do_request(mdsc, NULL, req); if (err < 0) { ceph_mdsc_put_request(req); -- cgit v1.1 From a6a5349d17f2a5c37079826f1a1474c3d08c6b53 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 13 Apr 2010 14:07:07 -0700 Subject: ceph: use separate class for ceph sockets' sk_lock Use a separate class for ceph sockets to prevent lockdep confusion. Because ceph sockets only get passed kernel pointers, there is no dependency from sk_lock -> mmap_sem. If we share the same class as other sockets, lockdep detects a circular dependency from mmap_sem (page fault) -> fs mutex -> sk_lock -> mmap_sem because dependencies are noted from both ceph and user contexts. Using a separate class prevents the sk_lock(ceph) -> mmap_sem dependency and makes lockdep happy. Signed-off-by: Sage Weil --- fs/ceph/messenger.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index f35b494..5c75d5d 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -29,6 +29,10 @@ static char tag_msg = CEPH_MSGR_TAG_MSG; static char tag_ack = CEPH_MSGR_TAG_ACK; static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE; +#ifdef CONFIG_LOCKDEP +static struct lock_class_key socket_class; +#endif + static void queue_con(struct ceph_connection *con); static void con_work(struct work_struct *); @@ -227,6 +231,10 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con) con->sock = sock; sock->sk->sk_allocation = GFP_NOFS; +#ifdef CONFIG_LOCKDEP + lockdep_set_class(&sock->sk->sk_lock, &socket_class); +#endif + set_sock_callbacks(sock, con); dout("connect %s\n", pr_addr(&con->peer_addr.in_addr)); -- cgit v1.1 From 2e2dc1d755cc5609d0c46d47f7d171318b3bffcd Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 13 Apr 2010 14:28:24 -0700 Subject: sparc: Fix forgotten kmemleak headers inclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix forgotten kmemleak headers inclusion for kmemleak_not_leak() declaration. This fixes the following build error: arch/sparc/kernel/irq_64.c: In function ‘sun4v_build_virq’: arch/sparc/kernel/irq_64.c:657: error: implicit declaration of function ‘kmemleak_not_leak’ Signed-off-by: Frederic Weisbecker Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_64.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 454ce3a..2b04c72 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include -- cgit v1.1 From 035df35d968323f6f463c8789553e8589efcbcd4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 13 Apr 2010 18:59:02 -0700 Subject: sparc64: Allocate sufficient stack space in ftrace stubs. 128 bytes is sufficient for the register window save area, but the calling conventions allow the callee to save up to 6 incoming argument registers into the stack frame after the register window save area. This means a minimal stack frame is 176 bytes (128 + (6 * 8)). This fixes random crashes when using the function tracer. Reported-by: Frederic Weisbecker Signed-off-by: David S. Miller --- arch/sparc/lib/mcount.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S index 3753e3c..3ad6cbd 100644 --- a/arch/sparc/lib/mcount.S +++ b/arch/sparc/lib/mcount.S @@ -34,7 +34,7 @@ mcount: cmp %g1, %g2 be,pn %icc, 1f mov %i7, %g3 - save %sp, -128, %sp + save %sp, -176, %sp mov %g3, %o1 jmpl %g1, %o7 mov %i7, %o0 @@ -56,7 +56,7 @@ mcount: nop 5: mov %i7, %g2 mov %fp, %g3 - save %sp, -128, %sp + save %sp, -176, %sp mov %g2, %l0 ba,pt %xcc, ftrace_graph_caller mov %g3, %l1 @@ -85,7 +85,7 @@ ftrace_caller: lduw [%g1 + %lo(function_trace_stop)], %g1 brnz,pn %g1, ftrace_stub mov %fp, %g3 - save %sp, -128, %sp + save %sp, -176, %sp mov %g2, %o1 mov %g2, %l0 mov %g3, %l1 @@ -120,7 +120,7 @@ ENTRY(ftrace_graph_caller) END(ftrace_graph_caller) ENTRY(return_to_handler) - save %sp, -128, %sp + save %sp, -176, %sp call ftrace_return_to_handler mov %fp, %o0 jmpl %o0 + 8, %g0 -- cgit v1.1 From afb567e3fdd2ee43b243cb4f6fe772ab921b2ada Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 13 Apr 2010 23:08:58 -0700 Subject: Revert "Input: wacom - merge out and in prox events" This reverts commit 776943fd6f104a6e8457dc95a17282e69e963666 as it causes issues with ISDv4 E3 touchscreens: https://bugzilla.kernel.org/show_bug.cgi?id=15670 Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 163 +++++++++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 59 deletions(-) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index b3ba343..4a852d8 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; - int x, y, prox; - int rw = 0; - int retval = 0; + int x, y, rw; + static int penData = 0; if (data[0] != WACOM_REPORT_PENABLED) { dbg("wacom_graphire_irq: received unknown report #%d", data[0]); - goto exit; + return 0; } - prox = data[1] & 0x80; - if (prox || wacom->id[0]) { - if (prox) { - switch ((data[1] >> 5) & 3) { + if (data[1] & 0x80) { + /* in prox and not a pad data */ + penData = 1; + + switch ((data[1] >> 5) & 3) { case 0: /* Pen */ wacom->tool[0] = BTN_TOOL_PEN; @@ -181,13 +181,23 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) case 2: /* Mouse with wheel */ wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); + if (features->type == WACOM_G4 || features->type == WACOM_MO) { + rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); + wacom_report_rel(wcombo, REL_WHEEL, -rw); + } else + wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); /* fall through */ case 3: /* Mouse without wheel */ wacom->tool[0] = BTN_TOOL_MOUSE; wacom->id[0] = CURSOR_DEVICE_ID; + wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); + wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); + if (features->type == WACOM_G4 || features->type == WACOM_MO) + wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); + else + wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); break; - } } x = wacom_le16_to_cpu(&data[2]); y = wacom_le16_to_cpu(&data[4]); @@ -198,32 +208,36 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); - } else { - wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); - wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (features->type == WACOM_G4 || - features->type == WACOM_MO) { - wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); - rw = (signed)(data[7] & 0x04) - (data[7] & 0x03); - } else { - wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); - rw = -(signed)data[6]; - } - wacom_report_rel(wcombo, REL_WHEEL, rw); } - - if (!prox) - wacom->id[0] = 0; wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_key(wcombo, wacom->tool[0], prox); - wacom_input_sync(wcombo); /* sync last event */ + wacom_report_key(wcombo, wacom->tool[0], 1); + } else if (wacom->id[0]) { + wacom_report_abs(wcombo, ABS_X, 0); + wacom_report_abs(wcombo, ABS_Y, 0); + if (wacom->tool[0] == BTN_TOOL_MOUSE) { + wacom_report_key(wcombo, BTN_LEFT, 0); + wacom_report_key(wcombo, BTN_RIGHT, 0); + wacom_report_abs(wcombo, ABS_DISTANCE, 0); + } else { + wacom_report_abs(wcombo, ABS_PRESSURE, 0); + wacom_report_key(wcombo, BTN_TOUCH, 0); + wacom_report_key(wcombo, BTN_STYLUS, 0); + wacom_report_key(wcombo, BTN_STYLUS2, 0); + } + wacom->id[0] = 0; + wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ + wacom_report_key(wcombo, wacom->tool[0], 0); } /* send pad data */ switch (features->type) { case WACOM_G4: - prox = data[7] & 0xf8; - if (prox || wacom->id[1]) { + if (data[7] & 0xf8) { + if (penData) { + wacom_input_sync(wcombo); /* sync last event */ + if (!wacom->id[0]) + penData = 0; + } wacom->id[1] = PAD_DEVICE_ID; wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); @@ -231,16 +245,29 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_rel(wcombo, REL_WHEEL, rw); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - if (!prox) - wacom->id[1] = 0; - wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); + wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); + } else if (wacom->id[1]) { + if (penData) { + wacom_input_sync(wcombo); /* sync last event */ + if (!wacom->id[0]) + penData = 0; + } + wacom->id[1] = 0; + wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); + wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); + wacom_report_rel(wcombo, REL_WHEEL, 0); + wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); + wacom_report_abs(wcombo, ABS_MISC, 0); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } - retval = 1; break; case WACOM_MO: - prox = (data[7] & 0xf8) || data[8]; - if (prox || wacom->id[1]) { + if ((data[7] & 0xf8) || (data[8] & 0xff)) { + if (penData) { + wacom_input_sync(wcombo); /* sync last event */ + if (!wacom->id[0]) + penData = 0; + } wacom->id[1] = PAD_DEVICE_ID; wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); @@ -248,16 +275,27 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); - if (!prox) - wacom->id[1] = 0; wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); + } else if (wacom->id[1]) { + if (penData) { + wacom_input_sync(wcombo); /* sync last event */ + if (!wacom->id[0]) + penData = 0; + } + wacom->id[1] = 0; + wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); + wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); + wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); + wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); + wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); + wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); + wacom_report_abs(wcombo, ABS_MISC, 0); + wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } - retval = 1; break; } -exit: - return retval; + return 1; } static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) @@ -598,9 +636,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) { wacom_report_abs(wcombo, ABS_X, - data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8)); + (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); wacom_report_abs(wcombo, ABS_Y, - data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8)); + (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); wacom_report_key(wcombo, wacom->tool[idx], 1); if (idx) @@ -744,24 +782,31 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) touchInProx = 0; - if (!wacom->id[0]) { /* first in prox */ - /* Going into proximity select tool */ - wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - if (wacom->tool[0] == BTN_TOOL_PEN) - wacom->id[0] = STYLUS_DEVICE_ID; - else - wacom->id[0] = ERASER_DEVICE_ID; - } - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - pressure = ((data[7] & 0x01) << 8) | data[6]; - if (pressure < 0) - pressure = features->pressure_max + pressure + 1; - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); - if (!prox) { /* out-prox */ + if (prox) { /* in prox */ + if (!wacom->id[0]) { + /* Going into proximity select tool */ + wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; + if (wacom->tool[0] == BTN_TOOL_PEN) + wacom->id[0] = STYLUS_DEVICE_ID; + else + wacom->id[0] = ERASER_DEVICE_ID; + } + wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); + wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); + wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); + wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); + pressure = ((data[7] & 0x01) << 8) | data[6]; + if (pressure < 0) + pressure = features->pressure_max + pressure + 1; + wacom_report_abs(wcombo, ABS_PRESSURE, pressure); + wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); + } else { + wacom_report_abs(wcombo, ABS_X, 0); + wacom_report_abs(wcombo, ABS_Y, 0); + wacom_report_abs(wcombo, ABS_PRESSURE, 0); + wacom_report_key(wcombo, BTN_STYLUS, 0); + wacom_report_key(wcombo, BTN_STYLUS2, 0); + wacom_report_key(wcombo, BTN_TOUCH, 0); wacom->id[0] = 0; /* pen is out so touch can be enabled now */ touchInProx = 1; -- cgit v1.1 From ec687886de00e1e63f3d821ccade9a61590408ed Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Apr 2010 02:04:29 -0700 Subject: sparc64: Run NMIs on the hardirq stack. Otherwise we can overflow the main stack with the function tracer enabled. Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_64.c | 19 +------------------ arch/sparc/kernel/kstack.h | 19 +++++++++++++++++++ arch/sparc/kernel/nmi.c | 7 +++++++ 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 2b04c72..830d70a 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -47,6 +47,7 @@ #include "entry.h" #include "cpumap.h" +#include "kstack.h" #define NUM_IVECS (IMAP_INR + 1) @@ -713,24 +714,6 @@ void ack_bad_irq(unsigned int virt_irq) void *hardirq_stack[NR_CPUS]; void *softirq_stack[NR_CPUS]; -static __attribute__((always_inline)) void *set_hardirq_stack(void) -{ - void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; - - __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); - if (orig_sp < sp || - orig_sp > (sp + THREAD_SIZE)) { - sp += THREAD_SIZE - 192 - STACK_BIAS; - __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); - } - - return orig_sp; -} -static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) -{ - __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); -} - void __irq_entry handler_irq(int irq, struct pt_regs *regs) { unsigned long pstate, bucket_pa; diff --git a/arch/sparc/kernel/kstack.h b/arch/sparc/kernel/kstack.h index 5247283..53dfb92 100644 --- a/arch/sparc/kernel/kstack.h +++ b/arch/sparc/kernel/kstack.h @@ -61,4 +61,23 @@ check_magic: } +static inline __attribute__((always_inline)) void *set_hardirq_stack(void) +{ + void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; + + __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); + if (orig_sp < sp || + orig_sp > (sp + THREAD_SIZE)) { + sp += THREAD_SIZE - 192 - STACK_BIAS; + __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); + } + + return orig_sp; +} + +static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) +{ + __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); +} + #endif /* _KSTACK_H */ diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index 75a3d1a..a4bd7ba 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c @@ -23,6 +23,8 @@ #include #include +#include "kstack.h" + /* We don't have a real NMI on sparc64, but we can fake one * up using profiling counter overflow interrupts and interrupt * levels. @@ -92,6 +94,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) { unsigned int sum, touched = 0; + void *orig_sp; clear_softint(1 << irq); @@ -99,6 +102,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) nmi_enter(); + orig_sp = set_hardirq_stack(); + if (notify_die(DIE_NMI, "nmi", regs, 0, pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) touched = 1; @@ -124,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) pcr_ops->write(pcr_enable); } + restore_hardirq_stack(orig_sp); + nmi_exit(); } -- cgit v1.1 From 317aa408d69a5b833a116317c18c7e957989ce44 Mon Sep 17 00:00:00 2001 From: Anders Larsen Date: Thu, 4 Mar 2010 11:22:53 +0100 Subject: ARM: 5975/1: AT91 slow-clock suspend: don't wait when turning PLLs off From: Julien Langer AT91: when turning off the PLLs during suspend, don't wait for the lock flag to be set. Previously the code would always run into the loop limitation of 1000 iterations because the flag is never set when turning the PLLs off. Comments from Anders Larsen: (in http://marc.info/?l=linux-kernel&m=127058929724193&w=2) Signed-off-by: Julien Langer Signed-off-by: Anders Larsen Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/pm_slowclock.S | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 9fcbd6c..9c5b48e 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -175,8 +175,6 @@ ENTRY(at91_slow_clock) orr r3, r3, #(1 << 29) /* bit 29 always set */ str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] - wait_pllalock - /* Save PLLB setting and disable it */ ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] str r3, .saved_pllbr @@ -184,8 +182,6 @@ ENTRY(at91_slow_clock) mov r3, #AT91_PMC_PLLCOUNT str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] - wait_pllblock - /* Turn off the main oscillator */ ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] bic r3, r3, #AT91_PMC_MOSCEN -- cgit v1.1 From 7e5a69e83ba7a0d5917ad830f417cba8b8d6aa72 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 29 Mar 2010 21:46:02 +0100 Subject: ARM: 6007/1: fix highmem with VIPT cache and DMA The VIVT cache of a highmem page is always flushed before the page is unmapped. This cache flush is explicit through flush_cache_kmaps() in flush_all_zero_pkmaps(), or through __cpuc_flush_dcache_area() in kunmap_atomic(). There is also an implicit flush of those highmem pages that were part of a process that just terminated making those pages free as the whole VIVT cache has to be flushed on every task switch. Hence unmapped highmem pages need no cache maintenance in that case. However unmapped pages may still be cached with a VIPT cache because the cache is tagged with physical addresses. There is no need for a whole cache flush during task switching for that reason, and despite the explicit cache flushes in flush_all_zero_pkmaps() and kunmap_atomic(), some highmem pages that were mapped in user space end up still cached even when they become unmapped. So, we do have to perform cache maintenance on those unmapped highmem pages in the context of DMA when using a VIPT cache. Unfortunately, it is not possible to perform that cache maintenance using physical addresses as all the L1 cache maintenance coprocessor functions accept virtual addresses only. Therefore we have no choice but to set up a temporary virtual mapping for that purpose. And of course the explicit cache flushing when unmapping a highmem page on a system with a VIPT cache now can go, which should increase performance. While at it, because the code in __flush_dcache_page() has to be modified anyway, let's also make sure the mapped highmem pages are pinned with kmap_high_get() for the duration of the cache maintenance operation. Because kunmap() does unmap highmem pages lazily, it was reported by Gary King that those pages ended up being unmapped during cache maintenance on SMP causing segmentation faults. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/include/asm/highmem.h | 15 ++++++- arch/arm/include/asm/kmap_types.h | 1 + arch/arm/mm/copypage-v6.c | 9 +--- arch/arm/mm/dma-mapping.c | 5 +++ arch/arm/mm/flush.c | 25 ++++++----- arch/arm/mm/highmem.c | 87 ++++++++++++++++++++++++++++++++++++++- 6 files changed, 122 insertions(+), 20 deletions(-) diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 7f36d00..feb988a 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h @@ -11,7 +11,11 @@ #define kmap_prot PAGE_KERNEL -#define flush_cache_kmaps() flush_cache_all() +#define flush_cache_kmaps() \ + do { \ + if (cache_is_vivt()) \ + flush_cache_all(); \ + } while (0) extern pte_t *pkmap_page_table; @@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page); extern void *kmap_high_get(struct page *page); extern void kunmap_high(struct page *page); +extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte); +extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte); + +/* + * The following functions are already defined by + * when CONFIG_HIGHMEM is not set. + */ +#ifdef CONFIG_HIGHMEM extern void *kmap(struct page *page); extern void kunmap(struct page *page); extern void *kmap_atomic(struct page *page, enum km_type type); extern void kunmap_atomic(void *kvaddr, enum km_type type); extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); extern struct page *kmap_atomic_to_page(const void *ptr); +#endif #endif diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index c019949..c4b2ea3 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h @@ -18,6 +18,7 @@ enum km_type { KM_IRQ1, KM_SOFTIRQ0, KM_SOFTIRQ1, + KM_L1_CACHE, KM_L2_CACHE, KM_TYPE_NR }; diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 8bca4de..f55fa10 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to, kfrom = kmap_atomic(from, KM_USER0); kto = kmap_atomic(to, KM_USER1); copy_page(kto, kfrom); -#ifdef CONFIG_HIGHMEM - /* - * kmap_atomic() doesn't set the page virtual address, and - * kunmap_atomic() takes care of cache flushing already. - */ - if (page_address(to) != NULL) -#endif - __cpuc_flush_dcache_area(kto, PAGE_SIZE); + __cpuc_flush_dcache_area(kto, PAGE_SIZE); kunmap_atomic(kto, KM_USER1); kunmap_atomic(kfrom, KM_USER0); } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 1351edc..13fa536 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, vaddr += offset; op(vaddr, len, dir); kunmap_high(page); + } else if (cache_is_vipt()) { + pte_t saved_pte; + vaddr = kmap_high_l1_vipt(page, &saved_pte); + op(vaddr + offset, len, dir); + kunmap_high_l1_vipt(page, saved_pte); } } else { vaddr = page_address(page) + offset; diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index e34f095..c6844cb 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, void __flush_dcache_page(struct address_space *mapping, struct page *page) { - void *addr = page_address(page); - /* * Writeback any data associated with the kernel mapping of this * page. This ensures that data in the physical page is mutually * coherent with the kernels mapping. */ -#ifdef CONFIG_HIGHMEM - /* - * kmap_atomic() doesn't set the page virtual address, and - * kunmap_atomic() takes care of cache flushing already. - */ - if (addr) -#endif - __cpuc_flush_dcache_area(addr, PAGE_SIZE); + if (!PageHighMem(page)) { + __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); + } else { + void *addr = kmap_high_get(page); + if (addr) { + __cpuc_flush_dcache_area(addr, PAGE_SIZE); + kunmap_high(page); + } else if (cache_is_vipt()) { + pte_t saved_pte; + addr = kmap_high_l1_vipt(page, &saved_pte); + __cpuc_flush_dcache_area(addr, PAGE_SIZE); + kunmap_high_l1_vipt(page, saved_pte); + } + } /* * If this is a page cache page, and we have an aliasing VIPT cache, diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 2be1ec7..77b030f 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); if (kvaddr >= (void *)FIXADDR_START) { - __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); + if (cache_is_vivt()) + __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); @@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr) pte = TOP_PTE(vaddr); return pte_page(*pte); } + +#ifdef CONFIG_CPU_CACHE_VIPT + +#include + +/* + * The VIVT cache of a highmem page is always flushed before the page + * is unmapped. Hence unmapped highmem pages need no cache maintenance + * in that case. + * + * However unmapped pages may still be cached with a VIPT cache, and + * it is not possible to perform cache maintenance on them using physical + * addresses unfortunately. So we have no choice but to set up a temporary + * virtual mapping for that purpose. + * + * Yet this VIPT cache maintenance may be triggered from DMA support + * functions which are possibly called from interrupt context. As we don't + * want to keep interrupt disabled all the time when such maintenance is + * taking place, we therefore allow for some reentrancy by preserving and + * restoring the previous fixmap entry before the interrupted context is + * resumed. If the reentrancy depth is 0 then there is no need to restore + * the previous fixmap, and leaving the current one in place allow it to + * be reused the next time without a TLB flush (common with DMA). + */ + +static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth); + +void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte) +{ + unsigned int idx, cpu = smp_processor_id(); + int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); + unsigned long vaddr, flags; + pte_t pte, *ptep; + + idx = KM_L1_CACHE + KM_TYPE_NR * cpu; + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + ptep = TOP_PTE(vaddr); + pte = mk_pte(page, kmap_prot); + + if (!in_interrupt()) + preempt_disable(); + + raw_local_irq_save(flags); + (*depth)++; + if (pte_val(*ptep) == pte_val(pte)) { + *saved_pte = pte; + } else { + *saved_pte = *ptep; + set_pte_ext(ptep, pte, 0); + local_flush_tlb_kernel_page(vaddr); + } + raw_local_irq_restore(flags); + + return (void *)vaddr; +} + +void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte) +{ + unsigned int idx, cpu = smp_processor_id(); + int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); + unsigned long vaddr, flags; + pte_t pte, *ptep; + + idx = KM_L1_CACHE + KM_TYPE_NR * cpu; + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + ptep = TOP_PTE(vaddr); + pte = mk_pte(page, kmap_prot); + + BUG_ON(pte_val(*ptep) != pte_val(pte)); + BUG_ON(*depth <= 0); + + raw_local_irq_save(flags); + (*depth)--; + if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) { + set_pte_ext(ptep, saved_pte, 0); + local_flush_tlb_kernel_page(vaddr); + } + raw_local_irq_restore(flags); + + if (!in_interrupt()) + preempt_enable(); +} + +#endif /* CONFIG_CPU_CACHE_VIPT */ -- cgit v1.1 From 5c5cac63851f347d8308d69f1892c4af51d7c1a4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Sun, 11 Apr 2010 15:57:07 +0100 Subject: ARM: 6050/1: VFP: fix the SMP versions of vfp_{sync,flush}_hwstate From: Imre Deak Recently the UP versions of these functions were refactored and as a side effect it became possible to call them for the current thread. This isn't true for the SMP versions however, so fix this up. Signed-off-by: Imre Deak Signed-off-by: Russell King --- arch/arm/vfp/vfpmodule.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index a420cb9..315a540 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -428,26 +428,6 @@ static void vfp_pm_init(void) static inline void vfp_pm_init(void) { } #endif /* CONFIG_PM */ -/* - * Synchronise the hardware VFP state of a thread other than current with the - * saved one. This function is used by the ptrace mechanism. - */ -#ifdef CONFIG_SMP -void vfp_sync_hwstate(struct thread_info *thread) -{ -} - -void vfp_flush_hwstate(struct thread_info *thread) -{ - /* - * On SMP systems, the VFP state is automatically saved at every - * context switch. We mark the thread VFP state as belonging to a - * non-existent CPU so that the saved one will be reloaded when - * needed. - */ - thread->vfpstate.hard.cpu = NR_CPUS; -} -#else void vfp_sync_hwstate(struct thread_info *thread) { unsigned int cpu = get_cpu(); @@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread) last_VFP_context[cpu] = NULL; } +#ifdef CONFIG_SMP + /* + * For SMP we still have to take care of the case where the thread + * migrates to another CPU and then back to the original CPU on which + * the last VFP user is still the same thread. Mark the thread VFP + * state as belonging to a non-existent CPU so that the saved one will + * be reloaded in the above case. + */ + thread->vfpstate.hard.cpu = NR_CPUS; +#endif put_cpu(); } -#endif #include -- cgit v1.1 From 82c6f5a5b3e91ef4d2fb8725de4b8cf7affd4d61 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Sun, 11 Apr 2010 15:58:27 +0100 Subject: ARM: 6051/1: VFP: preserve the HW context when calling signal handlers From: Imre Deak Signal handlers can use floating point, so prevent them to corrupt the main thread's VFP context. So far there were two signal stack frame formats defined based on the VFP implementation, but the user struct used for ptrace covers all posibilities, so use it for the signal stack too. Introduce also a new user struct for VFP exception registers. In this too fields not relevant to the current VFP architecture are ignored. Support to save / restore the exception registers was added by Will Deacon. Signed-off-by: Imre Deak Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/ucontext.h | 23 +++++----- arch/arm/include/asm/user.h | 12 +++++- arch/arm/kernel/signal.c | 93 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 111 insertions(+), 17 deletions(-) diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h index bf65e9f..47f023a 100644 --- a/arch/arm/include/asm/ucontext.h +++ b/arch/arm/include/asm/ucontext.h @@ -59,23 +59,22 @@ struct iwmmxt_sigframe { #endif /* CONFIG_IWMMXT */ #ifdef CONFIG_VFP -#if __LINUX_ARM_ARCH__ < 6 -/* For ARM pre-v6, we use fstmiax and fldmiax. This adds one extra - * word after the registers, and a word of padding at the end for - * alignment. */ #define VFP_MAGIC 0x56465001 -#define VFP_STORAGE_SIZE 152 -#else -#define VFP_MAGIC 0x56465002 -#define VFP_STORAGE_SIZE 144 -#endif struct vfp_sigframe { unsigned long magic; unsigned long size; - union vfp_state storage; -}; + struct user_vfp ufp; + struct user_vfp_exc ufp_exc; +} __attribute__((__aligned__(8))); + +/* + * 8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc, + * 4 bytes padding. + */ +#define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe) + #endif /* CONFIG_VFP */ /* @@ -91,7 +90,7 @@ struct aux_sigframe { #ifdef CONFIG_IWMMXT struct iwmmxt_sigframe iwmmxt; #endif -#if 0 && defined CONFIG_VFP /* Not yet saved. */ +#ifdef CONFIG_VFP struct vfp_sigframe vfp; #endif /* Something that isn't a valid magic number for any coprocessor. */ diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h index df95e05..05ac4b0 100644 --- a/arch/arm/include/asm/user.h +++ b/arch/arm/include/asm/user.h @@ -83,11 +83,21 @@ struct user{ /* * User specific VFP registers. If only VFPv2 is present, registers 16 to 31 - * are ignored by the ptrace system call. + * are ignored by the ptrace system call and the signal handler. */ struct user_vfp { unsigned long long fpregs[32]; unsigned long fpscr; }; +/* + * VFP exception registers exposed to user space during signal delivery. + * Fields not relavant to the current VFP architecture are ignored. + */ +struct user_vfp_exc { + unsigned long fpexc; + unsigned long fpinst; + unsigned long fpinst2; +}; + #endif /* _ARM_USER_H */ diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index e7714f3..907d5a6 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "ptrace.h" #include "signal.h" @@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) #endif +#ifdef CONFIG_VFP + +static int preserve_vfp_context(struct vfp_sigframe __user *frame) +{ + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *h = &thread->vfpstate.hard; + const unsigned long magic = VFP_MAGIC; + const unsigned long size = VFP_STORAGE_SIZE; + int err = 0; + + vfp_sync_hwstate(thread); + __put_user_error(magic, &frame->magic, err); + __put_user_error(size, &frame->size, err); + + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, + sizeof(h->fpregs)); + /* + * Copy the status and control register. + */ + __put_user_error(h->fpscr, &frame->ufp.fpscr, err); + + /* + * Copy the exception registers. + */ + __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); + __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); + __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + + return err ? -EFAULT : 0; +} + +static int restore_vfp_context(struct vfp_sigframe __user *frame) +{ + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *h = &thread->vfpstate.hard; + unsigned long magic; + unsigned long size; + unsigned long fpexc; + int err = 0; + + __get_user_error(magic, &frame->magic, err); + __get_user_error(size, &frame->size, err); + + if (err) + return -EFAULT; + if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) + return -EINVAL; + + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs, + sizeof(h->fpregs)); + /* + * Copy the status and control register. + */ + __get_user_error(h->fpscr, &frame->ufp.fpscr, err); + + /* + * Sanitise and restore the exception registers. + */ + __get_user_error(fpexc, &frame->ufp_exc.fpexc, err); + /* Ensure the VFP is enabled. */ + fpexc |= FPEXC_EN; + /* Ensure FPINST2 is invalid and the exception flag is cleared. */ + fpexc &= ~(FPEXC_EX | FPEXC_FP2V); + h->fpexc = fpexc; + + __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); + __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + + if (!err) + vfp_flush_hwstate(thread); + + return err ? -EFAULT : 0; +} + +#endif + /* * Do a signal return; undo the signal stack. These are aligned to 64-bit. */ @@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) err |= restore_iwmmxt_context(&aux->iwmmxt); #endif #ifdef CONFIG_VFP -// if (err == 0) -// err |= vfp_restore_state(&sf->aux.vfp); + if (err == 0) + err |= restore_vfp_context(&aux->vfp); #endif return err; @@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) err |= preserve_iwmmxt_context(&aux->iwmmxt); #endif #ifdef CONFIG_VFP -// if (err == 0) -// err |= vfp_save_state(&sf->aux.vfp); + if (err == 0) + err |= preserve_vfp_context(&aux->vfp); #endif __put_user_error(0, &aux->end_magic, err); -- cgit v1.1 From 3f2d4f561fab4588344cc519fd323382ab950928 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 13 Apr 2010 07:01:46 +0100 Subject: ARM: 6052/1: kdump: make kexec work in interrupt context When crash happens in interrupt context there is no userspace context. We always use current->active_mm in those cases. Signed-off-by: Mika Westerberg Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4223d08..241c24a 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1054,10 +1054,12 @@ void setup_mm_for_reboot(char mode) pgd_t *pgd; int i; - if (current->mm && current->mm->pgd) - pgd = current->mm->pgd; - else - pgd = init_mm.pgd; + /* + * We need to access to user-mode page tables here. For kernel threads + * we don't have any user-mode mappings so we use the context that we + * "borrowed". + */ + pgd = current->active_mm->pgd; base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) -- cgit v1.1 From b62730baea32f86fe91a7930e4b7ee8d82778b79 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 9 Apr 2010 15:39:10 -0700 Subject: rcu: Add rcu_access_pointer and rcu_dereference_protected This patch adds variants of rcu_dereference() that handle situations where the RCU-protected data structure cannot change, perhaps due to our holding the update-side lock, or where the RCU-protected pointer is only to be fetched, not dereferenced. These are needed due to some performance concerns with using rcu_dereference() where it is not required, aside from the need for lockdep/sparse checking. The new rcu_access_pointer() primitive is for the case where the pointer is be fetch and not dereferenced. This primitive may be used without protection, RCU or otherwise, due to the fact that it uses ACCESS_ONCE(). The new rcu_dereference_protected() primitive is for the case where updates are prevented, for example, due to holding the update-side lock. This primitive does neither ACCESS_ONCE() nor smp_read_barrier_depends(), so can only be used when updates are somehow prevented. Suggested-by: David Howells Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com Cc: eric.dumazet@gmail.com LKML-Reference: <1270852752-25278-1-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar --- include/linux/rcupdate.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 872a98e..8fe8660 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -209,13 +209,45 @@ static inline int rcu_read_lock_sched_held(void) rcu_dereference_raw(p); \ }) +/** + * rcu_dereference_protected - fetch RCU pointer when updates prevented + * + * Return the value of the specified RCU-protected pointer, but omit + * both the smp_read_barrier_depends() and the ACCESS_ONCE(). This + * is useful in cases where update-side locks prevent the value of the + * pointer from changing. Please note that this primitive does -not- + * prevent the compiler from repeating this reference or combining it + * with other references, so it should not be used without protection + * of appropriate locks. + */ +#define rcu_dereference_protected(p, c) \ + ({ \ + if (debug_lockdep_rcu_enabled() && !(c)) \ + lockdep_rcu_dereference(__FILE__, __LINE__); \ + (p); \ + }) + #else /* #ifdef CONFIG_PROVE_RCU */ #define rcu_dereference_check(p, c) rcu_dereference_raw(p) +#define rcu_dereference_protected(p, c) (p) #endif /* #else #ifdef CONFIG_PROVE_RCU */ /** + * rcu_access_pointer - fetch RCU pointer with no dereferencing + * + * Return the value of the specified RCU-protected pointer, but omit the + * smp_read_barrier_depends() and keep the ACCESS_ONCE(). This is useful + * when the value of this pointer is accessed, but the pointer is not + * dereferenced, for example, when testing an RCU-protected pointer against + * NULL. This may also be used in cases where update-side locks prevent + * the value of the pointer from changing, but rcu_dereference_protected() + * is a lighter-weight primitive for this use case. + */ +#define rcu_access_pointer(p) ACCESS_ONCE(p) + +/** * rcu_read_lock - mark the beginning of an RCU read-side critical section. * * When synchronize_rcu() is invoked on one CPU while other CPUs -- cgit v1.1 From c08c68dd76bd6b776bc0eb45a5e8f354ed772cdf Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 9 Apr 2010 15:39:11 -0700 Subject: rcu: Better explain the condition parameter of rcu_dereference_check() Better explain the condition parameter of rcu_dereference_check() that describes the conditions under which the dereference is permitted to take place (and incorporate Yong Zhang's suggestion). This condition is only checked under lockdep proving. Signed-off-by: David Howells Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: eric.dumazet@gmail.com LKML-Reference: <1270852752-25278-2-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar --- include/linux/rcupdate.h | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 8fe8660..9f1ddfe 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -195,12 +195,30 @@ static inline int rcu_read_lock_sched_held(void) /** * rcu_dereference_check - rcu_dereference with debug checking + * @p: The pointer to read, prior to dereferencing + * @c: The conditions under which the dereference will take place * - * Do an rcu_dereference(), but check that the context is correct. - * For example, rcu_dereference_check(gp, rcu_read_lock_held()) to - * ensure that the rcu_dereference_check() executes within an RCU - * read-side critical section. It is also possible to check for - * locks being held, for example, by using lockdep_is_held(). + * Do an rcu_dereference(), but check that the conditions under which the + * dereference will take place are correct. Typically the conditions indicate + * the various locking conditions that should be held at that point. The check + * should return true if the conditions are satisfied. + * + * For example: + * + * bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() || + * lockdep_is_held(&foo->lock)); + * + * could be used to indicate to lockdep that foo->bar may only be dereferenced + * if either the RCU read lock is held, or that the lock required to replace + * the bar struct at foo->bar is held. + * + * Note that the list of conditions may also include indications of when a lock + * need not be held, for example during initialisation or destruction of the + * target struct: + * + * bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() || + * lockdep_is_held(&foo->lock) || + * atomic_read(&foo->usage) == 0); */ #define rcu_dereference_check(p, c) \ ({ \ -- cgit v1.1 From 50aec0024eccb1d5f540ab64a1958eebcdb9340c Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 9 Apr 2010 15:39:12 -0700 Subject: rcu: Update docs for rcu_access_pointer and rcu_dereference_protected Update examples and lists of APIs to include these new primitives. Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com Cc: eric.dumazet@gmail.com LKML-Reference: <1270852752-25278-3-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar --- Documentation/RCU/NMI-RCU.txt | 39 ++++++++++++++++++++++----------------- Documentation/RCU/checklist.txt | 7 ++++--- Documentation/RCU/lockdep.txt | 28 ++++++++++++++++++++++++++-- Documentation/RCU/whatisRCU.txt | 6 ++++++ 4 files changed, 58 insertions(+), 22 deletions(-) diff --git a/Documentation/RCU/NMI-RCU.txt b/Documentation/RCU/NMI-RCU.txt index a6d32e6..a8536cb 100644 --- a/Documentation/RCU/NMI-RCU.txt +++ b/Documentation/RCU/NMI-RCU.txt @@ -34,7 +34,7 @@ NMI handler. cpu = smp_processor_id(); ++nmi_count(cpu); - if (!rcu_dereference(nmi_callback)(regs, cpu)) + if (!rcu_dereference_sched(nmi_callback)(regs, cpu)) default_do_nmi(regs); nmi_exit(); @@ -47,12 +47,13 @@ function pointer. If this handler returns zero, do_nmi() invokes the default_do_nmi() function to handle a machine-specific NMI. Finally, preemption is restored. -Strictly speaking, rcu_dereference() is not needed, since this code runs -only on i386, which does not need rcu_dereference() anyway. However, -it is a good documentation aid, particularly for anyone attempting to -do something similar on Alpha. +In theory, rcu_dereference_sched() is not needed, since this code runs +only on i386, which in theory does not need rcu_dereference_sched() +anyway. However, in practice it is a good documentation aid, particularly +for anyone attempting to do something similar on Alpha or on systems +with aggressive optimizing compilers. -Quick Quiz: Why might the rcu_dereference() be necessary on Alpha, +Quick Quiz: Why might the rcu_dereference_sched() be necessary on Alpha, given that the code referenced by the pointer is read-only? @@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI entry and exit, respectively. Answer to Quick Quiz - Why might the rcu_dereference() be necessary on Alpha, given + Why might the rcu_dereference_sched() be necessary on Alpha, given that the code referenced by the pointer is read-only? Answer: The caller to set_nmi_callback() might well have - initialized some data that is to be used by the - new NMI handler. In this case, the rcu_dereference() - would be needed, because otherwise a CPU that received - an NMI just after the new handler was set might see - the pointer to the new NMI handler, but the old - pre-initialized version of the handler's data. - - More important, the rcu_dereference() makes it clear - to someone reading the code that the pointer is being - protected by RCU. + initialized some data that is to be used by the new NMI + handler. In this case, the rcu_dereference_sched() would + be needed, because otherwise a CPU that received an NMI + just after the new handler was set might see the pointer + to the new NMI handler, but the old pre-initialized + version of the handler's data. + + This same sad story can happen on other CPUs when using + a compiler with aggressive pointer-value speculation + optimizations. + + More important, the rcu_dereference_sched() makes it + clear to someone reading the code that the pointer is + being protected by RCU-sched. diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index cbc180f..790d1a8 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt @@ -260,7 +260,8 @@ over a rather long period of time, but improvements are always welcome! The reason that it is permissible to use RCU list-traversal primitives when the update-side lock is held is that doing so can be quite helpful in reducing code bloat when common code is - shared between readers and updaters. + shared between readers and updaters. Additional primitives + are provided for this case, as discussed in lockdep.txt. 10. Conversely, if you are in an RCU read-side critical section, and you don't hold the appropriate update-side lock, you -must- @@ -344,8 +345,8 @@ over a rather long period of time, but improvements are always welcome! requiring SRCU's read-side deadlock immunity or low read-side realtime latency. - Note that, rcu_assign_pointer() and rcu_dereference() relate to - SRCU just as they do to other forms of RCU. + Note that, rcu_assign_pointer() relates to SRCU just as they do + to other forms of RCU. 15. The whole point of call_rcu(), synchronize_rcu(), and friends is to wait until all pre-existing readers have finished before diff --git a/Documentation/RCU/lockdep.txt b/Documentation/RCU/lockdep.txt index fe24b58..d7a49b2 100644 --- a/Documentation/RCU/lockdep.txt +++ b/Documentation/RCU/lockdep.txt @@ -32,9 +32,20 @@ checking of rcu_dereference() primitives: srcu_dereference(p, sp): Check for SRCU read-side critical section. rcu_dereference_check(p, c): - Use explicit check expression "c". + Use explicit check expression "c". This is useful in + code that is invoked by both readers and updaters. rcu_dereference_raw(p) Don't check. (Use sparingly, if at all.) + rcu_dereference_protected(p, c): + Use explicit check expression "c", and omit all barriers + and compiler constraints. This is useful when the data + structure cannot change, for example, in code that is + invoked only by updaters. + rcu_access_pointer(p): + Return the value of the pointer and omit all barriers, + but retain the compiler constraints that prevent duplicating + or coalescsing. This is useful when when testing the + value of the pointer itself, for example, against NULL. The rcu_dereference_check() check expression can be any boolean expression, but would normally include one of the rcu_read_lock_held() @@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla RCU read-side critical sections, in case (2) the ->file_lock prevents any change from taking place, and finally, in case (3) the current task is the only task accessing the file_struct, again preventing any change -from taking place. +from taking place. If the above statement was invoked only from updater +code, it could instead be written as follows: + + file = rcu_dereference_protected(fdt->fd[fd], + lockdep_is_held(&files->file_lock) || + atomic_read(&files->count) == 1); + +This would verify cases #2 and #3 above, and furthermore lockdep would +complain if this was used in an RCU read-side critical section unless one +of these two cases held. Because rcu_dereference_protected() omits all +barriers and compiler constraints, it generates better code than do the +other flavors of rcu_dereference(). On the other hand, it is illegal +to use rcu_dereference_protected() if either the RCU-protected pointer +or the RCU-protected data that it points to can change concurrently. There are currently only "universal" versions of the rcu_assign_pointer() and RCU list-/tree-traversal primitives, which do not (yet) check for diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 1dc00ee..cfaac34 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -840,6 +840,12 @@ SRCU: Initialization/cleanup init_srcu_struct cleanup_srcu_struct +All: lockdep-checked RCU-protected pointer access + + rcu_dereference_check + rcu_dereference_protected + rcu_access_pointer + See the comment headers in the source code (or the docbook generated from them) for more information. -- cgit v1.1 From b1cdbb5f8342d99b732c5535ee7d2de8e7b2cc2e Mon Sep 17 00:00:00 2001 From: Ernst Schwab Date: Thu, 4 Mar 2010 10:15:39 +0100 Subject: ARM: 5974/1: arm/mach-at91 Makefile: remove two blanks. Cosmetic change to mach-at91 Makefile: remove two blanks introduced by earlier patches. Signed-off-by: Ernst Schwab Signed-off-by: Russell King --- arch/arm/mach-at91/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 027dd57..d400455 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_d obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o - obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o -- cgit v1.1 From 5094aeafbbd500509f648e3cd102b053bc7926b3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 14 Apr 2010 21:43:53 -0600 Subject: lguest: workaround cmpxchg8b_emu by ignoring cli in the guest. It's only used by cmpxchg8b_emu (see db677ffa5f5a for the gory details), and fixing that to be paravirt aware would be more work than simply ignoring it (and AFAICT only help lguest). This makes lguest work on machines which have cmpxchg8b, for kernels compiled for older processors. (We can't emulate it properly: the popf which expects to restore interrupts does not trap). Signed-off-by: Rusty Russell Cc: Jeremy Fitzhardinge Cc: virtualization@lists.osdl.org --- drivers/lguest/x86/core.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index fb2b7ef..b4eb675 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c @@ -288,6 +288,18 @@ static int emulate_insn(struct lg_cpu *cpu) insn = lgread(cpu, physaddr, u8); /* + * Around 2.6.33, the kernel started using an emulation for the + * cmpxchg8b instruction in early boot on many configurations. This + * code isn't paravirtualized, and it tries to disable interrupts. + * Ignore it, which will Mostly Work. + */ + if (insn == 0xfa) { + /* "cli", or Clear Interrupt Enable instruction. Skip it. */ + cpu->regs->eip++; + return 1; + } + + /* * 0x66 is an "operand prefix". It means it's using the upper 16 bits * of the eax register. */ -- cgit v1.1 From 091ebf07a2408f9a56634caa0f86d9360e9af23b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 14 Apr 2010 21:43:54 -0600 Subject: lguest: stop using KVM hypercall mechanism This is a partial revert of 4cd8b5e2a159 "lguest: use KVM hypercalls"; we revert to using (just as questionable but more reliable) int $15 for hypercalls. I didn't revert the register mapping, so we still use the same calling convention as kvm. KVM in more recent incarnations stopped injecting a fault when a guest tried to use the VMCALL instruction from ring 1, so lguest under kvm fails to make hypercalls. It was nice to share code with our KVM cousins, but this was overreach. Signed-off-by: Rusty Russell Cc: Matias Zabaljauregui Cc: Avi Kivity --- arch/x86/include/asm/lguest_hcall.h | 29 ++++++++++++++---- arch/x86/lguest/boot.c | 61 ++++++++++++++++++------------------- arch/x86/lguest/i386_head.S | 2 +- drivers/lguest/lguest_device.c | 4 +-- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h index ba0eed8..b60f292 100644 --- a/arch/x86/include/asm/lguest_hcall.h +++ b/arch/x86/include/asm/lguest_hcall.h @@ -28,22 +28,39 @@ #ifndef __ASSEMBLY__ #include -#include /*G:030 * But first, how does our Guest contact the Host to ask for privileged * operations? There are two ways: the direct way is to make a "hypercall", * to make requests of the Host Itself. * - * We use the KVM hypercall mechanism, though completely different hypercall - * numbers. Seventeen hypercalls are available: the hypercall number is put in - * the %eax register, and the arguments (when required) are placed in %ebx, - * %ecx, %edx and %esi. If a return value makes sense, it's returned in %eax. + * Our hypercall mechanism uses the highest unused trap code (traps 32 and + * above are used by real hardware interrupts). Seventeen hypercalls are + * available: the hypercall number is put in the %eax register, and the + * arguments (when required) are placed in %ebx, %ecx, %edx and %esi. + * If a return value makes sense, it's returned in %eax. * * Grossly invalid calls result in Sudden Death at the hands of the vengeful * Host, rather than returning failure. This reflects Winston Churchill's * definition of a gentleman: "someone who is only rude intentionally". -:*/ + */ +static inline unsigned long +hcall(unsigned long call, + unsigned long arg1, unsigned long arg2, unsigned long arg3, + unsigned long arg4) +{ + /* "int" is the Intel instruction to trigger a trap. */ + asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) + /* The call in %eax (aka "a") might be overwritten */ + : "=a"(call) + /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */ + : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) + /* "memory" means this might write somewhere in memory. + * This isn't true for all calls, but it's safe to tell + * gcc that it might happen so it doesn't get clever. */ + : "memory"); + return call; +} /* Can't use our min() macro here: needs to be a constant */ #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32) diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 7e59dc1..2bdf628 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -115,7 +115,7 @@ static void async_hcall(unsigned long call, unsigned long arg1, local_irq_save(flags); if (lguest_data.hcall_status[next_call] != 0xFF) { /* Table full, so do normal hcall which will flush table. */ - kvm_hypercall4(call, arg1, arg2, arg3, arg4); + hcall(call, arg1, arg2, arg3, arg4); } else { lguest_data.hcalls[next_call].arg0 = call; lguest_data.hcalls[next_call].arg1 = arg1; @@ -145,46 +145,45 @@ static void async_hcall(unsigned long call, unsigned long arg1, * So, when we're in lazy mode, we call async_hcall() to store the call for * future processing: */ -static void lazy_hcall1(unsigned long call, - unsigned long arg1) +static void lazy_hcall1(unsigned long call, unsigned long arg1) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - kvm_hypercall1(call, arg1); + hcall(call, arg1, 0, 0, 0); else async_hcall(call, arg1, 0, 0, 0); } /* You can imagine what lazy_hcall2, 3 and 4 look like. :*/ static void lazy_hcall2(unsigned long call, - unsigned long arg1, - unsigned long arg2) + unsigned long arg1, + unsigned long arg2) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - kvm_hypercall2(call, arg1, arg2); + hcall(call, arg1, arg2, 0, 0); else async_hcall(call, arg1, arg2, 0, 0); } static void lazy_hcall3(unsigned long call, - unsigned long arg1, - unsigned long arg2, - unsigned long arg3) + unsigned long arg1, + unsigned long arg2, + unsigned long arg3) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - kvm_hypercall3(call, arg1, arg2, arg3); + hcall(call, arg1, arg2, arg3, 0); else async_hcall(call, arg1, arg2, arg3, 0); } #ifdef CONFIG_X86_PAE static void lazy_hcall4(unsigned long call, - unsigned long arg1, - unsigned long arg2, - unsigned long arg3, - unsigned long arg4) + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4) { if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) - kvm_hypercall4(call, arg1, arg2, arg3, arg4); + hcall(call, arg1, arg2, arg3, arg4); else async_hcall(call, arg1, arg2, arg3, arg4); } @@ -196,13 +195,13 @@ static void lazy_hcall4(unsigned long call, :*/ static void lguest_leave_lazy_mmu_mode(void) { - kvm_hypercall0(LHCALL_FLUSH_ASYNC); + hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); paravirt_leave_lazy_mmu(); } static void lguest_end_context_switch(struct task_struct *next) { - kvm_hypercall0(LHCALL_FLUSH_ASYNC); + hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); paravirt_end_context_switch(next); } @@ -286,7 +285,7 @@ static void lguest_write_idt_entry(gate_desc *dt, /* Keep the local copy up to date. */ native_write_idt_entry(dt, entrynum, g); /* Tell Host about this new entry. */ - kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]); + hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1], 0); } /* @@ -300,7 +299,7 @@ static void lguest_load_idt(const struct desc_ptr *desc) struct desc_struct *idt = (void *)desc->address; for (i = 0; i < (desc->size+1)/8; i++) - kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b); + hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0); } /* @@ -321,7 +320,7 @@ static void lguest_load_gdt(const struct desc_ptr *desc) struct desc_struct *gdt = (void *)desc->address; for (i = 0; i < (desc->size+1)/8; i++) - kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b); + hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0); } /* @@ -334,8 +333,8 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, { native_write_gdt_entry(dt, entrynum, desc, type); /* Tell Host about this new entry. */ - kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum, - dt[entrynum].a, dt[entrynum].b); + hcall(LHCALL_LOAD_GDT_ENTRY, entrynum, + dt[entrynum].a, dt[entrynum].b, 0); } /* @@ -931,7 +930,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta, } /* Please wake us this far in the future. */ - kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta); + hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0, 0); return 0; } @@ -942,7 +941,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: /* A 0 argument shuts the clock down. */ - kvm_hypercall0(LHCALL_SET_CLOCKEVENT); + hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0, 0); break; case CLOCK_EVT_MODE_ONESHOT: /* This is what we expect. */ @@ -1100,7 +1099,7 @@ static void set_lguest_basic_apic_ops(void) /* STOP! Until an interrupt comes in. */ static void lguest_safe_halt(void) { - kvm_hypercall0(LHCALL_HALT); + hcall(LHCALL_HALT, 0, 0, 0, 0); } /* @@ -1112,8 +1111,8 @@ static void lguest_safe_halt(void) */ static void lguest_power_off(void) { - kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"), - LGUEST_SHUTDOWN_POWEROFF); + hcall(LHCALL_SHUTDOWN, __pa("Power down"), + LGUEST_SHUTDOWN_POWEROFF, 0, 0); } /* @@ -1123,7 +1122,7 @@ static void lguest_power_off(void) */ static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) { - kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF); + hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0, 0); /* The hcall won't return, but to keep gcc happy, we're "done". */ return NOTIFY_DONE; } @@ -1162,7 +1161,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) len = sizeof(scratch) - 1; scratch[len] = '\0'; memcpy(scratch, buf, len); - kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch)); + hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0); /* This routine returns the number of bytes actually written. */ return len; @@ -1174,7 +1173,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) */ static void lguest_restart(char *reason) { - kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART); + hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0); } /*G:050 diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S index 27eac0f..4f420c2f 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S @@ -32,7 +32,7 @@ ENTRY(lguest_entry) */ movl $LHCALL_LGUEST_INIT, %eax movl $lguest_data - __PAGE_OFFSET, %ebx - .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */ + int $LGUEST_TRAP_ENTRY /* Set up the initial stack so we can run C code. */ movl $(init_thread_union+THREAD_SIZE),%esp diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 07090f3..69c84a1 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c @@ -178,7 +178,7 @@ static void set_status(struct virtio_device *vdev, u8 status) /* We set the status. */ to_lgdev(vdev)->desc->status = status; - kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset); + hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0); } static void lg_set_status(struct virtio_device *vdev, u8 status) @@ -229,7 +229,7 @@ static void lg_notify(struct virtqueue *vq) */ struct lguest_vq_info *lvq = vq->priv; - kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT); + hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0); } /* An extern declaration inside a C file is bad form. Don't do it. */ -- cgit v1.1 From b331439dfd41dc813b3557ca5927a3a644f35792 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 14 Apr 2010 14:33:57 +0200 Subject: ALSA: hda - Fix control element allocations in VIA codec parser The commit 5b0cb1d850c26893b1468b3a519433a1b7a176be ALSA: hda - add more NID->Control mapping breaks the control element allocation by returning a wrong value. Let's fix it. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 9ddc373..be12954 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, knew->name = kstrdup(tmpl->name, GFP_KERNEL); if (!knew->name) return NULL; - return 0; + return knew; } static void via_free_kctls(struct hda_codec *codec) -- cgit v1.1 From 3d83e577a8206f0f3822a3840e12f76477142ba2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 14 Apr 2010 14:36:23 +0200 Subject: ALSA: hda - Avoid invalid "Independent HP" control for VIA codecs Some VIA codecs have no multiple source selection for headphone pins, thus it's useless (and wrong) to create "Independent HP" control on them. This patch adds the check of connections to skip the control in such a case. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index be12954..7345381 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = { }, }; -static int via_hp_build(struct via_spec *spec) +static int via_hp_build(struct hda_codec *codec) { + struct via_spec *spec = codec->spec; struct snd_kcontrol_new *knew; hda_nid_t nid; - - knew = via_clone_control(spec, &via_hp_mixer[0]); - if (knew == NULL) - return -ENOMEM; + int nums; + hda_nid_t conn[HDA_MAX_CONNECTIONS]; switch (spec->codec_type) { case VT1718S: @@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec) break; } + nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); + if (nums <= 1) + return 0; + + knew = via_clone_control(spec, &via_hp_mixer[0]); + if (knew == NULL) + return -ENOMEM; + knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; knew->private_value = nid; @@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); return 1; @@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); return 1; @@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); return 1; @@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); return 1; @@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); return 1; } @@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); @@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); @@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); return 1; } @@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec, /* Line-Out: PortE */ err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Master Front Playback Volume", + "Front Playback Volume", HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); if (err < 0) return err; err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, - "Master Front Playback Switch", + "Front Playback Switch", HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT)); if (err < 0) return err; @@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); return 1; } -- cgit v1.1 From 328a2c22abd08911e37fa66f1358f829cecd72e9 Mon Sep 17 00:00:00 2001 From: Jerome Oufella Date: Wed, 14 Apr 2010 16:14:07 +0200 Subject: hwmon: (sht15) Fix sht15_calc_temp interpolation function I discovered two issues. First the previous sht15_calc_temp() loop did not iterate through the temppoints array since the (data->supply_uV > temppoints[i - 1].vdd) test is always true in this direction. Also the two-points linear interpolation function was returning biased values due to a stray division by 1000 which shouldn't be there. [JD: Also change the default value for d1 from 0 to something saner.] Signed-off-by: Jerome Oufella Acked-by: Jonathan Cameron Signed-off-by: Jean Delvare Cc: stable@kernel.org --- drivers/hwmon/sht15.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 6b2d8ae..9a15b1a 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -303,13 +303,13 @@ error_ret: **/ static inline int sht15_calc_temp(struct sht15_data *data) { - int d1 = 0; + int d1 = temppoints[0].d1; int i; - for (i = 1; i < ARRAY_SIZE(temppoints); i++) + for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--) /* Find pointer to interpolate */ if (data->supply_uV > temppoints[i - 1].vdd) { - d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd) + d1 = (data->supply_uV - temppoints[i - 1].vdd) * (temppoints[i].d1 - temppoints[i - 1].d1) / (temppoints[i].vdd - temppoints[i - 1].vdd) + temppoints[i - 1].d1; -- cgit v1.1 From c7a78d2c2e2537fd24903e966f34aae50319d587 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 14 Apr 2010 16:14:08 +0200 Subject: hwmon: (sht15) Properly handle the case CONFIG_REGULATOR=n When CONFIG_REGULATOR isn't set, regulator_get_voltage() returns 0. Properly handle this case by not trusting the value. Reported-by: Jerome Oufella Signed-off-by: Jean Delvare Cc: Jonathan Cameron Acked-by: Mark Brown Cc: stable@kernel.org --- drivers/hwmon/sht15.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 9a15b1a..a610e78 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -542,7 +542,12 @@ static int __devinit sht15_probe(struct platform_device *pdev) /* If a regulator is available, query what the supply voltage actually is!*/ data->reg = regulator_get(data->dev, "vcc"); if (!IS_ERR(data->reg)) { - data->supply_uV = regulator_get_voltage(data->reg); + int voltage; + + voltage = regulator_get_voltage(data->reg); + if (voltage) + data->supply_uV = voltage; + regulator_enable(data->reg); /* setup a notifier block to update this if another device * causes the voltage to change */ -- cgit v1.1 From a00afb97e23fd904b12a3f4de3237d8ab2f68738 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 14 Apr 2010 16:14:09 +0200 Subject: hwmon: (it87) Don't arbitrarily enable temperature channels Temperature channels can be used in 2 different modes (thermistor and thermal diode) and we don't know which one, if any, is correct for every given board. So don't arbitrarily choose one. Instead, leave the temperature channels untouched. They can be configured from user-space if needed anyway. Signed-off-by: Jean Delvare --- drivers/hwmon/it87.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 1002bef..5e39e2d 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -545,6 +545,7 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); + data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); data->sensor &= ~(1 << nr); data->sensor &= ~(8 << nr); if (val == 2) { /* backwards compatibility */ @@ -1841,14 +1842,10 @@ static void __devinit it87_init_device(struct platform_device *pdev) it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); } - /* Check if temperature channels are reset manually or by some reason */ - tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE); - if ((tmp & 0x3f) == 0) { - /* Temp1,Temp3=thermistor; Temp2=thermal diode */ - tmp = (tmp & 0xc0) | 0x2a; - it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp); - } - data->sensor = tmp; + /* Temperature channels are not forcibly enabled, as they can be + * set to two different sensor types and we can't guess which one + * is correct for a given system. These channels can be enabled at + * run-time through the temp{1-3}_type sysfs accessors if needed. */ /* Check if voltage monitors are reset manually or by some reason */ tmp = it87_read_value(data, IT87_REG_VIN_ENABLE); -- cgit v1.1 From 8acf07c5a7674e53f2d320d540aec5d714b105cf Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 14 Apr 2010 16:14:09 +0200 Subject: hwmon: (it87) Properly handle wrong sensor type requests Currently, if someone tries to set the thermal sensor type to an unsupported value, subsequent accesses to the chip may temporarily show the sensor in question as disabled. Use a temporary variable and only update the cached value on success, to prevent such confusion. Signed-off-by: Jean Delvare --- drivers/hwmon/it87.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 5e39e2d..a65ba31 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -539,15 +539,14 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, struct it87_data *data = dev_get_drvdata(dev); long val; + u8 reg; if (strict_strtol(buf, 10, &val) < 0) return -EINVAL; - mutex_lock(&data->update_lock); - - data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); - data->sensor &= ~(1 << nr); - data->sensor &= ~(8 << nr); + reg = it87_read_value(data, IT87_REG_TEMP_ENABLE); + reg &= ~(1 << nr); + reg &= ~(8 << nr); if (val == 2) { /* backwards compatibility */ dev_warn(dev, "Sensor type 2 is deprecated, please use 4 " "instead\n"); @@ -555,13 +554,14 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, } /* 3 = thermal diode; 4 = thermistor; 0 = disabled */ if (val == 3) - data->sensor |= 1 << nr; + reg |= 1 << nr; else if (val == 4) - data->sensor |= 8 << nr; - else if (val != 0) { - mutex_unlock(&data->update_lock); + reg |= 8 << nr; + else if (val != 0) return -EINVAL; - } + + mutex_lock(&data->update_lock); + data->sensor = reg; it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); mutex_unlock(&data->update_lock); return count; -- cgit v1.1 From 2b3d1d87eaabf422a42440351ff3be1792d35852 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 14 Apr 2010 16:14:10 +0200 Subject: hwmon: (it87) Invalidate cache on temperature sensor change When any temperature sensor type is changed, the corresponding temperature value needs to be updated. The register caching mechanism may delay this update, so we want to invalidate the cache to force an immediate update. Signed-off-by: Jean Delvare --- drivers/hwmon/it87.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index a65ba31..5be09c0 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -563,6 +563,7 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); data->sensor = reg; it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); + data->valid = 0; /* Force cache refresh */ mutex_unlock(&data->update_lock); return count; } -- cgit v1.1 From e1741712e85cec8004c7eeeea81186618f78eff1 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Wed, 14 Apr 2010 16:14:10 +0200 Subject: hwmon: (applesmc) Add iMac9,1 and MacBookPro2,2 support Add the iMac9,1 and the MacBookPro2,2 temperature sensors to hwmon driver applesmc to fix kernel bug #14429: https://bugzilla.kernel.org/show_bug.cgi?id=14429 Signed-off-by: Justin P. Mattock Acked-by: Nicolas Boichat Signed-off-by: Jean Delvare --- drivers/hwmon/applesmc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index c1605b5..0f28d91 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -142,6 +142,12 @@ static const char *temperature_sensors_sets[][41] = { "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S", "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S", NULL }, +/* Set 17: iMac 9,1 */ + { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P", + "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL }, +/* Set 18: MacBook Pro 2,2 */ + { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0", + "Th0H", "Th1H", "Tm0P", "Ts0P", NULL }, }; /* List of keys used to read/write fan speeds */ @@ -1350,6 +1356,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { { .accelerometer = 1, .light = 1, .temperature_set = 15 }, /* MacPro3,1: temperature set 16 */ { .accelerometer = 0, .light = 0, .temperature_set = 16 }, +/* iMac 9,1: light sensor only, temperature set 17 */ + { .accelerometer = 0, .light = 0, .temperature_set = 17 }, +/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */ + { .accelerometer = 1, .light = 1, .temperature_set = 18 }, }; /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". @@ -1375,6 +1385,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") }, &applesmc_dmi_data[9]}, + { applesmc_dmi_match, "Apple MacBook Pro 2,2", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") }, + &applesmc_dmi_data[18]}, { applesmc_dmi_match, "Apple MacBook Pro", { DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, @@ -1415,6 +1429,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, &applesmc_dmi_data[4]}, + { applesmc_dmi_match, "Apple iMac 9,1", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") }, + &applesmc_dmi_data[17]}, { applesmc_dmi_match, "Apple iMac 8", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") }, -- cgit v1.1 From d618540fb3e5b74e16aec8201d2d0de6f02633cb Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Wed, 14 Apr 2010 16:14:11 +0200 Subject: hwmon: (applesmc) Switch maintainers Nicolas has expressed a wish to be relieved from the maintenance of applesmc, so we simply switch maintainer with this patch. Signed-off-by: Henrik Rydberg Acked-by: Nicolas Boichat Signed-off-by: Jean Delvare --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5b42290..a0e3c3a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -485,8 +485,8 @@ S: Maintained F: drivers/input/mouse/bcm5974.c APPLE SMC DRIVER -M: Nicolas Boichat -L: mactel-linux-devel@lists.sourceforge.net +M: Henrik Rydberg +L: lm-sensors@lm-sensors.org S: Maintained F: drivers/hwmon/applesmc.c -- cgit v1.1 From 4e310fda91cb095915395f811d10b2c900c9589e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 14 Apr 2010 09:27:40 -0700 Subject: vsprintf: Change struct printf_spec.precision from s8 to s16 Commit ef0658f3de484bf9b173639cd47544584e01efa5 changed precision from int to s8. There is existing kernel code that uses a larger precision. An example from the audit code: vsnprintf(...,..., " msg='%.1024s'", (char *)data); which overflows precision and truncates to nothing. Extending precision size fixes the audit system issue. Other changes: Change the size of the struct printf_spec.type from u16 to u8 so sizeof(struct printf_spec) stays as small as possible. Reorder the struct members so sizeof(struct printf_spec) remains 64 bits without alignment holes. Document the struct members a bit more. Original-patch-by: Eric Paris Signed-off-by: Joe Perches Tested-by: Justin P. Mattock Signed-off-by: Linus Torvalds --- lib/vsprintf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 24112e5..7376b7c 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -408,12 +408,12 @@ enum format_type { }; struct printf_spec { - u16 type; - s16 field_width; /* width of output field */ + u8 type; /* format_type enum */ u8 flags; /* flags to number() */ - u8 base; - s8 precision; /* # of digits/chars */ - u8 qualifier; + u8 base; /* number base, 8, 10 or 16 only */ + u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */ + s16 field_width; /* width of output field */ + s16 precision; /* # of digits/chars */ }; static char *number(char *buf, char *end, unsigned long long num, -- cgit v1.1 From 1aac4effad4ea52da94eb13b12e0ca1731407ee4 Mon Sep 17 00:00:00 2001 From: Maxim Kuvyrkov Date: Wed, 3 Mar 2010 16:53:45 +0300 Subject: m68k: Fix `struct sigcontext' for ColdFire LibSegFault uses piggybacks sc_fpstate field of the `struct sigcontext' and this patch avoids LibSegFault overflowing this field. Also this removes an unnecessary divergence from classic m68k. Signed-off-by: Maxim Kuvyrkov Signed-off-by: Geert Uytterhoeven --- arch/m68k/include/asm/sigcontext.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h index 1320eaa..a29dd74 100644 --- a/arch/m68k/include/asm/sigcontext.h +++ b/arch/m68k/include/asm/sigcontext.h @@ -17,13 +17,11 @@ struct sigcontext { #ifndef __uClinux__ # ifdef __mcoldfire__ unsigned long sc_fpregs[2][2]; /* room for two fp registers */ - unsigned long sc_fpcntl[3]; - unsigned char sc_fpstate[16+6*8]; # else unsigned long sc_fpregs[2*3]; /* room for two fp registers */ +# endif unsigned long sc_fpcntl[3]; unsigned char sc_fpstate[216]; -# endif #endif }; -- cgit v1.1 From b560177f3e1c6b2d75b220d41ae72636243475c4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 21 Mar 2010 10:52:21 +0100 Subject: m68k: Fix asm constraints for atomic_sub_and_test() and atomic_add_negative() Recently, we started seeing this on allmodconfig builds: CC mm/memcontrol.o {standard input}: Assembler messages: {standard input}:4076: Error: operands mismatch -- statement `subl 12(%fp),170(%a0)' ignored Correct the asm constraint, like done for m68knommu. Signed-off-by: Geert Uytterhoeven --- arch/m68k/include/asm/atomic_mm.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/m68k/include/asm/atomic_mm.h b/arch/m68k/include/asm/atomic_mm.h index 88b7af2..d9d2ed6 100644 --- a/arch/m68k/include/asm/atomic_mm.h +++ b/arch/m68k/include/asm/atomic_mm.h @@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *v, int new) static inline int atomic_sub_and_test(int i, atomic_t *v) { char c; - __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i)); + __asm__ __volatile__("subl %2,%1; seq %0" + : "=d" (c), "+m" (*v) + : "id" (i)); return c != 0; } static inline int atomic_add_negative(int i, atomic_t *v) { char c; - __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i)); + __asm__ __volatile__("addl %2,%1; smi %0" + : "=d" (c), "+m" (*v) + : "id" (i)); return c != 0; } -- cgit v1.1 From 6c9ff1013b7a21099da838eeef7c3f23ee347957 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Mon, 15 Mar 2010 10:42:11 -0400 Subject: SELinux: Reduce max avtab size to avoid page allocation failures Reduce MAX_AVTAB_HASH_BITS so that the avtab allocation is an order 2 allocation rather than an order 4 allocation on x86_64. This addresses reports of page allocation failures: http://marc.info/?l=selinux&m=126757230625867&w=2 https://bugzilla.redhat.com/show_bug.cgi?id=570433 Reported-by: Russell Coker Signed-off-by: Stephen D. Smalley Acked-by: Eric Paris Signed-off-by: James Morris --- security/selinux/ss/avtab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 8da6a84..cd4f734 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified void avtab_cache_init(void); void avtab_cache_destroy(void); -#define MAX_AVTAB_HASH_BITS 13 +#define MAX_AVTAB_HASH_BITS 11 #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) #define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) #define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS -- cgit v1.1 From 565a79f74af96ae90dfec411da14dc38d2cd56bc Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Apr 2010 09:17:31 +0200 Subject: ASoC: imx-ssi: increase minimum periods to 4 Currently the notification of elapsed periods is not very exact. Increase minimum periods to 4 as suggested by Liam Girdwood. Signed-off-by: Sascha Hauer Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/imx/imx-pcm-fiq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index 64df813..98ab331 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c @@ -174,7 +174,7 @@ static struct snd_pcm_hardware snd_imx_hardware = { .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, .period_bytes_min = 128, .period_bytes_max = 16 * 1024, - .periods_min = 2, + .periods_min = 4, .periods_max = 255, .fifo_size = 0, }; -- cgit v1.1 From d1501ea844eefdf925f6b711875b4b2b928fddf8 Mon Sep 17 00:00:00 2001 From: Joerg Schirottke Date: Thu, 15 Apr 2010 08:37:41 +0200 Subject: ALSA: hda - add a quirk for Clevo M570U laptop Added the matching model for Clevo laptop M570U. Signed-off-by: Joerg Schirottke Tested-by: Maximilian Gerhard Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4b35176..aad1627 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9350,6 +9350,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), -- cgit v1.1 From 8815cd030fdd73932a791d1f06194c8db807cde7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Apr 2010 09:02:41 +0200 Subject: ALSA: hda - Add position_fix quirk for Biostar mobo The Biostar mobo seems to give a wrong DMA position, resulting in stuttering or skipping sounds on 2.6.34. Since the commit 7b3a177b0d4f92b3431b8dca777313a07533a710, "ALSA: pcm_lib: fix "something must be really wrong" condition", makes the position check more strictly, the DMA position problem is revealed more clearly now. The fix is to use only LPIB for obtaining the position, i.e. passing position_fix=1. This patch adds a static quirk to achieve it as default. Reported-by: Frank Griffin Cc: Eric Piel Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index f8fd586..f669442 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2272,6 +2272,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), {} }; -- cgit v1.1 From 19b3eecc21b65a24b0aae2684ca0c8e1b99ef802 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 11 Apr 2010 11:52:12 +0200 Subject: firewire: cdev: change license of exported header files to MIT license MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Among else, this allows projects like libdc1394 to carry copies of the ABI related header files without them or distributors having to worry about effects on the project's overall license terms. Switch to MIT license as suggested by Kristian. Also update the year in the copyright statement according to source history. Cc: Jay Fenlason Acked-by: Clemens Ladisch Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- include/linux/firewire-cdev.h | 35 ++++++++++++++++++++--------------- include/linux/firewire-constants.h | 29 +++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 6ffb24a..81f3b14 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h @@ -1,21 +1,26 @@ /* * Char device interface. * - * Copyright (C) 2005-2006 Kristian Hoegsberg - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Copyright (C) 2005-2007 Kristian Hoegsberg + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #ifndef _LINUX_FIREWIRE_CDEV_H diff --git a/include/linux/firewire-constants.h b/include/linux/firewire-constants.h index b316770..9c63f06 100644 --- a/include/linux/firewire-constants.h +++ b/include/linux/firewire-constants.h @@ -1,3 +1,28 @@ +/* + * IEEE 1394 constants. + * + * Copyright (C) 2005-2007 Kristian Hoegsberg + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + #ifndef _LINUX_FIREWIRE_CONSTANTS_H #define _LINUX_FIREWIRE_CONSTANTS_H @@ -21,7 +46,7 @@ #define EXTCODE_WRAP_ADD 0x6 #define EXTCODE_VENDOR_DEPENDENT 0x7 -/* Juju specific tcodes */ +/* Linux firewire-core (Juju) specific tcodes */ #define TCODE_LOCK_MASK_SWAP (0x10 | EXTCODE_MASK_SWAP) #define TCODE_LOCK_COMPARE_SWAP (0x10 | EXTCODE_COMPARE_SWAP) #define TCODE_LOCK_FETCH_ADD (0x10 | EXTCODE_FETCH_ADD) @@ -36,7 +61,7 @@ #define RCODE_TYPE_ERROR 0x6 #define RCODE_ADDRESS_ERROR 0x7 -/* Juju specific rcodes */ +/* Linux firewire-core (Juju) specific rcodes */ #define RCODE_SEND_ERROR 0x10 #define RCODE_CANCELLED 0x11 #define RCODE_BUSY 0x12 -- cgit v1.1 From 8392609969b3b37a4da5cff08161661f7a8c16af Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 14 Apr 2010 09:17:30 +0200 Subject: ASoC: imx-ssi: do not call hrtimer_disable in trigger function Doing so causes a deadlock, so just signal the timer to stop using an atomic variable. Signed-off-by: Sascha Hauer Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/imx/imx-pcm-fiq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index 98ab331..ecec332 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c @@ -41,6 +41,7 @@ struct imx_pcm_runtime_data { struct hrtimer hrt; int poll_time_ns; struct snd_pcm_substream *substream; + atomic_t running; }; static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) @@ -52,6 +53,9 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) struct pt_regs regs; unsigned long delta; + if (!atomic_read(&iprtd->running)) + return HRTIMER_NORESTART; + get_fiq_regs(®s); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -129,6 +133,7 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + atomic_set(&iprtd->running, 1); hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), HRTIMER_MODE_REL); if (++fiq_enable == 1) @@ -139,11 +144,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - hrtimer_cancel(&iprtd->hrt); + atomic_set(&iprtd->running, 0); + if (--fiq_enable == 0) disable_fiq(imx_pcm_fiq); - break; default: return -EINVAL; @@ -190,6 +195,7 @@ static int snd_imx_open(struct snd_pcm_substream *substream) iprtd->substream = substream; + atomic_set(&iprtd->running, 0); hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); iprtd->hrt.function = snd_hrtimer_callback; -- cgit v1.1 From 41b97ab5050088cd23692d578e7294c7be26109a Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 15 Apr 2010 19:01:53 +0200 Subject: pcmcia: fix ioport size calculation in rsrc_nonstatic Size needs to be calculated after manipulating with the start value. Reported-by: Komuro Signed-off-by: Dominik Brodowski --- drivers/pcmcia/rsrc_nonstatic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 1178a82..a6eb7b5 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -810,7 +810,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) { struct socket_data *data = s->resource_data; - unsigned long size = end - start + 1; + unsigned long size; int ret = 0; #if defined(CONFIG_X86) @@ -820,6 +820,8 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start = 0x100; #endif + size = end - start + 1; + if (end < start) return -EINVAL; -- cgit v1.1 From 014f61504af276ba9d9544d8a7401d8f8526eb73 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 13 Apr 2010 23:07:52 -0700 Subject: Input: wacom - switch mode upon system resume When Wacom devices wake up from a sleep, the switch mode command (wacom_query_tablet_data) is needed before wacom_open is called. wacom_query_tablet_data should not be executed inside wacom_open since wacom_open is called more than once during probe. wacom_retrieve_hid_descriptor is removed from wacom_resume due to the fact that the required descriptors are stored properly upon system resume. Reported-and-tested-by: Anton Anikin Signed-off-by: Ping Cheng Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 8b5d287..f465025 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf) int rv; mutex_lock(&wacom->lock); - if (wacom->open) { + + /* switch to wacom mode first */ + wacom_query_tablet_data(intf, features); + + if (wacom->open) rv = usb_submit_urb(wacom->irq, GFP_NOIO); - /* switch to wacom mode if needed */ - if (!wacom_retrieve_hid_descriptor(intf, features)) - wacom_query_tablet_data(intf, features); - } else + else rv = 0; + mutex_unlock(&wacom->lock); return rv; -- cgit v1.1 From 77165a48edeaf4758588563c0592af6559e8b256 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 7 Apr 2010 13:17:22 +0530 Subject: [WATCHDOG] omap4: Fix WDT Kconfig This patch allows Watchdog timer to be selected for OMAP4 by fixing Kconfig entry Signed-off-by: Santosh Shilimkar Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 0e8468f..3a6aa0f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -194,10 +194,10 @@ config EP93XX_WATCHDOG config OMAP_WATCHDOG tristate "OMAP Watchdog" - depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP3 + depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS help - Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y' - here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer. + Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y' + here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer. config PNX4008_WATCHDOG tristate "PNX4008 Watchdog" -- cgit v1.1 From 0fb06571bbb5c72b4663c20f721323260ea802bf Mon Sep 17 00:00:00 2001 From: Luuk Paulussen Date: Thu, 15 Apr 2010 15:59:10 +1200 Subject: [WATCHDOG] fixed book E watchdog period register mask. A previous fix changed the WDTP function to use the period directly, rather than subtracting from 63. However the mask generation was not changed, so the mask was coming out as 0. This patch fixes it. Signed-off-by: Luuk Paulussen Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/booke_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 8b724aa..500d383 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c @@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT; #ifdef CONFIG_FSL_BOOKE #define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) -#define WDTP_MASK (WDTP(0)) +#define WDTP_MASK (WDTP(0x3f)) #else #define WDTP(x) (TCR_WP(x)) #define WDTP_MASK (TCR_WP_MASK) -- cgit v1.1 From b1183e064a3f95d27351b2d2c811b50bf4d770a4 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 9 Apr 2010 17:43:33 +0100 Subject: [WATCHDOG] max63xx: be careful when disabling the watchdog When shutting down the watchdog timer, special care must be taken not to overwrite other bits in the register, as it may be shared with other peripherals. For example, on the Arcom Vulcan, the register is shared between the watchdog and the PCI reset line... Signed-off-by: Marc Zyngier Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/max63xx_wdt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c index 75f3a83..3053ff0 100644 --- a/drivers/watchdog/max63xx_wdt.c +++ b/drivers/watchdog/max63xx_wdt.c @@ -154,9 +154,14 @@ static void max63xx_wdt_enable(struct max63xx_timeout *entry) static void max63xx_wdt_disable(void) { + u8 val; + spin_lock(&io_lock); - __raw_writeb(3, wdt_base); + val = __raw_readb(wdt_base); + val &= ~MAX6369_WDSET; + val |= 3; + __raw_writeb(val, wdt_base); spin_unlock(&io_lock); -- cgit v1.1 From aebaec975f30c4db40bb418fe9117bb6b4655b1b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 7 Apr 2010 19:57:02 +0200 Subject: [WATCHDOG] max63xx driver depends on ioremap() Correct fix for the "ioremap() causes build failure on S390" should have been a dependancy on HAS_IOMEM. So we add this dependancy also (and leave the driver in the ARM section for now). Signed-off-by: Geert Uytterhoeven Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 3a6aa0f..0bf5020 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -302,7 +302,7 @@ config TS72XX_WATCHDOG config MAX63XX_WATCHDOG tristate "Max63xx watchdog" - depends on ARM + depends on ARM && HAS_IOMEM help Support for memory mapped max63{69,70,71,72,73,74} watchdog timer. -- cgit v1.1 From b6f8dd49dbdbfa60a33bba3d4b766fe341109b4b Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 13 Apr 2010 15:06:44 +1000 Subject: xfs: ensure that sync updates the log tail correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates to the VFS layer removed an extra ->sync_fs call into the filesystem during the sync process (from the quota code). Unfortunately the sync code was unknowingly relying on this call to make sure metadata buffers were flushed via a xfs_buftarg_flush() call to move the tail of the log forward in memory before the final transactions of the sync process were issued. As a result, the old code would write a very recent log tail value to the log by the end of the sync process, and so a subsequent crash would leave nothing for log recovery to do. Hence in qa test 182, log recovery only replayed a small handle for inode fsync transactions in this case. However, with the removal of the extra ->sync_fs call, the log tail was now not moved forward with the inode fsync transactions near the end of the sync procese the first (and only) buftarg flush occurred after these transactions went to disk. The result is that log recovery now sees a large number of transactions for metadata that is already on disk. This usually isn't a problem, but when the transactions include inode chunk allocation, the inode create transactions and all subsequent changes are replayed as we cannt rely on what is on disk is valid. As a result, if the inode was written and contains unlogged changes, the unlogged changes are lost, thereby violating sync semantics. The fix is to always issue a transaction after the buftarg flush occurs is the log iѕ not idle or covered. This results in a dummy transaction being written that contains the up-to-date log tail value, which will be very recent. Indeed, it will be at least as recent as the old code would have left on disk, so log recovery will behave exactly as it used to in this situation. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Alex Elder --- fs/xfs/xfs_log.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index e8fba92..2be0191 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -745,9 +745,16 @@ xfs_log_move_tail(xfs_mount_t *mp, /* * Determine if we have a transaction that has gone to disk - * that needs to be covered. Log activity needs to be idle (no AIL and - * nothing in the iclogs). And, we need to be in the right state indicating - * something has gone out. + * that needs to be covered. To begin the transition to the idle state + * firstly the log needs to be idle (no AIL and nothing in the iclogs). + * If we are then in a state where covering is needed, the caller is informed + * that dummy transactions are required to move the log into the idle state. + * + * Because this is called as part of the sync process, we should also indicate + * that dummy transactions should be issued in anything but the covered or + * idle states. This ensures that the log tail is accurately reflected in + * the log at the end of the sync, hence if a crash occurrs avoids replay + * of transactions where the metadata is already on disk. */ int xfs_log_need_covered(xfs_mount_t *mp) @@ -759,17 +766,24 @@ xfs_log_need_covered(xfs_mount_t *mp) return 0; spin_lock(&log->l_icloglock); - if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || - (log->l_covered_state == XLOG_STATE_COVER_NEED2)) - && !xfs_trans_ail_tail(log->l_ailp) - && xlog_iclogs_empty(log)) { - if (log->l_covered_state == XLOG_STATE_COVER_NEED) - log->l_covered_state = XLOG_STATE_COVER_DONE; - else { - ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2); - log->l_covered_state = XLOG_STATE_COVER_DONE2; + switch (log->l_covered_state) { + case XLOG_STATE_COVER_DONE: + case XLOG_STATE_COVER_DONE2: + case XLOG_STATE_COVER_IDLE: + break; + case XLOG_STATE_COVER_NEED: + case XLOG_STATE_COVER_NEED2: + if (!xfs_trans_ail_tail(log->l_ailp) && + xlog_iclogs_empty(log)) { + if (log->l_covered_state == XLOG_STATE_COVER_NEED) + log->l_covered_state = XLOG_STATE_COVER_DONE; + else + log->l_covered_state = XLOG_STATE_COVER_DONE2; } + /* FALLTHRU */ + default: needed = 1; + break; } spin_unlock(&log->l_icloglock); return needed; -- cgit v1.1 From f1d486a3617a2f620b31224e4ace1496c4627e39 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 13 Apr 2010 15:06:45 +1000 Subject: xfs: don't warn on EAGAIN in inode reclaim Any inode reclaim flush that returns EAGAIN will result in the inode reclaim being attempted again later. There is no need to issue a warning into the logs about this situation. Signed-off-by: Dave Chinner Reviewed-by: Alex Elder Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 05cd853..fd96982 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -820,10 +820,10 @@ xfs_reclaim_inode( * call into reclaim to find it in a clean state instead of waiting for * it now. We also don't return errors here - if the error is transient * then the next reclaim pass will flush the inode, and if the error - * is permanent then the next sync reclaim will relcaim the inode and + * is permanent then the next sync reclaim will reclaim the inode and * pass on the error. */ - if (error && !XFS_FORCED_SHUTDOWN(ip->i_mount)) { + if (error && error != EAGAIN && !XFS_FORCED_SHUTDOWN(ip->i_mount)) { xfs_fs_cmn_err(CE_WARN, ip->i_mount, "inode 0x%llx background reclaim flush failed with %d", (long long)ip->i_ino, error); -- cgit v1.1 From 2060c44576c79086ff24718878d7edaa7384a985 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Fri, 16 Apr 2010 15:36:40 -0400 Subject: ACPI: EC: Limit burst to 64 bits access_bit_width field is u8 in ACPICA, thus 256 value written to it becomes 0, causing divide by zero later. Proper fix would be to remove access_bit_width at all, just because we already have access_byte_width, which is access_bit_width / 8. Limit access width to 64 bit for now. https://bugzilla.kernel.org/show_bug.cgi?id=15749 fixes regression caused by the fix for: https://bugzilla.kernel.org/show_bug.cgi?id=14667 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/acpica/exprep.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index a610ebe..2fbfe51 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -471,13 +471,18 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) /* allow full data read from EC address space */ if (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_EC) { - if (obj_desc->common_field.bit_length > 8) - obj_desc->common_field.access_bit_width = - ACPI_ROUND_UP(obj_desc->common_field. - bit_length, 8); + if (obj_desc->common_field.bit_length > 8) { + unsigned width = + ACPI_ROUND_BITS_UP_TO_BYTES( + obj_desc->common_field.bit_length); + // access_bit_width is u8, don't overflow it + if (width > 8) + width = 8; obj_desc->common_field.access_byte_width = - ACPI_DIV_8(obj_desc->common_field. - access_bit_width); + width; + obj_desc->common_field.access_bit_width = + 8 * width; + } } ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, -- cgit v1.1 From a8408c17d0038b76a83affb1b56dc18fa1e7ed86 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 17 Apr 2010 17:37:33 +0200 Subject: pcmcia: avoid late calls to pccard_validate_cis pccard_validate_cis() nowadays destroys the CIS cache. Therefore, calling it after card setup should be avoided. We can't control the deprecated PCMCIA ioctl (which is only used on ARM nowadays), but we can avoid -- and report -- any other calls. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cistpl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index f230f65..854959c 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info) if (!s) return -EINVAL; + if (s->functions) { + WARN_ON(1); + return -EINVAL; + } + /* We do not want to validate the CIS cache... */ mutex_lock(&s->ops_mutex); destroy_cis_cache(s); @@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, count = 0; else { struct pcmcia_socket *s; - unsigned int chains; + unsigned int chains = 1; if (off + count > size) count = size - off; @@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, if (!(s->state & SOCKET_PRESENT)) return -ENODEV; - if (pccard_validate_cis(s, &chains)) + if (!s->functions && pccard_validate_cis(s, &chains)) return -EIO; if (!chains) return -ENODATA; -- cgit v1.1 From 6f4567c8cf64d1887c8e993bbf066465262b392f Mon Sep 17 00:00:00 2001 From: Timur Maximov Date: Wed, 14 Apr 2010 19:06:57 +0400 Subject: serial_cs: MD55x support (PCMCIA GPRS/EDGE modem) (kernel 2.6.33) Many PCMCIA GPRS modems like: Onda Edge N100E, Novaway PC98 (OEM SPC98Z), Rovermate Edgus Adaptmate-039 and others have same construction and identification: lspcmcia -vvv Product Name: Generic Modem: MD55x 1.00 Serial number: xxxxx-xxx Identification: manf_id: 0x015d card_id: 0x4c45 function: 2 (serial) prod_id(1): "Generic" (0xc49e4731) prod_id(2): "Modem: MD55x" (0x8913b110) prod_id(3): "1.00" (0x83dbf271) prod_id(4): "Serial number: xxxxx-xxx" (0x73ee9514) Serial connection to GSM module based on Elan VPU16551 PCMCIA UART with datasheet recommeded 14.7456MHz crystal oscillator. By default serial_cs set UART clock == 1843200 Hz For correct work need set clock 14745600 Hz. This quirk already present in driver, only need add device in quirk list. Signed-off-by: Timur Maximov Acked-by: Alan Cox Signed-off-by: Dominik Brodowski --- drivers/serial/serial_cs.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 175d202..8cfa5b1 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -105,6 +105,10 @@ struct serial_cfg_mem { * manfid 0x0160, 0x0104 * This card appears to have a 14.7456MHz clock. */ +/* Generic Modem: MD55x (GPRS/EDGE) have + * Elan VPU16551 UART with 14.7456MHz oscillator + * manfid 0x015D, 0x4C45 + */ static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port) { port->uartclk = 14745600; @@ -196,6 +200,11 @@ static const struct serial_quirk quirks[] = { .multi = -1, .setup = quirk_setup_brainboxes_0104, }, { + .manfid = 0x015D, + .prodid = 0x4C45, + .multi = -1, + .setup = quirk_setup_brainboxes_0104, + }, { .manfid = MANFID_IBM, .prodid = ~0, .multi = -1, -- cgit v1.1 From 42d284b986105a6ed5ac386818cae093532b2c55 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 29 Mar 2010 17:35:24 +0200 Subject: drivers/pcmcia: Add missing local_irq_restore Use local_irq_restore in this error-handling case just like in the one just below. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E1; identifier f; @@ f (...) { <+... * local_irq_save (E1,...); ... when != E1 * return ...; ...+> } // Signed-off-by: Julia Lawall Signed-off-by: Dominik Brodowski --- drivers/pcmcia/db1xxx_ss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 6206408..2d48196 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -166,8 +166,10 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, IRQF_DISABLED, "pcmcia_insert", sock); - if (ret) + if (ret) { + local_irq_restore(flags); goto out1; + } ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, IRQF_DISABLED, "pcmcia_eject", sock); -- cgit v1.1 From 1b5331d9c6ae1f68db6359d227531ec42bc40d47 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Mon, 12 Apr 2010 20:21:53 +0000 Subject: drm/radeon/kms: print GPU family and device id when loading This will help figuring out GPU when looking at bugs log. Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_device.c | 53 +++++++++++++++++++++++++++++++++- drivers/gpu/drm/radeon/radeon_family.h | 3 +- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 60ec47b..5e03b14 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -35,6 +35,54 @@ #include "radeon.h" #include "atom.h" +static const char radeon_family_name[][16] = { + "R100", + "RV100", + "RS100", + "RV200", + "RS200", + "R200", + "RV250", + "RS300", + "RV280", + "R300", + "R350", + "RV350", + "RV380", + "R420", + "R423", + "RV410", + "RS400", + "RS480", + "RS600", + "RS690", + "RS740", + "RV515", + "R520", + "RV530", + "RV560", + "RV570", + "R580", + "R600", + "RV610", + "RV630", + "RV670", + "RV620", + "RV635", + "RS780", + "RS880", + "RV770", + "RV730", + "RV710", + "RV740", + "CEDAR", + "REDWOOD", + "JUNIPER", + "CYPRESS", + "HEMLOCK", + "LAST", +}; + /* * Clear GPU surface registers. */ @@ -525,7 +573,6 @@ int radeon_device_init(struct radeon_device *rdev, int r; int dma_bits; - DRM_INFO("radeon: Initializing kernel modesetting.\n"); rdev->shutdown = false; rdev->dev = &pdev->dev; rdev->ddev = ddev; @@ -537,6 +584,10 @@ int radeon_device_init(struct radeon_device *rdev, rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; rdev->gpu_lockup = false; rdev->accel_working = false; + + DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n", + radeon_family_name[rdev->family], pdev->vendor, pdev->device); + /* mutex initialization are all done here so we * can recall function without having locking issues */ mutex_init(&rdev->cs_mutex); diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 93c7d5d4..e329066 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h @@ -36,7 +36,7 @@ * Radeon chip families */ enum radeon_family { - CHIP_R100, + CHIP_R100 = 0, CHIP_RV100, CHIP_RS100, CHIP_RV200, @@ -99,4 +99,5 @@ enum radeon_chip_flags { RADEON_IS_PCI = 0x00800000UL, RADEON_IS_IGPGART = 0x01000000UL, }; + #endif -- cgit v1.1 From 30f69f3fb20bd719b5e1bf879339914063d38f47 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 16 Apr 2010 18:46:35 +0200 Subject: drm/radeon/kms: fix rs600 tlb flush Typo in in flush leaded to no flush of the RS600 tlb which ultimately leaded to massive system ram corruption, with this patch everythings seems to work properly. Signed-off-by: Jerome Glisse Cc: stable Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/rs600.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index abf824c..a81bc7a 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -159,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev) WREG32_MC(R_000100_MC_PT0_CNTL, tmp); tmp = RREG32_MC(R_000100_MC_PT0_CNTL); - tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1); + tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1); WREG32_MC(R_000100_MC_PT0_CNTL, tmp); tmp = RREG32_MC(R_000100_MC_PT0_CNTL); -- cgit v1.1 From b317a9ce2259e64258a802a5ca70dec45ac15dda Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 15 Apr 2010 16:54:38 -0400 Subject: drm/radeon/kms/atom: fix dual-link DVI on DCE3.2/4.0 Got broken during the evergreen merge. Fixes fdo bug 27001. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index c52fc30..9f7f56a 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -865,6 +865,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { if (dig->coherent_mode) args.v3.acConfig.fCoherentMode = 1; + if (radeon_encoder->pixel_clock > 165000) + args.v3.acConfig.fDualLinkConnector = 1; } } else if (ASIC_IS_DCE32(rdev)) { args.v2.acConfig.ucEncoderSel = dig->dig_encoder; @@ -888,6 +890,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { if (dig->coherent_mode) args.v2.acConfig.fCoherentMode = 1; + if (radeon_encoder->pixel_clock > 165000) + args.v2.acConfig.fDualLinkConnector = 1; } } else { args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; -- cgit v1.1 From 16823d16f55afc303af7864b9a055d8a1c012e1b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 16 Apr 2010 11:35:30 -0400 Subject: drm/radeon/kms/evergreen: don't enable hdmi audio stuff Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_audio.c | 2 +- drivers/gpu/drm/radeon/r600_hdmi.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index dac7042..1d89805 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -35,7 +35,7 @@ */ static int r600_audio_chipset_supported(struct radeon_device *rdev) { - return rdev->family >= CHIP_R600 + return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR) || rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740; diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 029fa14..2616b82 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -314,6 +314,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod struct radeon_device *rdev = dev->dev_private; uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; + if (ASIC_IS_DCE4(rdev)) + return; + if (!offset) return; @@ -484,6 +487,9 @@ void r600_hdmi_enable(struct drm_encoder *encoder) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + if (ASIC_IS_DCE4(rdev)) + return; + if (!radeon_encoder->hdmi_offset) { r600_hdmi_assign_block(encoder); if (!radeon_encoder->hdmi_offset) { @@ -525,6 +531,9 @@ void r600_hdmi_disable(struct drm_encoder *encoder) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + if (ASIC_IS_DCE4(rdev)) + return; + if (!radeon_encoder->hdmi_offset) { dev_err(rdev->dev, "Disabling not enabled HDMI\n"); return; -- cgit v1.1 From 08d075116db3592db218bfe0f554cd93c9e12505 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 15 Apr 2010 13:31:12 -0400 Subject: drm/radeon/kms: fix tv dac conflict resolver On systems with the tv dac shared between DVI and TV, we can only use the dac for one of the connectors. However, when using a digital monitor on the DVI port, you can use the dac for the TV connector just fine. Check the use_digital status when resolving the conflict. Fixes fdo bug 27649, possibly others. Signed-off-by: Alex Deucher Cc: stable Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_connectors.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 3bc2040..1331351 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -162,12 +162,14 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, { struct drm_device *dev = connector->dev; struct drm_connector *conflict; + struct radeon_connector *radeon_conflict; int i; list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { if (conflict == connector) continue; + radeon_conflict = to_radeon_connector(conflict); for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { if (conflict->encoder_ids[i] == 0) break; @@ -177,6 +179,9 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, if (conflict->status != connector_status_connected) continue; + if (radeon_conflict->use_digital) + continue; + if (priority == true) { DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); -- cgit v1.1 From a1a4b23b66039c814c3d3a9a28d76d34800eadc5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 9 Apr 2010 15:31:56 -0400 Subject: drm/radeon/kms: adjust pll settings for tv May fix fdo bug 26582. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index fd4ef6d..a87990b 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -521,6 +521,10 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) adjusted_clock = mode->clock * 2; + if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { + pll->algo = PLL_ALGO_LEGACY; + pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; + } } else { if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; -- cgit v1.1 From d3a67a43b0460bae3e2ac14092497833344ac10d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 13 Apr 2010 11:21:59 -0400 Subject: drm/radeon/kms: disable the tv encoder when tv/cv is not in use Switching between TV and VGA caused VGA to break on some systems since the TV encoder was left enabled when VGA was used. fixes fdo bug 25520. Signed-off-by: Alex Deucher Cc: stable Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 9f7f56a..30293be 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1377,8 +1377,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, case ENCODER_OBJECT_ID_INTERNAL_DAC2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: atombios_dac_setup(encoder, ATOM_ENABLE); - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) - atombios_tv_setup(encoder, ATOM_ENABLE); + if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { + if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) + atombios_tv_setup(encoder, ATOM_ENABLE); + else + atombios_tv_setup(encoder, ATOM_DISABLE); + } break; } atombios_apply_encoder_quirks(encoder, adjusted_mode); -- cgit v1.1 From f12eebb0acbaa6dcb60ed34451f5b159f509b2c0 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Sun, 11 Apr 2010 12:34:00 -0700 Subject: drivers/gpu/radeon: Add MSPOS regs to safe list. Permits MSAA and D3D-style rasterization. [airlied: add rs600] Signed-off-by: Corbin Simpson Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/reg_srcs/r300 | 2 ++ drivers/gpu/drm/radeon/reg_srcs/r420 | 2 ++ drivers/gpu/drm/radeon/reg_srcs/rs600 | 2 ++ drivers/gpu/drm/radeon/reg_srcs/rv515 | 2 ++ 4 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index 19c4663..1e97b2d 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 @@ -125,6 +125,8 @@ r300 0x4f60 0x4000 GB_VAP_RASTER_VTX_FMT_0 0x4004 GB_VAP_RASTER_VTX_FMT_1 0x4008 GB_ENABLE +0x4010 GB_MSPOS0 +0x4014 GB_MSPOS1 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index 989f7a0..e958980 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 @@ -125,6 +125,8 @@ r420 0x4f60 0x4000 GB_VAP_RASTER_VTX_FMT_0 0x4004 GB_VAP_RASTER_VTX_FMT_1 0x4008 GB_ENABLE +0x4010 GB_MSPOS0 +0x4014 GB_MSPOS1 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 6801b86..83e8bc0 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 @@ -125,6 +125,8 @@ rs600 0x6d40 0x4000 GB_VAP_RASTER_VTX_FMT_0 0x4004 GB_VAP_RASTER_VTX_FMT_1 0x4008 GB_ENABLE +0x4010 GB_MSPOS0 +0x4014 GB_MSPOS1 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 38abf63..7f44ada 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -158,6 +158,8 @@ rv515 0x6d40 0x4000 GB_VAP_RASTER_VTX_FMT_0 0x4004 GB_VAP_RASTER_VTX_FMT_1 0x4008 GB_ENABLE +0x4010 GB_MSPOS0 +0x4014 GB_MSPOS1 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE -- cgit v1.1 From cae94b0ad9d147152af77b971a7234faf20027a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 21 Feb 2010 21:24:15 +0100 Subject: drm/radeon/kms: allow R500 regs VAP_ALT_NUM_VERTICES and VAP_INDEX_OFFSET MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [airlied: fix V_A_N_V to not be safe and fix check to make sure only r500 - bump userspace version] Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 6 +++++- drivers/gpu/drm/radeon/r100_track.h | 1 + drivers/gpu/drm/radeon/r300.c | 15 +++++++++++---- drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- drivers/gpu/drm/radeon/reg_srcs/rv515 | 1 + 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e40dbdc..c06207e 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3011,7 +3011,11 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) } } prim_walk = (track->vap_vf_cntl >> 4) & 0x3; - nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; + if (track->vap_vf_cntl & (1 << 14)) { + nverts = track->vap_alt_nverts; + } else { + nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; + } switch (prim_walk) { case 1: for (i = 0; i < track->num_arrays; i++) { diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index b27a699..fadfe68 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -64,6 +64,7 @@ struct r100_cs_track { unsigned maxy; unsigned vtx_size; unsigned vap_vf_cntl; + unsigned vap_alt_nverts; unsigned immd_dwords; unsigned num_arrays; unsigned max_indx; diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 0e9eb76..2a9b594 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -729,6 +729,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p, /* VAP_VF_MAX_VTX_INDX */ track->max_indx = idx_value & 0x00FFFFFFUL; break; + case 0x2088: + /* VAP_ALT_NUM_VERTICES - only valid on r500 */ + if (p->rdev->family < CHIP_RV515) + goto fail; + track->vap_alt_nverts = idx_value & 0xFFFFFF; + break; case 0x43E4: /* SC_SCISSOR1 */ track->maxy = ((idx_value >> 13) & 0x1FFF) + 1; @@ -766,7 +772,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, tmp = idx_value & ~(0x7 << 16); tmp |= tile_flags; ib[idx] = tmp; - i = (reg - 0x4E38) >> 2; track->cb[i].pitch = idx_value & 0x3FFE; switch (((idx_value >> 21) & 0xF)) { @@ -1051,11 +1056,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p, break; /* fallthrough do not move */ default: - printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", - reg, idx); - return -EINVAL; + goto fail; } return 0; +fail: + printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", + reg, idx); + return -EINVAL; } static int r300_packet3_check(struct radeon_cs_parser *p, diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 055a517..4b05563 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -43,9 +43,10 @@ * - 2.0.0 - initial interface * - 2.1.0 - add square tiling interface * - 2.2.0 - add r6xx/r7xx const buffer support + * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 2 +#define KMS_DRIVER_MINOR 3 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 7f44ada..1e46233 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -35,6 +35,7 @@ rv515 0x6d40 0x1DA8 VAP_VPORT_ZSCALE 0x1DAC VAP_VPORT_ZOFFSET 0x2080 VAP_CNTL +0x208C VAP_INDEX_OFFSET 0x2090 VAP_OUT_VTX_FMT_0 0x2094 VAP_OUT_VTX_FMT_1 0x20B0 VAP_VTE_CNTL -- cgit v1.1 From bc293d62b26ec590afc90a9e0a31c45d355b7bd8 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 15 Apr 2010 12:50:39 -0700 Subject: rcu: Make RCU lockdep check the lockdep_recursion variable The lockdep facility temporarily disables lockdep checking by incrementing the current->lockdep_recursion variable. Such disabling happens in NMIs and in other situations where lockdep might expect to recurse on itself. This patch therefore checks current->lockdep_recursion, disabling RCU lockdep splats when this variable is non-zero. In addition, this patch removes the "likely()", as suggested by Lai Jiangshan. Reported-by: Frederic Weisbecker Reported-by: David Miller Tested-by: Frederic Weisbecker Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com Cc: eric.dumazet@gmail.com LKML-Reference: <20100415195039.GA22623@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar --- include/linux/rcupdate.h | 5 +---- kernel/rcupdate.c | 7 +++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 9f1ddfe..07db2fe 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -101,10 +101,7 @@ extern struct lockdep_map rcu_sched_lock_map; # define rcu_read_release_sched() \ lock_release(&rcu_sched_lock_map, 1, _THIS_IP_) -static inline int debug_lockdep_rcu_enabled(void) -{ - return likely(rcu_scheduler_active && debug_locks); -} +extern int debug_lockdep_rcu_enabled(void); /** * rcu_read_lock_held - might we be in RCU read-side critical section? diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 63fe254..03a7ea1 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -69,6 +69,13 @@ EXPORT_SYMBOL_GPL(rcu_scheduler_active); #ifdef CONFIG_DEBUG_LOCK_ALLOC +int debug_lockdep_rcu_enabled(void) +{ + return rcu_scheduler_active && debug_locks && + current->lockdep_recursion == 0; +} +EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled); + /** * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section? * -- cgit v1.1 From 6c94b1ee0ca2bfb526d779c088ec20da6a3761db Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 19 Apr 2010 01:30:51 -0700 Subject: sparc64: Fix PREEMPT_ACTIVE value. It currently overlaps the NMI bit. Signed-off-by: David S. Miller --- arch/sparc/include/asm/thread_info_64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 9e2d944..4827a3a 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -111,7 +111,7 @@ struct thread_info { #define THREAD_SHIFT PAGE_SHIFT #endif /* PAGE_SHIFT == 13 */ -#define PREEMPT_ACTIVE 0x4000000 +#define PREEMPT_ACTIVE 0x10000000 /* * macros/functions for gaining access to the thread information structure -- cgit v1.1 From 79b9517a33a283c5d9db875c263670ed1e055f7e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 19 Apr 2010 17:54:31 +1000 Subject: drm/radeon/kms: add FireMV 2400 PCI ID. This is an M24/X600 chip. From RH# 581927 cc: stable@kernel.org Signed-off-by: Dave Airlie --- include/drm/drm_pciids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 04a6ebc..2d428b0 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -6,6 +6,7 @@ {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \ -- cgit v1.1 From 07a71415d5f790385695784a9b0e554412ee95c3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 18 Apr 2010 22:07:33 +0300 Subject: pcmcia: fix error handling in cm4000_cs.c In the original code we used -ENODEV as the number of bytes to copy_to_user() and we didn't release the locks. Signed-off-by: Dan Carpenter Acked-by: Harald Welte Signed-off-by: Dominik Brodowski --- drivers/char/pcmcia/cm4000_cs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index c9bc896..90b199f 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */ /* last check before exit */ - if (!io_detect_cm4000(iobase, dev)) - count = -ENODEV; + if (!io_detect_cm4000(iobase, dev)) { + rc = -ENODEV; + goto release_io; + } if (test_bit(IS_INVREV, &dev->flags) && count > 0) str_invert_revert(dev->rbuf, count); if (copy_to_user(buf, dev->rbuf, count)) - return -EFAULT; + rc = -EFAULT; release_io: clear_bit(LOCK_IO, &dev->flags); -- cgit v1.1 From 76e506a754c9519ba0a948b475a62f31fac8b599 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 19 Apr 2010 11:53:17 -0700 Subject: Fix ISDN/Gigaset build failure Commit b91ecb00 ("gigaset: include cleanup cleanup") removed an implicit sched.h inclusion that came in via slab.h, and caused various compile problems as a result. This should fix it. Reported-by: Ingo Molnar Signed-off-by: Linus Torvalds --- drivers/isdn/gigaset/gigaset.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index d32efb6..05947f9 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -20,6 +20,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include -- cgit v1.1 From 3a60a1686f0d51c99bd0df8ac93050fb6dfce647 Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Mon, 22 Mar 2010 00:41:35 -0500 Subject: eCryptfs: Decrypt symlink target for stat size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a getattr handler for eCryptfs symlinks that is capable of reading the lower target and decrypting its path. Prior to this patch, a stat's st_size field would represent the strlen of the encrypted path, while readlink() would return the strlen of the decrypted path. This could lead to confusion in some userspace applications, since the two values should be equal. https://bugs.launchpad.net/bugs/524919 Reported-by: Loïc Minier Cc: stable@kernel.org Signed-off-by: Tyler Hicks --- fs/ecryptfs/inode.c | 100 +++++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index ddbd096..605f514 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -648,38 +648,17 @@ out_lock: return rc; } -static int -ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) +static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, + size_t *bufsiz) { + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); char *lower_buf; - size_t lower_bufsiz; - struct dentry *lower_dentry; - struct ecryptfs_mount_crypt_stat *mount_crypt_stat; - char *plaintext_name; - size_t plaintext_name_size; + size_t lower_bufsiz = PATH_MAX; mm_segment_t old_fs; int rc; - lower_dentry = ecryptfs_dentry_to_lower(dentry); - if (!lower_dentry->d_inode->i_op->readlink) { - rc = -EINVAL; - goto out; - } - mount_crypt_stat = &ecryptfs_superblock_to_private( - dentry->d_sb)->mount_crypt_stat; - /* - * If the lower filename is encrypted, it will result in a significantly - * longer name. If needed, truncate the name after decode and decrypt. - */ - if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) - lower_bufsiz = PATH_MAX; - else - lower_bufsiz = bufsiz; - /* Released in this function */ lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); - if (lower_buf == NULL) { - printk(KERN_ERR "%s: Out of memory whilst attempting to " - "kmalloc [%zd] bytes\n", __func__, lower_bufsiz); + if (!lower_buf) { rc = -ENOMEM; goto out; } @@ -689,29 +668,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) (char __user *)lower_buf, lower_bufsiz); set_fs(old_fs); - if (rc >= 0) { - rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, - &plaintext_name_size, - dentry, lower_buf, - rc); - if (rc) { - printk(KERN_ERR "%s: Error attempting to decode and " - "decrypt filename; rc = [%d]\n", __func__, - rc); - goto out_free_lower_buf; - } - /* Check for bufsiz <= 0 done in sys_readlinkat() */ - rc = copy_to_user(buf, plaintext_name, - min((size_t) bufsiz, plaintext_name_size)); - if (rc) - rc = -EFAULT; - else - rc = plaintext_name_size; - kfree(plaintext_name); - fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode); - } -out_free_lower_buf: + if (rc < 0) + goto out; + lower_bufsiz = rc; + rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, + lower_buf, lower_bufsiz); +out: kfree(lower_buf); + return rc; +} + +static int +ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) +{ + char *kbuf; + size_t kbufsiz, copied; + int rc; + + rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz); + if (rc) + goto out; + copied = min_t(size_t, bufsiz, kbufsiz); + rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied; + kfree(kbuf); + fsstack_copy_attr_atime(dentry->d_inode, + ecryptfs_dentry_to_lower(dentry)->d_inode); out: return rc; } @@ -1016,6 +997,28 @@ out: return rc; } +int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat) +{ + struct ecryptfs_mount_crypt_stat *mount_crypt_stat; + int rc = 0; + + mount_crypt_stat = &ecryptfs_superblock_to_private( + dentry->d_sb)->mount_crypt_stat; + generic_fillattr(dentry->d_inode, stat); + if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) { + char *target; + size_t targetsiz; + + rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz); + if (!rc) { + kfree(target); + stat->size = targetsiz; + } + } + return rc; +} + int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { @@ -1133,6 +1136,7 @@ const struct inode_operations ecryptfs_symlink_iops = { .put_link = ecryptfs_put_link, .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, + .getattr = ecryptfs_getattr_link, .setxattr = ecryptfs_setxattr, .getxattr = ecryptfs_getxattr, .listxattr = ecryptfs_listxattr, -- cgit v1.1 From cfce08c6bdfb20ade979284e55001ca1f100ed51 Mon Sep 17 00:00:00 2001 From: Christian Pulvermacher Date: Tue, 23 Mar 2010 11:51:38 -0500 Subject: ecryptfs: fix error code for missing xattrs in lower fs If the lower file system driver has extended attributes disabled, ecryptfs' own access functions return -ENOSYS instead of -EOPNOTSUPP. This breaks execution of programs in the ecryptfs mount, since the kernel expects the latter error when checking for security capabilities in xattrs. Signed-off-by: Christian Pulvermacher Cc: stable@kernel.org Signed-off-by: Tyler Hicks --- fs/ecryptfs/inode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 605f514..efd4f47d5 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -1043,7 +1043,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, lower_dentry = ecryptfs_dentry_to_lower(dentry); if (!lower_dentry->d_inode->i_op->setxattr) { - rc = -ENOSYS; + rc = -EOPNOTSUPP; goto out; } mutex_lock(&lower_dentry->d_inode->i_mutex); @@ -1061,7 +1061,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, int rc = 0; if (!lower_dentry->d_inode->i_op->getxattr) { - rc = -ENOSYS; + rc = -EOPNOTSUPP; goto out; } mutex_lock(&lower_dentry->d_inode->i_mutex); @@ -1088,7 +1088,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) lower_dentry = ecryptfs_dentry_to_lower(dentry); if (!lower_dentry->d_inode->i_op->listxattr) { - rc = -ENOSYS; + rc = -EOPNOTSUPP; goto out; } mutex_lock(&lower_dentry->d_inode->i_mutex); @@ -1105,7 +1105,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name) lower_dentry = ecryptfs_dentry_to_lower(dentry); if (!lower_dentry->d_inode->i_op->removexattr) { - rc = -ENOSYS; + rc = -EOPNOTSUPP; goto out; } mutex_lock(&lower_dentry->d_inode->i_mutex); -- cgit v1.1 From 133b8f9d632cc23715c6d72d1c5ac449e054a12a Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Fri, 19 Mar 2010 15:35:46 -0400 Subject: ecryptfs: fix use with tmpfs by removing d_drop from ecryptfs_destroy_inode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since tmpfs has no persistent storage, it pins all its dentries in memory so they have d_count=1 when other file systems would have d_count=0. ->lookup is only used to create new dentries. If the caller doesn't instantiate it, it's freed immediately at dput(). ->readdir reads directly from the dcache and depends on the dentries being hashed. When an ecryptfs mount is mounted, it associates the lower file and dentry with the ecryptfs files as they're accessed. When it's umounted and destroys all the in-memory ecryptfs inodes, it fput's the lower_files and d_drop's the lower_dentries. Commit 4981e081 added this and a d_delete in 2008 and several months later commit caeeeecf removed the d_delete. I believe the d_drop() needs to be removed as well. The d_drop effectively hides any file that has been accessed via ecryptfs from the underlying tmpfs since it depends on it being hashed for it to be accessible. I've removed the d_drop on my development node and see no ill effects with basic testing on both tmpfs and persistent storage. As a side effect, after ecryptfs d_drops the dentries on tmpfs, tmpfs BUGs on umount. This is due to the dentries being unhashed. tmpfs->kill_sb is kill_litter_super which calls d_genocide to drop the reference pinning the dentry. It skips unhashed and negative dentries, but shrink_dcache_for_umount_subtree doesn't. Since those dentries still have an elevated d_count, we get a BUG(). This patch removes the d_drop call and fixes both issues. This issue was reported at: https://bugzilla.novell.com/show_bug.cgi?id=567887 Reported-by: Árpád Bíró Signed-off-by: Jeff Mahoney Cc: Dustin Kirkland Cc: stable@kernel.org Signed-off-by: Tyler Hicks --- fs/ecryptfs/super.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index b15a43a..1a037f7 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c @@ -85,7 +85,6 @@ static void ecryptfs_destroy_inode(struct inode *inode) if (lower_dentry->d_inode) { fput(inode_info->lower_file); inode_info->lower_file = NULL; - d_drop(lower_dentry); } } ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); -- cgit v1.1 From 3a8380c0754a7972668a46f645930910e304095c Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Tue, 23 Mar 2010 18:09:02 -0500 Subject: eCryptfs: Copy lower directory inode times and size on link The timestamps and size of a lower inode involved in a link() call was being copied to the upper parent inode. Instead, we should be copying lower parent inode's timestamps and size to the upper parent inode. I discovered this bug using the POSIX test suite at Tuxera. Signed-off-by: Tyler Hicks --- fs/ecryptfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index efd4f47d5..15b4248 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -456,8 +456,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); if (rc) goto out_lock; - fsstack_copy_attr_times(dir, lower_new_dentry->d_inode); - fsstack_copy_inode_size(dir, lower_new_dentry->d_inode); + fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); + fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); old_dentry->d_inode->i_nlink = ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; i_size_write(new_dentry->d_inode, file_size_save); -- cgit v1.1 From 9f37622f897a90ad3c3da5c14d94d8f3ffc62b70 Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Thu, 25 Mar 2010 11:16:56 -0500 Subject: eCryptfs: Turn lower lookup error messages into debug messages Vaugue warnings about ENAMETOOLONG errors when looking up an encrypted file name have caused many users to become concerned about their data. Since this is a rather harmless condition, I'm moving this warning to only be printed when the ecryptfs_verbosity module param is 1. Signed-off-by: Tyler Hicks --- fs/ecryptfs/inode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 15b4248..b980fce 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -388,9 +388,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); if (IS_ERR(lower_dentry)) { rc = PTR_ERR(lower_dentry); - printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " - "lower_dentry = [%s]\n", __func__, rc, - ecryptfs_dentry->d_name.name); + ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " + "[%d] on lower_dentry = [%s]\n", __func__, rc, + encrypted_and_encoded_name); goto out_d_drop; } if (lower_dentry->d_inode) @@ -417,9 +417,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); if (IS_ERR(lower_dentry)) { rc = PTR_ERR(lower_dentry); - printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " - "lower_dentry = [%s]\n", __func__, rc, - encrypted_and_encoded_name); + ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " + "[%d] on lower_dentry = [%s]\n", __func__, rc, + encrypted_and_encoded_name); goto out_d_drop; } lookup_and_interpose: -- cgit v1.1 From baa06775e224e9f74e5c2de894c95cd49678beff Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 19 Apr 2010 13:46:48 -0700 Subject: sparc64: Use correct pt_regs in decode_access_size() error paths. Signed-off-by: David S. Miller --- arch/sparc/kernel/unaligned_64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index ebce430..c752c4c 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -50,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn) } /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */ -static inline int decode_access_size(unsigned int insn) +static inline int decode_access_size(struct pt_regs *regs, unsigned int insn) { unsigned int tmp; @@ -66,7 +66,7 @@ static inline int decode_access_size(unsigned int insn) return 2; else { printk("Impossible unaligned trap. insn=%08x\n", insn); - die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs); + die_if_kernel("Byte sized unaligned access?!?!", regs); /* GCC should never warn that control reaches the end * of this function without returning a value because @@ -286,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs) asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) { enum direction dir = decode_direction(insn); - int size = decode_access_size(insn); + int size = decode_access_size(regs, insn); int orig_asi, asi; current_thread_info()->kern_una_regs = regs; -- cgit v1.1 From e8a03feb54ca7f1768bbdc2b491f9ef654e6d01d Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Wed, 14 Apr 2010 17:59:28 -0400 Subject: rmap: add exclusively owned pages to the newest anon_vma The recent anon_vma fixes cause many anonymous pages to end up in the parent process anon_vma, even when the page is exclusively owned by the current process. Adding exclusively owned anonymous pages to the top anon_vma reduces rmap scanning overhead, especially in workloads with forking servers. This patch adds a parameter to __page_set_anon_rmap that can be used to indicate whether or not the added page is exclusively owned by the current process. Pages added through page_add_new_anon_rmap are exclusively owned by the current process, and can be added to the top anon_vma. Pages added through page_add_anon_rmap can be either shared or exclusively owned, so we do the conservative thing and add it to the oldest anon_vma. A next step would be to add the exclusive parameter to page_add_anon_rmap, to be used from functions where we do know for sure whether a page is exclusively owned. Signed-off-by: Rik van Riel Reviewed-by: Johannes Weiner Lightly-tested-by: Borislav Petkov Reviewed-by: Minchan Kim [ Edited to look nicer - Linus ] Signed-off-by: Linus Torvalds --- mm/rmap.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 4bad326..526704e 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -730,23 +730,28 @@ void page_move_anon_rmap(struct page *page, * @page: the page to add the mapping to * @vma: the vm area in which the mapping is added * @address: the user virtual address mapped + * @exclusive: the page is exclusively owned by the current process */ static void __page_set_anon_rmap(struct page *page, - struct vm_area_struct *vma, unsigned long address) + struct vm_area_struct *vma, unsigned long address, int exclusive) { - struct anon_vma_chain *avc; - struct anon_vma *anon_vma; + struct anon_vma *anon_vma = vma->anon_vma; - BUG_ON(!vma->anon_vma); + BUG_ON(!anon_vma); /* - * We must use the _oldest_ possible anon_vma for the page mapping! + * If the page isn't exclusively mapped into this vma, + * we must use the _oldest_ possible anon_vma for the + * page mapping! * - * So take the last AVC chain entry in the vma, which is the deepest - * ancestor, and use the anon_vma from that. + * So take the last AVC chain entry in the vma, which is + * the deepest ancestor, and use the anon_vma from that. */ - avc = list_entry(vma->anon_vma_chain.prev, struct anon_vma_chain, same_vma); - anon_vma = avc->anon_vma; + if (!exclusive) { + struct anon_vma_chain *avc; + avc = list_entry(vma->anon_vma_chain.prev, struct anon_vma_chain, same_vma); + anon_vma = avc->anon_vma; + } anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; page->mapping = (struct address_space *) anon_vma; @@ -802,7 +807,7 @@ void page_add_anon_rmap(struct page *page, VM_BUG_ON(!PageLocked(page)); VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end); if (first) - __page_set_anon_rmap(page, vma, address); + __page_set_anon_rmap(page, vma, address, 0); else __page_check_anon_rmap(page, vma, address); } @@ -824,7 +829,7 @@ void page_add_new_anon_rmap(struct page *page, SetPageSwapBacked(page); atomic_set(&page->_mapcount, 0); /* increment count (starts at -1) */ __inc_zone_page_state(page, NR_ANON_PAGES); - __page_set_anon_rmap(page, vma, address); + __page_set_anon_rmap(page, vma, address, 1); if (page_evictable(page, vma)) lru_cache_add_lru(page, LRU_ACTIVE_ANON); else -- cgit v1.1 From 01bf0b64579ead8a82e7cfc32ae44bc667e7ad0f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 19 Apr 2010 16:29:56 -0700 Subject: Linux 2.6.34-rc5 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9754615..fa1db90 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 34 -EXTRAVERSION = -rc4 -NAME = Man-Eating Seals of Antiquity +EXTRAVERSION = -rc5 +NAME = Sheep on Meth # *DOCUMENTATION* # To see a list of typical targets execute "make help" -- cgit v1.1 From b78315f051de8d207bead90470aa216c0617572b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 26 Mar 2010 11:07:16 -0700 Subject: drm: delay vblank cleanup until after driver unload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drivers may use vblank calls now (e.g. drm_vblank_off) in their unload paths, so don't clean up the vblank related structures until after driver unload. Signed-off-by: Jesse Barnes Reviewed-by: Kristian Høgsberg Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_stub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index ad73e14..543e79c1 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -515,8 +515,6 @@ void drm_put_dev(struct drm_device *dev) } driver = dev->driver; - drm_vblank_cleanup(dev); - drm_lastclose(dev); if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && @@ -536,6 +534,8 @@ void drm_put_dev(struct drm_device *dev) dev->agp = NULL; } + drm_vblank_cleanup(dev); + list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) drm_rmmap(dev, r_list->map); drm_ht_remove(&dev->map_hash); -- cgit v1.1 From 28a1f533ae8606020238b840b82ae70a3f87609e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 20 Apr 2010 00:48:37 -0700 Subject: sparc64: Fix hardirq tracing in trap return path. We can overflow the hardirq stack if we set the %pil here so early, just let the normal control flow do it. This is fine as we are allowed to do the actual IRQ enable at any point after we call trace_hardirqs_on. Signed-off-by: David S. Miller --- arch/sparc/kernel/rtrap_64.S | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 83f1873..090b9e9 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -130,7 +130,17 @@ rtrap_xcall: nop call trace_hardirqs_on nop - wrpr %l4, %pil + /* Do not actually set the %pil here. We will do that + * below after we clear PSTATE_IE in the %pstate register. + * If we re-enable interrupts here, we can recurse down + * the hardirq stack potentially endlessly, causing a + * stack overflow. + * + * It is tempting to put this test and trace_hardirqs_on + * call at the 'rt_continue' label, but that will not work + * as that path hits unconditionally and we do not want to + * execute this in NMI return paths, for example. + */ #endif rtrap_no_irq_enable: andcc %l1, TSTATE_PRIV, %l3 -- cgit v1.1 From 4cecd935f67bf46a9fe8037c710dd86651fcafe4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 20 Apr 2010 05:31:02 +0200 Subject: x86: correctly wire up the newuname system call Before commit e28cbf22933d0c0ccaf3c4c27a1a263b41f73859 ("improve sys_newuname() for compat architectures") 64-bit x86 had a private implementation of sys_uname which was just called sys_uname, which other architectures used for the old uname. Due to some merge issues with the uname refactoring patches we ended up calling the old uname version for both the old and new system call slots, which lead to the domainname filed never be set which caused failures with libnss_nis. Reported-and-tested-by: Andy Isaacson Signed-off-by: Christoph Hellwig Signed-off-by: Linus Torvalds --- arch/x86/ia32/ia32entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 59b4556..e790bc1 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -626,7 +626,7 @@ ia32_sys_call_table: .quad stub32_sigreturn .quad stub32_clone /* 120 */ .quad sys_setdomainname - .quad sys_uname + .quad sys_newuname .quad sys_modify_ldt .quad compat_sys_adjtimex .quad sys32_mprotect /* 125 */ -- cgit v1.1 From 62af9b520513d78484f22f874916dfacbc889ce0 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 19 Apr 2010 16:47:20 +0200 Subject: quota: Convert __DQUOT_PARANOIA symbol to standard config option Make __DQUOT_PARANOIA define from the old days a standard config option and turn it off by default. This gets rid of a quota warning about writes before quota is turned on for systems with ext4 root filesystem. Currently there's no way to legally solve this because /etc/mtab has to be written before quota is turned on on most systems. Signed-off-by: Jan Kara --- fs/quota/Kconfig | 8 ++++++++ fs/quota/dquot.c | 16 +++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/fs/quota/Kconfig b/fs/quota/Kconfig index dad7fb2..3e21b1e 100644 --- a/fs/quota/Kconfig +++ b/fs/quota/Kconfig @@ -33,6 +33,14 @@ config PRINT_QUOTA_WARNING Note that this behavior is currently deprecated and may go away in future. Please use notification via netlink socket instead. +config QUOTA_DEBUG + bool "Additional quota sanity checks" + depends on QUOTA + default n + help + If you say Y here, quota subsystem will perform some additional + sanity checks of quota internal structures. If unsure, say N. + # Generic support for tree structured quota files. Selected when needed. config QUOTA_TREE tristate diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index a0a9405..788b580 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -80,8 +80,6 @@ #include -#define __DQUOT_PARANOIA - /* * There are three quota SMP locks. dq_list_lock protects all lists with quotas * and quota formats, dqstats structure containing statistics about the lists @@ -695,7 +693,7 @@ void dqput(struct dquot *dquot) if (!dquot) return; -#ifdef __DQUOT_PARANOIA +#ifdef CONFIG_QUOTA_DEBUG if (!atomic_read(&dquot->dq_count)) { printk("VFS: dqput: trying to free free dquot\n"); printk("VFS: device %s, dquot of %s %d\n", @@ -748,7 +746,7 @@ we_slept: goto we_slept; } atomic_dec(&dquot->dq_count); -#ifdef __DQUOT_PARANOIA +#ifdef CONFIG_QUOTA_DEBUG /* sanity check */ BUG_ON(!list_empty(&dquot->dq_free)); #endif @@ -845,7 +843,7 @@ we_slept: dquot = NULL; goto out; } -#ifdef __DQUOT_PARANOIA +#ifdef CONFIG_QUOTA_DEBUG BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ #endif out: @@ -874,7 +872,7 @@ static int dqinit_needed(struct inode *inode, int type) static void add_dquot_ref(struct super_block *sb, int type) { struct inode *inode, *old_inode = NULL; -#ifdef __DQUOT_PARANOIA +#ifdef CONFIG_QUOTA_DEBUG int reserved = 0; #endif @@ -882,7 +880,7 @@ static void add_dquot_ref(struct super_block *sb, int type) list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) continue; -#ifdef __DQUOT_PARANOIA +#ifdef CONFIG_QUOTA_DEBUG if (unlikely(inode_get_rsv_space(inode) > 0)) reserved = 1; #endif @@ -907,7 +905,7 @@ static void add_dquot_ref(struct super_block *sb, int type) spin_unlock(&inode_lock); iput(old_inode); -#ifdef __DQUOT_PARANOIA +#ifdef CONFIG_QUOTA_DEBUG if (reserved) { printk(KERN_WARNING "VFS (%s): Writes happened before quota" " was turned on thus quota information is probably " @@ -940,7 +938,7 @@ static int remove_inode_dquot_ref(struct inode *inode, int type, inode->i_dquot[type] = NULL; if (dquot) { if (dqput_blocks(dquot)) { -#ifdef __DQUOT_PARANOIA +#ifdef CONFIG_QUOTA_DEBUG if (atomic_read(&dquot->dq_count) != 1) printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); #endif -- cgit v1.1