diff --git a/[refs] b/[refs] index 93d2990edf1c..32a73a81c63a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d91fa971285a3ac33b4e8af6cea7c455543e2599 +refs/heads/master: ac53c4fca42c394d8a06c7a470ae2d1d50503717 diff --git a/trunk/Makefile b/trunk/Makefile index 346e28f5de52..3d2fc460b22f 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 7 SUBLEVEL = 0 -EXTRAVERSION = -rc8 +EXTRAVERSION = -rc7 NAME = Terrified Chipmunk # *DOCUMENTATION* @@ -1321,12 +1321,10 @@ kernelversion: # Clear a bunch of variables before executing the submake tools/: FORCE - $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ tools/%: FORCE - $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ $* + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ $* # Single targets # --------------------------------------------------------------------------- diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 9759fec0b704..ade7e924bef5 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -547,7 +547,6 @@ config ARCH_KIRKWOOD select CPU_FEROCEON select GENERIC_CLOCKEVENTS select PCI - select PCI_QUIRKS select PLAT_ORION_LEGACY help Support for the following Marvell Kirkwood series SoCs: diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index 49ca86e37b8d..90275f036cd1 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -652,15 +652,6 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size mov pc, lr ENDPROC(__setup_mmu) -@ Enable unaligned access on v6, to allow better code generation -@ for the decompressor C code: -__armv6_mmu_cache_on: - mrc p15, 0, r0, c1, c0, 0 @ read SCTLR - bic r0, r0, #2 @ A (no unaligned access fault) - orr r0, r0, #1 << 22 @ U (v6 unaligned access model) - mcr p15, 0, r0, c1, c0, 0 @ write SCTLR - b __armv4_mmu_cache_on - __arm926ejs_mmu_cache_on: #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ put dcache in WT mode @@ -703,9 +694,6 @@ __armv7_mmu_cache_on: bic r0, r0, #1 << 28 @ clear SCTLR.TRE orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x003c @ write buffer - bic r0, r0, #2 @ A (no unaligned access fault) - orr r0, r0, #1 << 22 @ U (v6 unaligned access model) - @ (needed for ARM1176) #ifdef CONFIG_MMU #ifdef CONFIG_CPU_ENDIAN_BE8 orr r0, r0, #1 << 25 @ big-endian page tables @@ -926,7 +914,7 @@ proc_types: .word 0x0007b000 @ ARMv6 .word 0x000ff000 - W(b) __armv6_mmu_cache_on + W(b) __armv4_mmu_cache_on W(b) __armv4_mmu_cache_off W(b) __armv6_mmu_cache_flush diff --git a/trunk/arch/arm/common/timer-sp.c b/trunk/arch/arm/common/timer-sp.c index 9d2d3ba339ff..df13a3ffff35 100644 --- a/trunk/arch/arm/common/timer-sp.c +++ b/trunk/arch/arm/common/timer-sp.c @@ -162,6 +162,7 @@ static struct clock_event_device sp804_clockevent = { .set_mode = sp804_set_mode, .set_next_event = sp804_set_next_event, .rating = 300, + .cpumask = cpu_all_mask, }; static struct irqaction sp804_timer_irq = { @@ -184,7 +185,6 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); evt->name = name; evt->irq = irq; - evt->cpumask = cpu_possible_mask; setup_irq(irq, &sp804_timer_irq); clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); diff --git a/trunk/arch/arm/mach-dove/include/mach/pm.h b/trunk/arch/arm/mach-dove/include/mach/pm.h index b47f75038686..7bcd0dfce4b1 100644 --- a/trunk/arch/arm/mach-dove/include/mach/pm.h +++ b/trunk/arch/arm/mach-dove/include/mach/pm.h @@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin) static inline int irq_to_pmu(int irq) { - if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS) + if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS) return irq - IRQ_DOVE_PMU_START; return -EINVAL; diff --git a/trunk/arch/arm/mach-dove/irq.c b/trunk/arch/arm/mach-dove/irq.c index bc4344aa1009..087711524e8a 100644 --- a/trunk/arch/arm/mach-dove/irq.c +++ b/trunk/arch/arm/mach-dove/irq.c @@ -46,20 +46,8 @@ static void pmu_irq_ack(struct irq_data *d) int pin = irq_to_pmu(d->irq); u32 u; - /* - * The PMU mask register is not RW0C: it is RW. This means that - * the bits take whatever value is written to them; if you write - * a '1', you will set the interrupt. - * - * Unfortunately this means there is NO race free way to clear - * these interrupts. - * - * So, let's structure the code so that the window is as small as - * possible. - */ u = ~(1 << (pin & 31)); - u &= readl_relaxed(PMU_INTERRUPT_CAUSE); - writel_relaxed(u, PMU_INTERRUPT_CAUSE); + writel(u, PMU_INTERRUPT_CAUSE); } static struct irq_chip pmu_irq_chip = { diff --git a/trunk/arch/arm/mach-ixp4xx/common-pci.c b/trunk/arch/arm/mach-ixp4xx/common-pci.c index 6d6bde3e15fa..1694f01ce2b6 100644 --- a/trunk/arch/arm/mach-ixp4xx/common-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/common-pci.c @@ -410,7 +410,6 @@ void __init ixp4xx_pci_preinit(void) * Enable the IO window to be way up high, at 0xfffffc00 */ local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01); - local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */ } else { printk("PCI: IXP4xx is target - No bus scan performed\n"); } diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index 8c0c0e2d0727..fdf91a160884 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -67,12 +67,15 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS), .length = IXP4XX_PCI_CFG_REGION_SIZE, .type = MT_DEVICE - }, { /* Queue Manager */ - .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT, - .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS), - .length = IXP4XX_QMGR_REGION_SIZE, - .type = MT_DEVICE }, +#ifdef CONFIG_DEBUG_LL + { /* Debug UART mapping */ + .virtual = (unsigned long)IXP4XX_DEBUG_UART_BASE_VIRT, + .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS), + .length = IXP4XX_DEBUG_UART_REGION_SIZE, + .type = MT_DEVICE + } +#endif }; void __init ixp4xx_map_io(void) diff --git a/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c b/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c index 53b8348dfcc2..b800a031207c 100644 --- a/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/trunk/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -15,7 +15,6 @@ #include #include #include -#include #define SLOT_ETHA 0x0B /* IDSEL = AD21 */ #define SLOT_ETHB 0x0C /* IDSEL = AD20 */ @@ -330,7 +329,7 @@ static struct platform_device device_hss_tab[] = { }; -static struct platform_device *device_tab[7] __initdata = { +static struct platform_device *device_tab[6] __initdata = { &device_flash, /* index 0 */ }; diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/trunk/arch/arm/mach-ixp4xx/include/mach/debug-macro.S index ff686cbc5df4..8c9f8d564492 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/debug-macro.S @@ -17,8 +17,8 @@ #else mov \rp, #0 #endif - orr \rv, \rp, #0xfe000000 @ virtual - orr \rv, \rv, #0x00f00000 + orr \rv, \rp, #0xff000000 @ virtual + orr \rv, \rv, #0x00b00000 orr \rp, \rp, #0xc8000000 @ physical .endm diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/trunk/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h index c5bae9c035d5..eb68b61ce975 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h @@ -30,43 +30,51 @@ * * 0x50000000 0x10000000 ioremap'd EXP BUS * - * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals + * 0x6000000 0x00004000 ioremap'd QMgr * - * 0xC0000000 0x00001000 0xFEF13000 PCI CFG + * 0xC0000000 0x00001000 0xffbff000 PCI CFG * - * 0xC4000000 0x00001000 0xFEF14000 EXP CFG + * 0xC4000000 0x00001000 0xffbfe000 EXP CFG * - * 0x60000000 0x00004000 0xFEF15000 QMgr + * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals */ /* * Queue Manager */ -#define IXP4XX_QMGR_BASE_PHYS 0x60000000 -#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000) -#define IXP4XX_QMGR_REGION_SIZE 0x00004000 +#define IXP4XX_QMGR_BASE_PHYS (0x60000000) +#define IXP4XX_QMGR_REGION_SIZE (0x00004000) /* - * Peripheral space, including debug UART. Must be section-aligned so that - * it can be used with the low-level debug code. + * Expansion BUS Configuration registers */ -#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000 -#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000) -#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000 +#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000) +#define IXP4XX_EXP_CFG_BASE_VIRT IOMEM(0xFFBFE000) +#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000) /* * PCI Config registers */ -#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000 -#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000) -#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000 +#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000) +#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFFBFF000) +#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000) /* - * Expansion BUS Configuration registers + * Peripheral space + */ +#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000) +#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFFBEB000) +#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000) + +/* + * Debug UART + * + * This is basically a remap of UART1 into a region that is section + * aligned so that it * can be used with the low-level debug code. */ -#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000 -#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000 -#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000 +#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000) +#define IXP4XX_DEBUG_UART_BASE_VIRT IOMEM(0xffb00000) +#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000) #define IXP4XX_EXP_CS0_OFFSET 0x00 #define IXP4XX_EXP_CS1_OFFSET 0x04 diff --git a/trunk/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/trunk/arch/arm/mach-ixp4xx/include/mach/qmgr.h index 4de8da536dbb..9e7cad2d54cb 100644 --- a/trunk/arch/arm/mach-ixp4xx/include/mach/qmgr.h +++ b/trunk/arch/arm/mach-ixp4xx/include/mach/qmgr.h @@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue); static inline void qmgr_put_entry(unsigned int queue, u32 val) { - struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val) static inline u32 qmgr_get_entry(unsigned int queue) { u32 val; - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; val = __raw_readl(&qmgr_regs->acc[queue][0]); #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue) static inline int __qmgr_get_stat1(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) >> ((queue & 7) << 2)) & 0xF; } static inline int __qmgr_get_stat2(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; BUG_ON(queue >= HALF_QUEUES); return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) >> ((queue & 0xF) << 1)) & 0x3; @@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue) */ static inline int qmgr_stat_below_low_watermark(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statne_h) >> (queue - HALF_QUEUES)) & 0x01; @@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue) */ static inline int qmgr_stat_full(unsigned int queue) { - const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; + extern struct qmgr_regs __iomem *qmgr_regs; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statf_h) >> (queue - HALF_QUEUES)) & 0x01; diff --git a/trunk/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/trunk/arch/arm/mach-ixp4xx/ixp4xx_npe.c index d4eb09a62863..a17ed79207a4 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixp4xx_npe.c +++ b/trunk/arch/arm/mach-ixp4xx/ixp4xx_npe.c @@ -116,11 +116,7 @@ /* NPE mailbox_status value for reset */ #define RESET_MBOX_STAT 0x0000F0F0 -#define NPE_A_FIRMWARE "NPE-A" -#define NPE_B_FIRMWARE "NPE-B" -#define NPE_C_FIRMWARE "NPE-C" - -const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE }; +const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" }; #define print_npe(pri, npe, fmt, ...) \ printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__) @@ -728,9 +724,6 @@ module_exit(npe_cleanup_module); MODULE_AUTHOR("Krzysztof Halasa"); MODULE_LICENSE("GPL v2"); -MODULE_FIRMWARE(NPE_A_FIRMWARE); -MODULE_FIRMWARE(NPE_B_FIRMWARE); -MODULE_FIRMWARE(NPE_C_FIRMWARE); EXPORT_SYMBOL(npe_names); EXPORT_SYMBOL(npe_running); diff --git a/trunk/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/trunk/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c index 9d1b6b7c394c..852f7c9f87d0 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c +++ b/trunk/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c @@ -14,7 +14,7 @@ #include #include -static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; +struct qmgr_regs __iomem *qmgr_regs; static struct resource *mem_res; static spinlock_t qmgr_lock; static u32 used_sram_bitmap[4]; /* 128 16-dword pages */ @@ -293,6 +293,12 @@ static int qmgr_init(void) if (mem_res == NULL) return -EBUSY; + qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); + if (qmgr_regs == NULL) { + err = -ENOMEM; + goto error_map; + } + /* reset qmgr registers */ for (i = 0; i < 4; i++) { __raw_writel(0x33333333, &qmgr_regs->stat1[i]); @@ -341,6 +347,8 @@ static int qmgr_init(void) error_irq2: free_irq(IRQ_IXP4XX_QM1, NULL); error_irq: + iounmap(qmgr_regs); +error_map: release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); return err; } @@ -351,6 +359,7 @@ static void qmgr_remove(void) free_irq(IRQ_IXP4XX_QM2, NULL); synchronize_irq(IRQ_IXP4XX_QM1); synchronize_irq(IRQ_IXP4XX_QM2); + iounmap(qmgr_regs); release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); } @@ -360,6 +369,7 @@ module_exit(qmgr_remove); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Krzysztof Halasa"); +EXPORT_SYMBOL(qmgr_regs); EXPORT_SYMBOL(qmgr_set_irq); EXPORT_SYMBOL(qmgr_enable_irq); EXPORT_SYMBOL(qmgr_disable_irq); diff --git a/trunk/arch/arm/mach-kirkwood/pcie.c b/trunk/arch/arm/mach-kirkwood/pcie.c index 74fc5a074fc4..ec544918b12c 100644 --- a/trunk/arch/arm/mach-kirkwood/pcie.c +++ b/trunk/arch/arm/mach-kirkwood/pcie.c @@ -207,19 +207,14 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } -/* - * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it - * is operating as a root complex this needs to be switched to - * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on - * the device. Decoding setup is handled by the orion code. - */ static void __devinit rc_pci_fixup(struct pci_dev *dev) { + /* + * Prevent enumeration of root complex. + */ if (dev->bus->parent == NULL && dev->devfn == 0) { int i; - dev->class &= 0xff; - dev->class |= PCI_CLASS_BRIDGE_HOST << 8; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { dev->resource[i].start = 0; dev->resource[i].end = 0; diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index 09c5233f4dfc..86b8b480634f 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area) mov pc, lr /* - * cpu_v6_switch_mm(pgd_phys, tsk) + * cpu_arm926_switch_mm(pgd_phys, tsk) * * Set the translation table base pointer to be pgd_phys * diff --git a/trunk/arch/arm/plat-s3c24xx/dma.c b/trunk/arch/arm/plat-s3c24xx/dma.c index 0abd1c469887..db98e7021f0d 100644 --- a/trunk/arch/arm/plat-s3c24xx/dma.c +++ b/trunk/arch/arm/plat-s3c24xx/dma.c @@ -473,13 +473,12 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id, pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", chan->number, __func__, buf); - if (chan->end == NULL) { + if (chan->end == NULL) pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", chan->number, __func__, chan); - } else { - chan->end->next = buf; - chan->end = buf; - } + + chan->end->next = buf; + chan->end = buf; } /* if necessary, update the next buffer field */ diff --git a/trunk/arch/arm64/include/asm/unistd32.h b/trunk/arch/arm64/include/asm/unistd32.h index 656a6f291a35..6d909faebf28 100644 --- a/trunk/arch/arm64/include/asm/unistd32.h +++ b/trunk/arch/arm64/include/asm/unistd32.h @@ -392,7 +392,7 @@ __SYSCALL(367, sys_fanotify_init) __SYSCALL(368, compat_sys_fanotify_mark_wrapper) __SYSCALL(369, sys_prlimit64) __SYSCALL(370, sys_name_to_handle_at) -__SYSCALL(371, compat_sys_open_by_handle_at) +__SYSCALL(371, sys_open_by_handle_at) __SYSCALL(372, sys_clock_adjtime) __SYSCALL(373, sys_syncfs) diff --git a/trunk/arch/c6x/include/asm/setup.h b/trunk/arch/c6x/include/asm/setup.h deleted file mode 100644 index ecead15872a6..000000000000 --- a/trunk/arch/c6x/include/asm/setup.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * 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_C6X_SETUP_H -#define _ASM_C6X_SETUP_H - -#include - -#ifndef __ASSEMBLY__ -extern char c6x_command_line[COMMAND_LINE_SIZE]; - -extern int c6x_add_memory(phys_addr_t start, unsigned long size); - -extern unsigned long ram_start; -extern unsigned long ram_end; - -extern int c6x_num_cores; -extern unsigned int c6x_silicon_rev; -extern unsigned int c6x_devstat; -extern unsigned char c6x_fuse_mac[6]; - -extern void machine_init(unsigned long dt_ptr); -extern void time_init(void); - -#endif /* !__ASSEMBLY__ */ -#endif /* _ASM_C6X_SETUP_H */ diff --git a/trunk/arch/c6x/include/uapi/asm/Kbuild b/trunk/arch/c6x/include/uapi/asm/Kbuild index e9bc2b2b8147..c312b424c433 100644 --- a/trunk/arch/c6x/include/uapi/asm/Kbuild +++ b/trunk/arch/c6x/include/uapi/asm/Kbuild @@ -1,8 +1,6 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm -generic-y += kvm_para.h - header-y += byteorder.h header-y += kvm_para.h header-y += ptrace.h diff --git a/trunk/arch/c6x/include/uapi/asm/kvm_para.h b/trunk/arch/c6x/include/uapi/asm/kvm_para.h new file mode 100644 index 000000000000..14fab8f0b957 --- /dev/null +++ b/trunk/arch/c6x/include/uapi/asm/kvm_para.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/c6x/include/uapi/asm/setup.h b/trunk/arch/c6x/include/uapi/asm/setup.h index ad9ac97a8dad..a01e31896fa9 100644 --- a/trunk/arch/c6x/include/uapi/asm/setup.h +++ b/trunk/arch/c6x/include/uapi/asm/setup.h @@ -1,6 +1,33 @@ -#ifndef _UAPI_ASM_C6X_SETUP_H -#define _UAPI_ASM_C6X_SETUP_H +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * 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_C6X_SETUP_H +#define _ASM_C6X_SETUP_H #define COMMAND_LINE_SIZE 1024 -#endif /* _UAPI_ASM_C6X_SETUP_H */ +#ifndef __ASSEMBLY__ +extern char c6x_command_line[COMMAND_LINE_SIZE]; + +extern int c6x_add_memory(phys_addr_t start, unsigned long size); + +extern unsigned long ram_start; +extern unsigned long ram_end; + +extern int c6x_num_cores; +extern unsigned int c6x_silicon_rev; +extern unsigned int c6x_devstat; +extern unsigned char c6x_fuse_mac[6]; + +extern void machine_init(unsigned long dt_ptr); +extern void time_init(void); + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_C6X_SETUP_H */ diff --git a/trunk/arch/c6x/kernel/entry.S b/trunk/arch/c6x/kernel/entry.S index 0ed6157dd256..5449c36018fe 100644 --- a/trunk/arch/c6x/kernel/entry.S +++ b/trunk/arch/c6x/kernel/entry.S @@ -277,8 +277,6 @@ work_rescheduled: [A1] BNOP .S1 work_resched,5 work_notifysig: - ;; enable interrupts for do_notify_resume() - UNMASK_INT B2 B .S2 do_notify_resume LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag ADDKPC .S2 resume_userspace,B3,1 @@ -429,7 +427,8 @@ ENTRY(ret_from_kernel_execve) ENDPROC(ret_from_kernel_execve) ;; - ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ() + ;; These are the interrupt handlers, responsible for calling __do_IRQ() + ;; int6 is used for syscalls (see _system_call entry) ;; .macro SAVE_ALL_INT SAVE_ALL IRP,ITSR diff --git a/trunk/arch/microblaze/kernel/signal.c b/trunk/arch/microblaze/kernel/signal.c index 3903e3d11f5a..3847e5b9c601 100644 --- a/trunk/arch/microblaze/kernel/signal.c +++ b/trunk/arch/microblaze/kernel/signal.c @@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1)) goto badframe; return rval; diff --git a/trunk/arch/mips/include/asm/hugetlb.h b/trunk/arch/mips/include/asm/hugetlb.h index bd94946a18f3..ef99db994c2f 100644 --- a/trunk/arch/mips/include/asm/hugetlb.h +++ b/trunk/arch/mips/include/asm/hugetlb.h @@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, pte_t pte, int dirty) { - return ptep_set_access_flags(vma, addr, ptep, pte, dirty); + int changed = !pte_same(*ptep, pte); + + if (changed) { + set_pte_at(vma->vm_mm, addr, ptep, pte); + /* + * There could be some standard sized pages in there, + * get them all. + */ + flush_tlb_range(vma, addr, addr + HPAGE_SIZE); + } + return changed; } static inline pte_t huge_ptep_get(pte_t *ptep) diff --git a/trunk/arch/mips/mm/tlb-r4k.c b/trunk/arch/mips/mm/tlb-r4k.c index 4b9b935a070e..88e79ad6f811 100644 --- a/trunk/arch/mips/mm/tlb-r4k.c +++ b/trunk/arch/mips/mm/tlb-r4k.c @@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, if (cpu_context(cpu, mm) != 0) { unsigned long size, flags; - int huge = is_vm_hugetlb_page(vma); ENTER_CRITICAL(flags); - if (huge) { - start = round_down(start, HPAGE_SIZE); - end = round_up(end, HPAGE_SIZE); - size = (end - start) >> HPAGE_SHIFT; - } else { - start = round_down(start, PAGE_SIZE << 1); - end = round_up(end, PAGE_SIZE << 1); - size = (end - start) >> (PAGE_SHIFT + 1); - } + start = round_down(start, PAGE_SIZE << 1); + end = round_up(end, PAGE_SIZE << 1); + size = (end - start) >> (PAGE_SHIFT + 1); if (size <= current_cpu_data.tlbsize/2) { int oldpid = read_c0_entryhi(); int newpid = cpu_asid(cpu, mm); @@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, int idx; write_c0_entryhi(start | newpid); - if (huge) - start += HPAGE_SIZE; - else - start += (PAGE_SIZE << 1); + start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); tlb_probe_hazard(); diff --git a/trunk/arch/openrisc/kernel/signal.c b/trunk/arch/openrisc/kernel/signal.c index ddedc8a77861..30110297f4f9 100644 --- a/trunk/arch/openrisc/kernel/signal.c +++ b/trunk/arch/openrisc/kernel/signal.c @@ -84,6 +84,7 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp; sigset_t set; + stack_t st; /* * Since we stacked the signal on a dword boundary, @@ -103,10 +104,11 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; + if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) + goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) - goto badframe; + do_sigaltstack(&st, NULL, regs->sp); return regs->gpr[11]; diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index cbf5d59d5d6a..3735abd7f8f6 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -60,7 +60,7 @@ ENTRY_SAME(fork_wrapper) ENTRY_SAME(read) ENTRY_SAME(write) - ENTRY_COMP(open) /* 5 */ + ENTRY_SAME(open) /* 5 */ ENTRY_SAME(close) ENTRY_SAME(waitpid) ENTRY_SAME(creat) diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 827e094a2f49..ad79b846535c 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -28,7 +28,7 @@ ENTRY(sys32_open_wrapper) llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int lgfr %r4,%r4 # int - jg compat_sys_open # branch to system call + jg sys_open # branch to system call ENTRY(sys32_close_wrapper) llgfr %r2,%r2 # unsigned int diff --git a/trunk/arch/score/kernel/signal.c b/trunk/arch/score/kernel/signal.c index 02353bde92d8..c268bbf8b410 100644 --- a/trunk/arch/score/kernel/signal.c +++ b/trunk/arch/score/kernel/signal.c @@ -148,6 +148,7 @@ score_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe __user *frame; sigset_t set; + stack_t st; int sig; /* Always make any pending restarted system calls return -EINTR */ @@ -167,10 +168,12 @@ score_rt_sigreturn(struct pt_regs *regs) else if (sig) force_sig(sig, current); + if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) + goto badframe; + /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT) - goto badframe; + do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]); regs->is_syscall = 0; __asm__ __volatile__( diff --git a/trunk/arch/sh/kernel/signal_64.c b/trunk/arch/sh/kernel/signal_64.c index d867cd95a622..23853814bd17 100644 --- a/trunk/arch/sh/kernel/signal_64.c +++ b/trunk/arch/sh/kernel/signal_64.c @@ -347,6 +347,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, { struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP; sigset_t set; + stack_t __user st; long long ret; /* Always make any pending restarted system calls return -EINTR */ @@ -364,10 +365,11 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, goto badframe; regs->pc -= 4; + if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) + goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT) - goto badframe; + do_sigaltstack(&st, NULL, REF_REG_SP); return (int) ret; diff --git a/trunk/arch/sparc/boot/piggyback.c b/trunk/arch/sparc/boot/piggyback.c index bb7c95161d71..c0a798fcf030 100644 --- a/trunk/arch/sparc/boot/piggyback.c +++ b/trunk/arch/sparc/boot/piggyback.c @@ -81,18 +81,18 @@ static void usage(void) static int start_line(const char *line) { - if (strcmp(line + 10, " _start\n") == 0) + if (strcmp(line + 8, " T _start\n") == 0) return 1; - else if (strcmp(line + 18, " _start\n") == 0) + else if (strcmp(line + 16, " T _start\n") == 0) return 1; return 0; } static int end_line(const char *line) { - if (strcmp(line + 10, " _end\n") == 0) + if (strcmp(line + 8, " A _end\n") == 0) return 1; - else if (strcmp (line + 18, " _end\n") == 0) + else if (strcmp (line + 16, " A _end\n") == 0) return 1; return 0; } @@ -100,8 +100,8 @@ static int end_line(const char *line) /* * Find address for start and end in System.map. * The file looks like this: - * f0004000 ... _start - * f0379f79 ... _end + * f0004000 T _start + * f0379f79 A _end * 1234567890123456 * ^coloumn 1 * There is support for 64 bit addresses too. diff --git a/trunk/arch/sparc/kernel/sys32.S b/trunk/arch/sparc/kernel/sys32.S index 8475a474273a..44025f4ba41f 100644 --- a/trunk/arch/sparc/kernel/sys32.S +++ b/trunk/arch/sparc/kernel/sys32.S @@ -47,7 +47,7 @@ STUB: sra REG1, 0, REG1; \ sra REG4, 0, REG4 SIGN1(sys32_exit, sparc_exit, %o0) -SIGN1(sys32_exit_group, sparc_exit_group, %o0) +SIGN1(sys32_exit_group, sys_exit_group, %o0) SIGN1(sys32_wait4, compat_sys_wait4, %o2) SIGN1(sys32_creat, sys_creat, %o1) SIGN1(sys32_mknod, sys_mknod, %o1) diff --git a/trunk/arch/sparc/kernel/syscalls.S b/trunk/arch/sparc/kernel/syscalls.S index bf2347794e33..7f5f65d0b3fd 100644 --- a/trunk/arch/sparc/kernel/syscalls.S +++ b/trunk/arch/sparc/kernel/syscalls.S @@ -118,20 +118,10 @@ ret_from_syscall: ba,pt %xcc, ret_sys_call ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 - .globl sparc_exit_group - .type sparc_exit_group,#function -sparc_exit_group: - sethi %hi(sys_exit_group), %g7 - ba,pt %xcc, 1f - or %g7, %lo(sys_exit_group), %g7 - .size sparc_exit_group,.-sparc_exit_group - .globl sparc_exit .type sparc_exit,#function sparc_exit: - sethi %hi(sys_exit), %g7 - or %g7, %lo(sys_exit), %g7 -1: rdpr %pstate, %g2 + rdpr %pstate, %g2 wrpr %g2, PSTATE_IE, %pstate rdpr %otherwin, %g1 rdpr %cansave, %g3 @@ -139,7 +129,7 @@ sparc_exit: wrpr %g3, 0x0, %cansave wrpr %g0, 0x0, %otherwin wrpr %g2, 0x0, %pstate - jmpl %g7, %g0 + ba,pt %xcc, sys_exit stb %g0, [%g6 + TI_WSAVED] .size sparc_exit,.-sparc_exit diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S index 017b74a63dcb..1c9af9fa38e9 100644 --- a/trunk/arch/sparc/kernel/systbls_64.S +++ b/trunk/arch/sparc/kernel/systbls_64.S @@ -133,7 +133,7 @@ sys_call_table: /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall - .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname + .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall diff --git a/trunk/arch/um/kernel/exec.c b/trunk/arch/um/kernel/exec.c index 0d7103c9eff3..3a8ece7d09ca 100644 --- a/trunk/arch/um/kernel/exec.c +++ b/trunk/arch/um/kernel/exec.c @@ -32,14 +32,13 @@ void flush_thread(void) "err = %d\n", ret); force_sig(SIGKILL, current); } - get_safe_registers(current_pt_regs()->regs.gp, - current_pt_regs()->regs.fp); __switch_mm(¤t->mm->context.id); } void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { + get_safe_registers(regs->regs.gp, regs->regs.fp); PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; current->ptrace &= ~PT_DTRACE; diff --git a/trunk/arch/x86/include/asm/Kbuild b/trunk/arch/x86/include/asm/Kbuild index 79fd8a3418f9..66e5f0ef0523 100644 --- a/trunk/arch/x86/include/asm/Kbuild +++ b/trunk/arch/x86/include/asm/Kbuild @@ -12,7 +12,6 @@ header-y += mce.h header-y += msr-index.h header-y += msr.h header-y += mtrr.h -header-y += perf_regs.h header-y += posix_types_32.h header-y += posix_types_64.h header-y += posix_types_x32.h @@ -20,10 +19,8 @@ header-y += prctl.h header-y += processor-flags.h header-y += ptrace-abi.h header-y += sigcontext32.h -header-y += svm.h header-y += ucontext.h header-y += vm86.h -header-y += vmx.h header-y += vsyscall.h genhdr-y += unistd_32.h diff --git a/trunk/arch/x86/include/asm/fpu-internal.h b/trunk/arch/x86/include/asm/fpu-internal.h index 41ab26ea6564..831dbb9c6c02 100644 --- a/trunk/arch/x86/include/asm/fpu-internal.h +++ b/trunk/arch/x86/include/asm/fpu-internal.h @@ -399,17 +399,14 @@ static inline void drop_init_fpu(struct task_struct *tsk) typedef struct { int preload; } fpu_switch_t; /* - * Must be run with preemption disabled: this clears the fpu_owner_task, - * on this CPU. + * FIXME! We could do a totally lazy restore, but we need to + * add a per-cpu "this was the task that last touched the FPU + * on this CPU" variable, and the task needs to have a "I last + * touched the FPU on this CPU" and check them. * - * This will disable any lazy FPU state restore of the current FPU state, - * but if the current thread owns the FPU, it will still be saved by. + * We don't do that yet, so "fpu_lazy_restore()" always returns + * false, but some day.. */ -static inline void __cpu_disable_lazy_restore(unsigned int cpu) -{ - per_cpu(fpu_owner_task, cpu) = NULL; -} - static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu) { return new == this_cpu_read_stable(fpu_owner_task) && diff --git a/trunk/arch/x86/kernel/head_32.S b/trunk/arch/x86/kernel/head_32.S index 4dac2f68ed4a..957a47aec64e 100644 --- a/trunk/arch/x86/kernel/head_32.S +++ b/trunk/arch/x86/kernel/head_32.S @@ -292,8 +292,8 @@ default_entry: * be using the global pages. * * NOTE! If we are on a 486 we may have no cr4 at all! - * Specifically, cr4 exists if and only if CPUID exists - * and has flags other than the FPU flag set. + * Specifically, cr4 exists if and only if CPUID exists, + * which in turn exists if and only if EFLAGS.ID exists. */ movl $X86_EFLAGS_ID,%ecx pushl %ecx @@ -308,11 +308,6 @@ default_entry: testl %ecx,%eax jz 6f # No ID flag = no CPUID = no CR4 - movl $1,%eax - cpuid - andl $~1,%edx # Ignore CPUID.FPU - jz 6f # No flags or only CPUID.FPU = no CR4 - movl pa(mmu_cr4_features),%eax movl %eax,%cr4 diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c index 974b67e46dd0..5e0596b0632e 100644 --- a/trunk/arch/x86/kernel/ptrace.c +++ b/trunk/arch/x86/kernel/ptrace.c @@ -1541,13 +1541,6 @@ void syscall_trace_leave(struct pt_regs *regs) { bool step; - /* - * We may come here right after calling schedule_user() - * or do_notify_resume(), in which case we can be in RCU - * user mode. - */ - rcu_user_exit(); - audit_syscall_exit(regs); if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index f3e2ec878b8c..c80a33bc528b 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -68,8 +68,6 @@ #include #include #include -#include -#include #include #include #include @@ -820,9 +818,6 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; - /* the FPU context is blank, nobody can own it */ - __cpu_disable_lazy_restore(cpu); - err = do_boot_cpu(apicid, cpu, tidle); if (err) { pr_debug("do_boot_cpu failed %d\n", err); diff --git a/trunk/arch/x86/kvm/emulate.c b/trunk/arch/x86/kvm/emulate.c index bba39bfa1c4b..39171cb307ea 100644 --- a/trunk/arch/x86/kvm/emulate.c +++ b/trunk/arch/x86/kvm/emulate.c @@ -426,7 +426,8 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) _ASM_EXTABLE(1b, 3b) \ : "=m" ((ctxt)->eflags), "=&r" (_tmp), \ "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \ - : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \ + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \ + "a" (*rax), "d" (*rdx)); \ } while (0) /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ diff --git a/trunk/drivers/atm/ambassador.c b/trunk/drivers/atm/ambassador.c index ff7bb8a42ed6..89b30f32ba68 100644 --- a/trunk/drivers/atm/ambassador.c +++ b/trunk/drivers/atm/ambassador.c @@ -1961,7 +1961,6 @@ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) { res = loader_verify(lb, dev, rec); if (res) break; - rec = ihex_next_binrec(rec); } release_firmware(fw); if (!res) diff --git a/trunk/drivers/char/hw_random/Kconfig b/trunk/drivers/char/hw_random/Kconfig index c58ea9b80b1a..fbd9b2b850ef 100644 --- a/trunk/drivers/char/hw_random/Kconfig +++ b/trunk/drivers/char/hw_random/Kconfig @@ -127,12 +127,12 @@ config HW_RANDOM_VIA If unsure, say Y. config HW_RANDOM_IXP4XX - tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support" + tristate "Intel IXP4xx NPU HW Random Number Generator support" depends on HW_RANDOM && ARCH_IXP4XX default HW_RANDOM ---help--- - This driver provides kernel-side support for the Pseudo-Random - Number Generator hardware found on the Intel IXP45x/46x NPU. + This driver provides kernel-side support for the Random + Number Generator hardware found on the Intel IXP4xx NPU. To compile this driver as a module, choose M here: the module will be called ixp4xx-rng. diff --git a/trunk/drivers/char/hw_random/ixp4xx-rng.c b/trunk/drivers/char/hw_random/ixp4xx-rng.c index beec1627db3c..263567f5f392 100644 --- a/trunk/drivers/char/hw_random/ixp4xx-rng.c +++ b/trunk/drivers/char/hw_random/ixp4xx-rng.c @@ -45,9 +45,6 @@ static int __init ixp4xx_rng_init(void) void __iomem * rng_base; int err; - if (!cpu_is_ixp46x()) /* includes IXP455 */ - return -ENOSYS; - rng_base = ioremap(0x70002100, 4); if (!rng_base) return -ENOMEM; @@ -71,5 +68,5 @@ module_init(ixp4xx_rng_init); module_exit(ixp4xx_rng_exit); MODULE_AUTHOR("Deepak Saxena "); -MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x"); +MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/raw.c b/trunk/drivers/char/raw.c index 54a3a6d09819..0bb207eaef2f 100644 --- a/trunk/drivers/char/raw.c +++ b/trunk/drivers/char/raw.c @@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd, static const struct file_operations raw_fops = { .read = do_sync_read, - .aio_read = generic_file_aio_read, + .aio_read = blkdev_aio_read, .write = do_sync_write, .aio_write = blkdev_aio_write, .fsync = blkdev_fsync, diff --git a/trunk/drivers/crypto/Kconfig b/trunk/drivers/crypto/Kconfig index f6644f59fd9d..308c7fb92a60 100644 --- a/trunk/drivers/crypto/Kconfig +++ b/trunk/drivers/crypto/Kconfig @@ -224,7 +224,7 @@ config CRYPTO_DEV_TALITOS config CRYPTO_DEV_IXP4XX tristate "Driver for IXP4xx crypto hardware acceleration" - depends on ARCH_IXP4XX && IXP4XX_QMGR && IXP4XX_NPE + depends on ARCH_IXP4XX select CRYPTO_DES select CRYPTO_ALGAPI select CRYPTO_AUTHENC diff --git a/trunk/drivers/crypto/ixp4xx_crypto.c b/trunk/drivers/crypto/ixp4xx_crypto.c index 21180d6cad6e..8f3f74ce8c7f 100644 --- a/trunk/drivers/crypto/ixp4xx_crypto.c +++ b/trunk/drivers/crypto/ixp4xx_crypto.c @@ -750,12 +750,12 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt, } if (cipher_cfg & MOD_AES) { switch (key_len) { - case 16: keylen_cfg = MOD_AES128; break; - case 24: keylen_cfg = MOD_AES192; break; - case 32: keylen_cfg = MOD_AES256; break; - default: - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; - return -EINVAL; + case 16: keylen_cfg = MOD_AES128 | KEYLEN_128; break; + case 24: keylen_cfg = MOD_AES192 | KEYLEN_192; break; + case 32: keylen_cfg = MOD_AES256 | KEYLEN_256; break; + default: + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; } cipher_cfg |= keylen_cfg; } else if (cipher_cfg & MOD_3DES) { diff --git a/trunk/drivers/edac/edac_mc.c b/trunk/drivers/edac/edac_mc.c index 75c0a1a85fc3..90f0b730e9bb 100644 --- a/trunk/drivers/edac/edac_mc.c +++ b/trunk/drivers/edac/edac_mc.c @@ -416,18 +416,10 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, dimm->cschannel = chn; /* Increment csrow location */ - if (layers[0].is_virt_csrow) { + row++; + if (row == tot_csrows) { + row = 0; chn++; - if (chn == tot_channels) { - chn = 0; - row++; - } - } else { - row++; - if (row == tot_csrows) { - row = 0; - chn++; - } } /* Increment dimm location */ diff --git a/trunk/drivers/edac/i7300_edac.c b/trunk/drivers/edac/i7300_edac.c index 9d669cd43618..a09d0667f72a 100644 --- a/trunk/drivers/edac/i7300_edac.c +++ b/trunk/drivers/edac/i7300_edac.c @@ -197,8 +197,8 @@ static const char *ferr_fat_fbd_name[] = { [0] = "Memory Write error on non-redundant retry or " "FBD configuration Write error on retry", }; -#define GET_FBD_FAT_IDX(fbderr) (((fbderr) >> 28) & 3) -#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22)) +#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28)) +#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) #define FERR_NF_FBD 0xa0 static const char *ferr_nf_fbd_name[] = { @@ -225,7 +225,7 @@ static const char *ferr_nf_fbd_name[] = { [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC", [0] = "Uncorrectable Data ECC on Replay", }; -#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3) +#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28)) #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\ (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\ (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\ @@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) errnum = find_first_bit(&errors, ARRAY_SIZE(ferr_nf_fbd_name)); specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); - branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0; + branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0; pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, REDMEMA, &syndrome); diff --git a/trunk/drivers/edac/i7core_edac.c b/trunk/drivers/edac/i7core_edac.c index 10c8c00d6469..3672101023bd 100644 --- a/trunk/drivers/edac/i7core_edac.c +++ b/trunk/drivers/edac/i7core_edac.c @@ -816,7 +816,7 @@ static ssize_t i7core_inject_store_##param( \ struct device_attribute *mattr, \ const char *data, size_t count) \ { \ - struct mem_ctl_info *mci = dev_get_drvdata(dev); \ + struct mem_ctl_info *mci = to_mci(dev); \ struct i7core_pvt *pvt; \ long value; \ int rc; \ @@ -845,7 +845,7 @@ static ssize_t i7core_inject_show_##param( \ struct device_attribute *mattr, \ char *data) \ { \ - struct mem_ctl_info *mci = dev_get_drvdata(dev); \ + struct mem_ctl_info *mci = to_mci(dev); \ struct i7core_pvt *pvt; \ \ pvt = mci->pvt_info; \ @@ -1052,7 +1052,7 @@ static ssize_t i7core_show_counter_##param( \ struct device_attribute *mattr, \ char *data) \ { \ - struct mem_ctl_info *mci = dev_get_drvdata(dev); \ + struct mem_ctl_info *mci = to_mci(dev); \ struct i7core_pvt *pvt = mci->pvt_info; \ \ edac_dbg(1, "\n"); \ diff --git a/trunk/drivers/edac/i82975x_edac.c b/trunk/drivers/edac/i82975x_edac.c index a98020409fa9..069e26c11c4f 100644 --- a/trunk/drivers/edac/i82975x_edac.c +++ b/trunk/drivers/edac/i82975x_edac.c @@ -370,6 +370,10 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank) static void i82975x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, void __iomem *mch_window) { + static const char *labels[4] = { + "DIMM A1", "DIMM A2", + "DIMM B1", "DIMM B2" + }; struct csrow_info *csrow; unsigned long last_cumul_size; u8 value; @@ -419,10 +423,9 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci, dimm = mci->csrows[index]->channels[chan]->dimm; dimm->nr_pages = nr_pages / csrow->nr_channels; - - snprintf(csrow->channels[chan]->dimm->label, EDAC_MC_LABEL_LEN, "DIMM %c%d", - (chan == 0) ? 'A' : 'B', - index); + strncpy(csrow->channels[chan]->dimm->label, + labels[(index >> 1) + (chan * 2)], + EDAC_MC_LABEL_LEN); dimm->grain = 1 << 7; /* 128Byte cache-line resolution */ dimm->dtype = i82975x_dram_type(mch_window, index); dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c index f2df06c603f7..241ad1eeec64 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -226,12 +226,6 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) * already updated or not by exynos_drm_encoder_dpms function. */ exynos_encoder->updated = true; - - /* - * In case of setcrtc, there is no way to update encoder's dpms - * so update it here. - */ - exynos_encoder->dpms = DRM_MODE_DPMS_ON; } static void exynos_drm_encoder_disable(struct drm_encoder *encoder) @@ -513,6 +507,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data) * because the setting for disabling the overlay will be updated * at vsync. */ - if (overlay_ops && overlay_ops->wait_for_vblank) + if (overlay_ops->wait_for_vblank) overlay_ops->wait_for_vblank(manager->dev); } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e7466c4414cb..67eb6ba56edf 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -87,8 +87,7 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; fbi->screen_base = buffer->kvaddr + offset; - fbi->fix.smem_start = (unsigned long)(page_to_phys(buffer->pages[0]) + - offset); + fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset); fbi->screen_size = size; fbi->fix.smem_len = size; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index e08478f19f1a..130a2b510d4a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -61,11 +61,11 @@ struct fimd_driver_data { unsigned int timing_base; }; -static struct fimd_driver_data exynos4_fimd_driver_data = { +struct fimd_driver_data exynos4_fimd_driver_data = { .timing_base = 0x0, }; -static struct fimd_driver_data exynos5_fimd_driver_data = { +struct fimd_driver_data exynos5_fimd_driver_data = { .timing_base = 0x20000, }; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c index 862ca1eb2102..60b877a388c2 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -204,6 +204,7 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, return ret; plane->crtc = crtc; + plane->fb = crtc->fb; exynos_plane_commit(plane); exynos_plane_dpms(plane, DRM_MODE_DPMS_ON); diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.c b/trunk/drivers/gpu/drm/i915/intel_bios.c index 56846ed5ee55..0ed6baff4b0c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.c +++ b/trunk/drivers/gpu/drm/i915/intel_bios.c @@ -499,8 +499,12 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) edp = find_section(bdb, BDB_EDP); if (!edp) { - if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) - DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n"); + if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) { + DRM_DEBUG_KMS("No eDP BDB found but eDP panel " + "supported, assume %dbpp panel color " + "depth.\n", + dev_priv->edp.bpp); + } return; } @@ -653,6 +657,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) dev_priv->lvds_use_ssc = 1; dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); + + /* eDP data */ + dev_priv->edp.bpp = 18; } static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index b426d44a2b05..4154bcd7a070 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -3845,7 +3845,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, /* Use VBT settings if we have an eDP panel */ unsigned int edp_bpc = dev_priv->edp.bpp / 3; - if (edp_bpc && edp_bpc < display_bpc) { + if (edp_bpc < display_bpc) { DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); display_bpc = edp_bpc; } diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index 442968f8b201..72f41aaa71ff 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -2373,9 +2373,15 @@ int intel_enable_rc6(const struct drm_device *dev) if (i915_enable_rc6 >= 0) return i915_enable_rc6; - /* Disable RC6 on Ironlake */ - if (INTEL_INFO(dev)->gen == 5) - return 0; + if (INTEL_INFO(dev)->gen == 5) { +#ifdef CONFIG_INTEL_IOMMU + /* Disable rc6 on ilk if VT-d is on. */ + if (intel_iommu_gfx_mapped) + return false; +#endif + DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n"); + return INTEL_RC6_ENABLE; + } if (IS_HASWELL(dev)) { DRM_DEBUG_DRIVER("Haswell: only RC6 available\n"); diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index a6ac0b416964..c600fb06e25e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -2201,6 +2201,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; intel_sdvo->is_hdmi = true; } + intel_sdvo->base.cloneable = true; intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); if (intel_sdvo->is_hdmi) @@ -2231,6 +2232,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) intel_sdvo->is_tv = true; intel_sdvo->base.needs_tv_clock = true; + intel_sdvo->base.cloneable = false; intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); @@ -2273,6 +2275,8 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; } + intel_sdvo->base.cloneable = true; + intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); return true; @@ -2303,6 +2307,9 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; } + /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */ + intel_sdvo->base.cloneable = false; + intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) goto err; @@ -2714,16 +2721,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) goto err_output; } - /* - * Cloning SDVO with anything is often impossible, since the SDVO - * encoder can request a special input timing mode. And even if that's - * not the case we have evidence that cloning a plain unscaled mode with - * VGA doesn't really work. Furthermore the cloning flags are way too - * simplistic anyway to express such constraints, so just give up on - * cloning for SDVO encoders. - */ - intel_sdvo->base.cloneable = false; - /* Only enable the hotplug irq if we need it, to work around noisy * hotplug lines. */ diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 24d932f53203..3bce0299f64a 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1696,22 +1696,42 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) return ATOM_PPLL2; DRM_ERROR("unable to allocate a PPLL\n"); return ATOM_PPLL_INVALID; + } else if (ASIC_IS_AVIVO(rdev)) { + /* in DP mode, the DP ref clock can come from either PPLL + * depending on the asic: + * DCE3: PPLL1 or PPLL2 + */ + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { + /* use the same PPLL for all DP monitors */ + pll = radeon_get_shared_dp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) + return pll; + } else { + /* use the same PPLL for all monitors with the same clock */ + pll = radeon_get_shared_nondp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) + return pll; + } + /* all other cases */ + pll_in_use = radeon_get_pll_use_mask(crtc); + /* the order shouldn't matter here, but we probably + * need this until we have atomic modeset + */ + if (rdev->flags & RADEON_IS_IGP) { + if (!(pll_in_use & (1 << ATOM_PPLL1))) + return ATOM_PPLL1; + if (!(pll_in_use & (1 << ATOM_PPLL2))) + return ATOM_PPLL2; + } else { + if (!(pll_in_use & (1 << ATOM_PPLL2))) + return ATOM_PPLL2; + if (!(pll_in_use & (1 << ATOM_PPLL1))) + return ATOM_PPLL1; + } + DRM_ERROR("unable to allocate a PPLL\n"); + return ATOM_PPLL_INVALID; } else { /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ - /* some atombios (observed in some DCE2/DCE3) code have a bug, - * the matching btw pll and crtc is done through - * PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the - * pll (1 or 2) to select which register to write. ie if using - * pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2 - * it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to - * choose which value to write. Which is reverse order from - * register logic. So only case that works is when pllid is - * same as crtcid or when both pll and crtc are enabled and - * both use same clock. - * - * So just return crtc id as if crtc and pll were hard linked - * together even if they aren't - */ return radeon_crtc->crtc_id; } } diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index a0f73092176e..636bae0405e8 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -963,7 +963,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) struct r1conf *conf = mddev->private; struct bio *bio; - if (from_schedule || current->bio_list) { + if (from_schedule) { spin_lock_irq(&conf->device_lock); bio_list_merge(&conf->pending_bio_list, &plug->pending); conf->pending_count += plug->pending_cnt; diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index c9acbd717131..0d5d0ff2c0f7 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1069,7 +1069,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) struct r10conf *conf = mddev->private; struct bio *bio; - if (from_schedule || current->bio_list) { + if (from_schedule) { spin_lock_irq(&conf->device_lock); bio_list_merge(&conf->pending_bio_list, &plug->pending); conf->pending_count += plug->pending_cnt; diff --git a/trunk/drivers/media/dvb-frontends/stv0900_core.c b/trunk/drivers/media/dvb-frontends/stv0900_core.c index b551ca350e00..262dfa503c2a 100644 --- a/trunk/drivers/media/dvb-frontends/stv0900_core.c +++ b/trunk/drivers/media/dvb-frontends/stv0900_core.c @@ -300,15 +300,15 @@ static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 { u32 m_div, clk_sel; + dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, + intp->quartz); + if (intp == NULL) return STV0900_INVALID_HANDLE; if (intp->errs) return STV0900_I2C_ERROR; - dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, - intp->quartz); - clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6); m_div = ((clk_sel * mclk) / intp->quartz) - 1; stv0900_write_bits(intp, F0900_M_DIV, m_div); diff --git a/trunk/drivers/media/i2c/adv7604.c b/trunk/drivers/media/i2c/adv7604.c index 05f8950f6f91..109bc9b12e74 100644 --- a/trunk/drivers/media/i2c/adv7604.c +++ b/trunk/drivers/media/i2c/adv7604.c @@ -53,7 +53,8 @@ MODULE_LICENSE("GPL"); /* ADV7604 system clock frequency */ #define ADV7604_fsc (28636360) -#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI) +#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \ + (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR)) /* ********************************************************************** @@ -67,7 +68,7 @@ struct adv7604_state { struct v4l2_subdev sd; struct media_pad pad; struct v4l2_ctrl_handler hdl; - enum adv7604_mode mode; + enum adv7604_prim_mode prim_mode; struct v4l2_dv_timings timings; u8 edid[256]; unsigned edid_blocks; @@ -76,7 +77,6 @@ struct adv7604_state { struct workqueue_struct *work_queues; struct delayed_work delayed_work_enable_hotplug; bool connector_hdmi; - bool restart_stdi_once; /* i2c clients */ struct i2c_client *i2c_avlink; @@ -106,6 +106,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = { V4L2_DV_BT_CEA_720X576P50, V4L2_DV_BT_CEA_1280X720P24, V4L2_DV_BT_CEA_1280X720P25, + V4L2_DV_BT_CEA_1280X720P30, V4L2_DV_BT_CEA_1280X720P50, V4L2_DV_BT_CEA_1280X720P60, V4L2_DV_BT_CEA_1920X1080P24, @@ -114,7 +115,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = { V4L2_DV_BT_CEA_1920X1080P50, V4L2_DV_BT_CEA_1920X1080P60, - /* sorted by DMT ID */ V4L2_DV_BT_DMT_640X350P85, V4L2_DV_BT_DMT_640X400P85, V4L2_DV_BT_DMT_720X400P85, @@ -164,89 +164,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = { { }, }; -struct adv7604_video_standards { - struct v4l2_dv_timings timings; - u8 vid_std; - u8 v_freq; -}; - -/* sorted by number of lines */ -static const struct adv7604_video_standards adv7604_prim_mode_comp[] = { - /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */ - { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, - { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 }, - { V4L2_DV_BT_CEA_1280X720P60, 0x19, 0x00 }, - { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 }, - { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 }, - { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 }, - { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 }, - { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 }, - /* TODO add 1920x1080P60_RB (CVT timing) */ - { }, -}; - -/* sorted by number of lines */ -static const struct adv7604_video_standards adv7604_prim_mode_gr[] = { - { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, - { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, - { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, - { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 }, - { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 }, - { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 }, - { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 }, - { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 }, - { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 }, - { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 }, - { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 }, - { V4L2_DV_BT_DMT_1360X768P60, 0x12, 0x00 }, - { V4L2_DV_BT_DMT_1366X768P60, 0x13, 0x00 }, - { V4L2_DV_BT_DMT_1400X1050P60, 0x14, 0x00 }, - { V4L2_DV_BT_DMT_1400X1050P75, 0x15, 0x00 }, - { V4L2_DV_BT_DMT_1600X1200P60, 0x16, 0x00 }, /* TODO not tested */ - /* TODO add 1600X1200P60_RB (not a DMT timing) */ - { V4L2_DV_BT_DMT_1680X1050P60, 0x18, 0x00 }, - { V4L2_DV_BT_DMT_1920X1200P60_RB, 0x19, 0x00 }, /* TODO not tested */ - { }, -}; - -/* sorted by number of lines */ -static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = { - { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, - { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, - { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 }, - { V4L2_DV_BT_CEA_1280X720P60, 0x13, 0x00 }, - { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 }, - { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 }, - { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 }, - { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 }, - { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 }, - { }, -}; - -/* sorted by number of lines */ -static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = { - { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, - { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, - { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, - { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 }, - { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 }, - { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 }, - { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 }, - { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 }, - { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 }, - { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 }, - { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 }, - { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 }, - { }, -}; - /* ----------------------------------------------------------------------- */ static inline struct adv7604_state *to_state(struct v4l2_subdev *sd) @@ -755,145 +672,65 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) ((io_read(sd, 0x6f) & 0x10) >> 4)); } -static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, - u8 prim_mode, - const struct adv7604_video_standards *predef_vid_timings, - const struct v4l2_dv_timings *timings) -{ - struct adv7604_state *state = to_state(sd); - int i; - - for (i = 0; predef_vid_timings[i].timings.bt.width; i++) { - if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings, - DIGITAL_INPUT ? 250000 : 1000000)) - continue; - io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */ - io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) + - prim_mode); /* v_freq and prim mode */ - return 0; - } - - return -1; -} - -static int configure_predefined_video_timings(struct v4l2_subdev *sd, - struct v4l2_dv_timings *timings) +static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings) { - struct adv7604_state *state = to_state(sd); - int err; - - v4l2_dbg(1, debug, sd, "%s", __func__); - - /* reset to default values */ - io_write(sd, 0x16, 0x43); - io_write(sd, 0x17, 0x5a); - /* disable embedded syncs for auto graphics mode */ - cp_write_and_or(sd, 0x81, 0xef, 0x00); - cp_write(sd, 0x8f, 0x00); - cp_write(sd, 0x90, 0x00); - cp_write(sd, 0xa2, 0x00); - cp_write(sd, 0xa3, 0x00); - cp_write(sd, 0xa4, 0x00); - cp_write(sd, 0xa5, 0x00); - cp_write(sd, 0xa6, 0x00); - cp_write(sd, 0xa7, 0x00); - cp_write(sd, 0xab, 0x00); - cp_write(sd, 0xac, 0x00); - - switch (state->mode) { - case ADV7604_MODE_COMP: - case ADV7604_MODE_GR: - err = find_and_set_predefined_video_timings(sd, - 0x01, adv7604_prim_mode_comp, timings); - if (err) - err = find_and_set_predefined_video_timings(sd, - 0x02, adv7604_prim_mode_gr, timings); - break; - case ADV7604_MODE_HDMI: - err = find_and_set_predefined_video_timings(sd, - 0x05, adv7604_prim_mode_hdmi_comp, timings); - if (err) - err = find_and_set_predefined_video_timings(sd, - 0x06, adv7604_prim_mode_hdmi_gr, timings); - break; - default: - v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", - __func__, state->mode); - err = -1; - break; - } - - - return err; -} - -static void configure_custom_video_timings(struct v4l2_subdev *sd, - const struct v4l2_bt_timings *bt) -{ - struct adv7604_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - u32 width = htotal(bt); - u32 height = vtotal(bt); - u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; - u16 cp_start_eav = width - bt->hfrontporch; - u16 cp_start_vbi = height - bt->vfrontporch; - u16 cp_end_vbi = bt->vsync + bt->vbackporch; - u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ? - ((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0; - const u8 pll[2] = { - 0xc0 | ((width >> 8) & 0x1f), - width & 0xff - }; + u32 width = htotal(timings); + u32 height = vtotal(timings); + u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ? + ((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0; v4l2_dbg(2, debug, sd, "%s\n", __func__); - switch (state->mode) { - case ADV7604_MODE_COMP: - case ADV7604_MODE_GR: - /* auto graphics */ - io_write(sd, 0x00, 0x07); /* video std */ - io_write(sd, 0x01, 0x02); /* prim mode */ - /* enable embedded syncs for auto graphics mode */ - cp_write_and_or(sd, 0x81, 0xef, 0x10); + cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); /* CH1_FR_LL */ + cp_write(sd, 0x90, ch1_fr_ll & 0xff); /* CH1_FR_LL */ + cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */ + cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */ + /* TODO support interlaced */ + cp_write(sd, 0x91, 0x10); /* INTERLACED */ + + /* Should only be set in auto-graphics mode [REF_02 p. 91-92] */ + if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) { + u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi; + const u8 pll[2] = { + (0xc0 | ((width >> 8) & 0x1f)), + (width & 0xff) + }; - /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ /* IO-map reg. 0x16 and 0x17 should be written in sequence */ if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) { v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); - break; + return; } /* active video - horizontal timing */ + cp_start_sav = timings->hsync + timings->hbackporch - 4; + cp_start_eav = width - timings->hfrontporch; cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff); - cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | - ((cp_start_eav >> 8) & 0x0f)); + cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f)); cp_write(sd, 0xa4, cp_start_eav & 0xff); /* active video - vertical timing */ + cp_start_vbi = height - timings->vfrontporch; + cp_end_vbi = timings->vsync + timings->vbackporch; cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff); - cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | - ((cp_end_vbi >> 8) & 0xf)); + cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf)); cp_write(sd, 0xa7, cp_end_vbi & 0xff); - break; - case ADV7604_MODE_HDMI: - /* set default prim_mode/vid_std for HDMI - accoring to [REF_03, c. 4.2] */ - io_write(sd, 0x00, 0x02); /* video std */ - io_write(sd, 0x01, 0x06); /* prim mode */ - break; - default: - v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", - __func__, state->mode); - break; + } else { + /* reset to default values */ + io_write(sd, 0x16, 0x43); + io_write(sd, 0x17, 0x5a); + cp_write(sd, 0xa2, 0x00); + cp_write(sd, 0xa3, 0x00); + cp_write(sd, 0xa4, 0x00); + cp_write(sd, 0xa5, 0x00); + cp_write(sd, 0xa6, 0x00); + cp_write(sd, 0xa7, 0x00); } - - cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); - cp_write(sd, 0x90, ch1_fr_ll & 0xff); - cp_write(sd, 0xab, (height >> 4) & 0xff); - cp_write(sd, 0xac, (height & 0x0f) << 4); } + static void set_rgb_quantization_range(struct v4l2_subdev *sd) { struct adv7604_state *state = to_state(sd); @@ -901,7 +738,12 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) switch (state->rgb_quantization_range) { case V4L2_DV_RGB_RANGE_AUTO: /* automatic */ - if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) { + if ((hdmi_read(sd, 0x05) & 0x80) || + (state->prim_mode == ADV7604_PRIM_MODE_COMP) || + (state->prim_mode == ADV7604_PRIM_MODE_RGB)) { + /* receiving HDMI or analog signal */ + io_write_and_or(sd, 0x02, 0x0f, 0xf0); + } else { /* receiving DVI-D signal */ /* ADV7604 selects RGB limited range regardless of @@ -914,9 +756,6 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) /* RGB full range (0-255) */ io_write_and_or(sd, 0x02, 0x0f, 0x10); } - } else { - /* receiving HDMI or analog signal, set automode */ - io_write_and_or(sd, 0x02, 0x0f, 0xf0); } break; case V4L2_DV_RGB_RANGE_LIMITED: @@ -1128,10 +967,8 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, state->aspect_ratio, timings)) return 0; - v4l2_dbg(2, debug, sd, - "%s: No format candidate found for lcvs = %d, lcf=%d, bl = %d, %chsync, %cvsync\n", - __func__, stdi->lcvs, stdi->lcf, stdi->bl, - stdi->hs_pol, stdi->vs_pol); + v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n", + __func__, stdi->lcf, stdi->bl); return -1; } @@ -1286,7 +1123,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, adv7604_fill_optional_dv_timings_fields(sd, timings); } else { /* find format - * Since LCVS values are inaccurate [REF_03, p. 275-276], + * Since LCVS values are inaccurate (REF_03, page 275-276), * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails. */ if (!stdi2dv_timings(sd, &stdi, timings)) @@ -1298,31 +1135,9 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, stdi.lcvs -= 2; v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs); if (stdi2dv_timings(sd, &stdi, timings)) { - /* - * The STDI block may measure wrong values, especially - * for lcvs and lcf. If the driver can not find any - * valid timing, the STDI block is restarted to measure - * the video timings again. The function will return an - * error, but the restart of STDI will generate a new - * STDI interrupt and the format detection process will - * restart. - */ - if (state->restart_stdi_once) { - v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__); - /* TODO restart STDI for Sync Channel 2 */ - /* enter one-shot mode */ - cp_write_and_or(sd, 0x86, 0xf9, 0x00); - /* trigger STDI restart */ - cp_write_and_or(sd, 0x86, 0xf9, 0x04); - /* reset to continuous mode */ - cp_write_and_or(sd, 0x86, 0xf9, 0x02); - state->restart_stdi_once = false; - return -ENOLINK; - } v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__); return -ERANGE; } - state->restart_stdi_once = true; } found: @@ -1351,7 +1166,6 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, { struct adv7604_state *state = to_state(sd); struct v4l2_bt_timings *bt; - int err; if (!timings) return -EINVAL; @@ -1364,20 +1178,12 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, __func__, (u32)bt->pixelclock); return -ERANGE; } - adv7604_fill_optional_dv_timings_fields(sd, timings); state->timings = *timings; - cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10); - - /* Use prim_mode and vid_std when available */ - err = configure_predefined_video_timings(sd, timings); - if (err) { - /* custom settings when the video format - does not have prim_mode/vid_std */ - configure_custom_video_timings(sd, bt); - } + /* freerun */ + configure_free_run(sd, bt); set_rgb_quantization_range(sd); @@ -1397,25 +1203,24 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd, return 0; } -static void enable_input(struct v4l2_subdev *sd) +static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) { - struct adv7604_state *state = to_state(sd); - - switch (state->mode) { - case ADV7604_MODE_COMP: - case ADV7604_MODE_GR: + switch (prim_mode) { + case ADV7604_PRIM_MODE_COMP: + case ADV7604_PRIM_MODE_RGB: /* enable */ io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ break; - case ADV7604_MODE_HDMI: + case ADV7604_PRIM_MODE_HDMI_COMP: + case ADV7604_PRIM_MODE_HDMI_GR: /* enable */ hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */ hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ break; default: - v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", - __func__, state->mode); + v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", + __func__, prim_mode); break; } } @@ -1428,13 +1233,17 @@ static void disable_input(struct v4l2_subdev *sd) hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ } -static void select_input(struct v4l2_subdev *sd) +static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) { - struct adv7604_state *state = to_state(sd); + switch (prim_mode) { + case ADV7604_PRIM_MODE_COMP: + case ADV7604_PRIM_MODE_RGB: + /* set mode and select free run resolution */ + io_write(sd, 0x00, 0x07); /* video std */ + io_write(sd, 0x01, 0x02); /* prim mode */ + /* enable embedded syncs for auto graphics mode */ + cp_write_and_or(sd, 0x81, 0xef, 0x10); - switch (state->mode) { - case ADV7604_MODE_COMP: - case ADV7604_MODE_GR: /* reset ADI recommended settings for HDMI: */ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */ @@ -1462,7 +1271,16 @@ static void select_input(struct v4l2_subdev *sd) cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */ break; - case ADV7604_MODE_HDMI: + case ADV7604_PRIM_MODE_HDMI_COMP: + case ADV7604_PRIM_MODE_HDMI_GR: + /* set mode and select free run resolution */ + /* video std */ + io_write(sd, 0x00, + (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e); + io_write(sd, 0x01, prim_mode); /* prim mode */ + /* disable embedded syncs for auto graphics mode */ + cp_write_and_or(sd, 0x81, 0xef, 0x00); + /* set ADI recommended settings for HDMI: */ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */ @@ -1491,8 +1309,7 @@ static void select_input(struct v4l2_subdev *sd) break; default: - v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", - __func__, state->mode); + v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode); break; } } @@ -1504,13 +1321,26 @@ static int adv7604_s_routing(struct v4l2_subdev *sd, v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input); - state->mode = input; + switch (input) { + case 0: + /* TODO select HDMI_COMP or HDMI_GR */ + state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP; + break; + case 1: + state->prim_mode = ADV7604_PRIM_MODE_RGB; + break; + case 2: + state->prim_mode = ADV7604_PRIM_MODE_COMP; + break; + default: + return -EINVAL; + } disable_input(sd); - select_input(sd); + select_input(sd, state->prim_mode); - enable_input(sd); + enable_input(sd, state->prim_mode); return 0; } @@ -1719,9 +1549,8 @@ static int adv7604_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true"); v4l2_info(sd, "CP free run: %s\n", (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off")); - v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n", - io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f, - (io_read(sd, 0x01) & 0x70) >> 4); + v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n", + io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f); v4l2_info(sd, "-----Video Timings-----\n"); if (read_stdi(sd, &stdi)) @@ -1883,9 +1712,9 @@ static int adv7604_core_init(struct v4l2_subdev *sd) cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */ cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */ cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold - - ADI recommended setting [REF_01, c. 2.3.3] */ + ADI recommended setting [REF_01 c. 2.3.3] */ cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold - - ADI recommended setting [REF_01, c. 2.3.3] */ + ADI recommended setting [REF_01 c. 2.3.3] */ cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution for digital formats */ @@ -1895,6 +1724,11 @@ static int adv7604_core_init(struct v4l2_subdev *sd) afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4); + state->prim_mode = pdata->prim_mode; + select_input(sd, pdata->prim_mode); + + enable_input(sd, pdata->prim_mode); + /* interrupts */ io_write(sd, 0x40, 0xc2); /* Configure INT1 */ io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */ @@ -2049,7 +1883,6 @@ static int adv7604_probe(struct i2c_client *client, v4l2_err(sd, "failed to create all i2c clients\n"); goto err_i2c; } - state->restart_stdi_once = true; /* work queues */ state->work_queues = create_singlethread_workqueue(client->name); diff --git a/trunk/drivers/media/i2c/soc_camera/mt9v022.c b/trunk/drivers/media/i2c/soc_camera/mt9v022.c index 333ef178d6fb..13057b966ee9 100644 --- a/trunk/drivers/media/i2c/soc_camera/mt9v022.c +++ b/trunk/drivers/media/i2c/soc_camera/mt9v022.c @@ -263,14 +263,9 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) if (ret & 1) /* Autoexposure */ ret = reg_write(client, mt9v022->reg->max_total_shutter_width, rect.height + mt9v022->y_skip_top + 43); - /* - * If autoexposure is off, there is no need to set - * MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off - * only if the user has set exposure manually, using the - * V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL. - * In this case the register MT9V022_TOTAL_SHUTTER_WIDTH - * already contains the correct value. - */ + else + ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, + rect.height + mt9v022->y_skip_top + 43); } /* Setup frame format: defaults apart from width and height */ if (!ret) diff --git a/trunk/drivers/media/platform/exynos-gsc/gsc-core.c b/trunk/drivers/media/platform/exynos-gsc/gsc-core.c index 19cbb12a12a2..bfec9e65aefb 100644 --- a/trunk/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/trunk/drivers/media/platform/exynos-gsc/gsc-core.c @@ -965,10 +965,8 @@ static struct platform_device_id gsc_driver_ids[] = { MODULE_DEVICE_TABLE(platform, gsc_driver_ids); static const struct of_device_id exynos_gsc_match[] = { - { - .compatible = "samsung,exynos5-gsc", - .data = &gsc_v_100_drvdata, - }, + { .compatible = "samsung,exynos5250-gsc", + .data = &gsc_v_100_drvdata, }, {}, }; MODULE_DEVICE_TABLE(of, exynos_gsc_match); diff --git a/trunk/drivers/media/platform/exynos-gsc/gsc-m2m.c b/trunk/drivers/media/platform/exynos-gsc/gsc-m2m.c index c065d040ed94..3c7f00577bd9 100644 --- a/trunk/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/trunk/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -657,7 +657,8 @@ static int gsc_m2m_release(struct file *file) pr_debug("pid: %d, state: 0x%lx, refcnt= %d", task_pid_nr(current), gsc->state, gsc->m2m.refcnt); - mutex_lock(&gsc->lock); + if (mutex_lock_interruptible(&gsc->lock)) + return -ERESTARTSYS; v4l2_m2m_ctx_release(ctx->m2m_ctx); gsc_ctrls_delete(ctx); @@ -731,7 +732,6 @@ int gsc_register_m2m_device(struct gsc_dev *gsc) gsc->vdev.ioctl_ops = &gsc_m2m_ioctl_ops; gsc->vdev.release = video_device_release_empty; gsc->vdev.lock = &gsc->lock; - gsc->vdev.vfl_dir = VFL_DIR_M2M; snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m", GSC_MODULE_NAME, gsc->id); diff --git a/trunk/drivers/media/platform/exynos-gsc/gsc-regs.h b/trunk/drivers/media/platform/exynos-gsc/gsc-regs.h index 4678f9a6a4fd..533e9947a925 100644 --- a/trunk/drivers/media/platform/exynos-gsc/gsc-regs.h +++ b/trunk/drivers/media/platform/exynos-gsc/gsc-regs.h @@ -40,10 +40,10 @@ #define GSC_IN_ROT_YFLIP (2 << 16) #define GSC_IN_ROT_XFLIP (1 << 16) #define GSC_IN_RGB_TYPE_MASK (3 << 14) -#define GSC_IN_RGB_HD_NARROW (3 << 14) -#define GSC_IN_RGB_HD_WIDE (2 << 14) -#define GSC_IN_RGB_SD_NARROW (1 << 14) -#define GSC_IN_RGB_SD_WIDE (0 << 14) +#define GSC_IN_RGB_HD_WIDE (3 << 14) +#define GSC_IN_RGB_HD_NARROW (2 << 14) +#define GSC_IN_RGB_SD_WIDE (1 << 14) +#define GSC_IN_RGB_SD_NARROW (0 << 14) #define GSC_IN_YUV422_1P_ORDER_MASK (1 << 13) #define GSC_IN_YUV422_1P_ORDER_LSB_Y (0 << 13) #define GSC_IN_YUV422_1P_OEDER_LSB_C (1 << 13) @@ -85,10 +85,10 @@ #define GSC_OUT_GLOBAL_ALPHA_MASK (0xff << 24) #define GSC_OUT_GLOBAL_ALPHA(x) ((x) << 24) #define GSC_OUT_RGB_TYPE_MASK (3 << 10) -#define GSC_OUT_RGB_HD_WIDE (3 << 10) -#define GSC_OUT_RGB_HD_NARROW (2 << 10) -#define GSC_OUT_RGB_SD_WIDE (1 << 10) -#define GSC_OUT_RGB_SD_NARROW (0 << 10) +#define GSC_OUT_RGB_HD_NARROW (3 << 10) +#define GSC_OUT_RGB_HD_WIDE (2 << 10) +#define GSC_OUT_RGB_SD_NARROW (1 << 10) +#define GSC_OUT_RGB_SD_WIDE (0 << 10) #define GSC_OUT_YUV422_1P_ORDER_MASK (1 << 9) #define GSC_OUT_YUV422_1P_ORDER_LSB_Y (0 << 9) #define GSC_OUT_YUV422_1P_OEDER_LSB_C (1 << 9) diff --git a/trunk/drivers/media/platform/omap3isp/ispccdc.c b/trunk/drivers/media/platform/omap3isp/ispccdc.c index aa9df9d71a7b..60181ab96063 100644 --- a/trunk/drivers/media/platform/omap3isp/ispccdc.c +++ b/trunk/drivers/media/platform/omap3isp/ispccdc.c @@ -1706,7 +1706,7 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { if (sub->type != V4L2_EVENT_FRAME_SYNC) return -EINVAL; @@ -1719,7 +1719,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, } static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { return v4l2_event_unsubscribe(fh, sub); } diff --git a/trunk/drivers/media/platform/omap3isp/ispstat.c b/trunk/drivers/media/platform/omap3isp/ispstat.c index b8640be692f1..d7ac76b5c2ae 100644 --- a/trunk/drivers/media/platform/omap3isp/ispstat.c +++ b/trunk/drivers/media/platform/omap3isp/ispstat.c @@ -1025,7 +1025,7 @@ void omap3isp_stat_dma_isr(struct ispstat *stat) int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { struct ispstat *stat = v4l2_get_subdevdata(subdev); @@ -1037,7 +1037,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) + const struct v4l2_event_subscription *sub) { return v4l2_event_unsubscribe(fh, sub); } diff --git a/trunk/drivers/media/platform/omap3isp/ispstat.h b/trunk/drivers/media/platform/omap3isp/ispstat.h index 9b7c8654dc8a..a6fe653eb237 100644 --- a/trunk/drivers/media/platform/omap3isp/ispstat.h +++ b/trunk/drivers/media/platform/omap3isp/ispstat.h @@ -147,10 +147,10 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name, void omap3isp_stat_cleanup(struct ispstat *stat); int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub); + const struct v4l2_event_subscription *sub); int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub); + const struct v4l2_event_subscription *sub); int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable); int omap3isp_stat_busy(struct ispstat *stat); diff --git a/trunk/drivers/media/platform/omap3isp/ispvideo.c b/trunk/drivers/media/platform/omap3isp/ispvideo.c index 75cd309035f9..a0b737fecf13 100644 --- a/trunk/drivers/media/platform/omap3isp/ispvideo.c +++ b/trunk/drivers/media/platform/omap3isp/ispvideo.c @@ -792,7 +792,7 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop) } static int -isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop) +isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop) { struct isp_video *video = video_drvdata(file); struct v4l2_subdev *subdev; diff --git a/trunk/drivers/media/platform/s5p-fimc/Kconfig b/trunk/drivers/media/platform/s5p-fimc/Kconfig index c16b20d86ed2..8f090a8f270e 100644 --- a/trunk/drivers/media/platform/s5p-fimc/Kconfig +++ b/trunk/drivers/media/platform/s5p-fimc/Kconfig @@ -24,7 +24,6 @@ config VIDEO_S5P_FIMC config VIDEO_S5P_MIPI_CSIS tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver" depends on REGULATOR - select S5P_SETUP_MIPIPHY help This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2 receiver (MIPI-CSIS) devices. diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-capture.c b/trunk/drivers/media/platform/s5p-fimc/fimc-capture.c index 891ee873c62b..367efd164d0f 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -556,7 +556,8 @@ static int fimc_capture_close(struct file *file) dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); - mutex_lock(&fimc->lock); + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; if (--fimc->vid_cap.refcnt == 0) { clear_bit(ST_CAPT_BUSY, &fimc->state); @@ -1735,9 +1736,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct fimc_vid_buffer); - ret = vb2_queue_init(q); - if (ret) - goto err_ent; + vb2_queue_init(q); vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); @@ -1773,13 +1772,9 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd) if (ret) return ret; - fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd); - ret = fimc_register_capture_device(fimc, sd->v4l2_dev); - if (ret) { + if (ret) fimc_unregister_m2m_device(fimc); - fimc->pipeline_ops = NULL; - } return ret; } @@ -1796,7 +1791,6 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd) if (video_is_registered(&fimc->vid_cap.vfd)) { video_unregister_device(&fimc->vid_cap.vfd); media_entity_cleanup(&fimc->vid_cap.vfd.entity); - fimc->pipeline_ops = NULL; } kfree(fimc->vid_cap.ctx); fimc->vid_cap.ctx = NULL; diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c b/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c index 1b309a72f09f..70bcf39de879 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-lite.c @@ -491,7 +491,8 @@ static int fimc_lite_close(struct file *file) struct fimc_lite *fimc = video_drvdata(file); int ret; - mutex_lock(&fimc->lock); + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { clear_bit(ST_FLITE_IN_USE, &fimc->state); @@ -1252,9 +1253,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) q->buf_struct_size = sizeof(struct flite_buffer); q->drv_priv = fimc; - ret = vb2_queue_init(q); - if (ret < 0) - return ret; + vb2_queue_init(q); fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); @@ -1262,12 +1261,10 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) return ret; video_set_drvdata(vfd, fimc); - fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd); ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret < 0) { media_entity_cleanup(&vfd->entity); - fimc->pipeline_ops = NULL; return ret; } @@ -1286,7 +1283,6 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd) if (video_is_registered(&fimc->vfd)) { video_unregister_device(&fimc->vfd); media_entity_cleanup(&fimc->vfd.entity); - fimc->pipeline_ops = NULL; } } diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-m2m.c b/trunk/drivers/media/platform/s5p-fimc/fimc-m2m.c index 62afed3162ea..4500e44f6857 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-m2m.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-m2m.c @@ -718,7 +718,8 @@ static int fimc_m2m_release(struct file *file) dbg("pid: %d, state: 0x%lx, refcnt= %d", task_pid_nr(current), fimc->state, fimc->m2m.refcnt); - mutex_lock(&fimc->lock); + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; v4l2_m2m_ctx_release(ctx->m2m_ctx); fimc_ctrls_delete(ctx); diff --git a/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c index 0531ab70a94c..80ada5882f62 100644 --- a/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/trunk/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -343,50 +343,53 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) static int fimc_register_callback(struct device *dev, void *p) { struct fimc_dev *fimc = dev_get_drvdata(dev); - struct v4l2_subdev *sd; + struct v4l2_subdev *sd = &fimc->vid_cap.subdev; struct fimc_md *fmd = p; - int ret; + int ret = 0; - if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS) + if (!fimc || !fimc->pdev) return 0; - sd = &fimc->vid_cap.subdev; + if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS) + return 0; + + fimc->pipeline_ops = &fimc_pipeline_ops; + fmd->fimc[fimc->pdev->id] = fimc; sd->grp_id = FIMC_GROUP_ID; - v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops); ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); if (ret) { v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n", fimc->id, ret); - return ret; } - fmd->fimc[fimc->id] = fimc; - return 0; + return ret; } static int fimc_lite_register_callback(struct device *dev, void *p) { struct fimc_lite *fimc = dev_get_drvdata(dev); + struct v4l2_subdev *sd = &fimc->subdev; struct fimc_md *fmd = p; int ret; - if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS) + if (fimc == NULL) return 0; - fimc->subdev.grp_id = FLITE_GROUP_ID; - v4l2_set_subdev_hostdata(&fimc->subdev, (void *)&fimc_pipeline_ops); + if (fimc->index >= FIMC_LITE_MAX_DEVS) + return 0; + + fimc->pipeline_ops = &fimc_pipeline_ops; + fmd->fimc_lite[fimc->index] = fimc; + sd->grp_id = FLITE_GROUP_ID; - ret = v4l2_device_register_subdev(&fmd->v4l2_dev, &fimc->subdev); + ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); if (ret) { v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC-LITE.%d (%d)\n", fimc->index, ret); - return ret; } - - fmd->fimc_lite[fimc->index] = fimc; - return 0; + return ret; } static int csis_register_callback(struct device *dev, void *p) @@ -404,12 +407,10 @@ static int csis_register_callback(struct device *dev, void *p) v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name); id = pdev->id < 0 ? 0 : pdev->id; + fmd->csis[id].sd = sd; sd->grp_id = CSIS_GROUP_ID; - ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); - if (!ret) - fmd->csis[id].sd = sd; - else + if (ret) v4l2_err(&fmd->v4l2_dev, "Failed to register CSIS subdevice: %d\n", ret); return ret; diff --git a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c index 3afe879d54d7..130f4ac8649e 100644 --- a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -381,8 +381,11 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops, get_consumed_stream, dev); if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC && - ctx->consumed_stream + STUFF_BYTE < - src_buf->b->v4l2_planes[0].bytesused) { + s5p_mfc_hw_call(dev->mfc_ops, + get_dec_frame_type, dev) == + S5P_FIMV_DECODE_FRAME_P_FRAME + && ctx->consumed_stream + STUFF_BYTE < + src_buf->b->v4l2_planes[0].bytesused) { /* Run MFC again on the same buffer */ mfc_debug(2, "Running again the same buffer\n"); ctx->after_packed_pb = 1; diff --git a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 3a8cfd9fc1bd..50b5bee3c44e 100644 --- a/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/trunk/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -1762,7 +1762,7 @@ int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) { - return mfc_read(dev, S5P_FIMV_D_DECODED_LUMA_ADDR_V6); + return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6); } int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) diff --git a/trunk/drivers/media/platform/sh_vou.c b/trunk/drivers/media/platform/sh_vou.c index a1c87f0ceaab..85fd312f0a82 100644 --- a/trunk/drivers/media/platform/sh_vou.c +++ b/trunk/drivers/media/platform/sh_vou.c @@ -935,10 +935,9 @@ static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a) /* Assume a dull encoder, do all the work ourselves. */ static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a) { - struct v4l2_crop a_writable = *a; struct video_device *vdev = video_devdata(file); struct sh_vou_device *vou_dev = video_get_drvdata(vdev); - struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &a->c; struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT}; struct v4l2_pix_format *pix = &vou_dev->pix; struct sh_vou_geometry geo; diff --git a/trunk/drivers/media/platform/soc_camera/mx1_camera.c b/trunk/drivers/media/platform/soc_camera/mx1_camera.c index 032b8c9097f9..bbe70991d30b 100644 --- a/trunk/drivers/media/platform/soc_camera/mx1_camera.c +++ b/trunk/drivers/media/platform/soc_camera/mx1_camera.c @@ -470,6 +470,14 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd) pcdev->icd = NULL; } +static int mx1_camera_set_crop(struct soc_camera_device *icd, + struct v4l2_crop *a) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + return v4l2_subdev_call(sd, video, s_crop, a); +} + static int mx1_camera_set_bus_param(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); @@ -681,6 +689,7 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = { .add = mx1_camera_add_device, .remove = mx1_camera_remove_device, .set_bus_param = mx1_camera_set_bus_param, + .set_crop = mx1_camera_set_crop, .set_fmt = mx1_camera_set_fmt, .try_fmt = mx1_camera_try_fmt, .init_videobuf = mx1_camera_init_videobuf, diff --git a/trunk/drivers/media/platform/soc_camera/mx2_camera.c b/trunk/drivers/media/platform/soc_camera/mx2_camera.c index 9a55f4c4c7f4..9fd9d1c5b218 100644 --- a/trunk/drivers/media/platform/soc_camera/mx2_camera.c +++ b/trunk/drivers/media/platform/soc_camera/mx2_camera.c @@ -864,10 +864,8 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) bytesperline = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); - if (bytesperline < 0) { - spin_unlock_irqrestore(&pcdev->lock, flags); + if (bytesperline < 0) return bytesperline; - } /* * I didn't manage to properly enable/disable the prp @@ -880,10 +878,8 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev, pcdev->discard_size, &pcdev->discard_buffer_dma, GFP_KERNEL); - if (!pcdev->discard_buffer) { - spin_unlock_irqrestore(&pcdev->lock, flags); + if (!pcdev->discard_buffer) return -ENOMEM; - } pcdev->buf_discard[0].discard = true; list_add_tail(&pcdev->buf_discard[0].queue, @@ -1103,10 +1099,9 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) } static int mx2_camera_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) + struct v4l2_crop *a) { - struct v4l2_crop a_writable = *a; - struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &a->c; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct v4l2_mbus_framefmt mf; int ret; diff --git a/trunk/drivers/media/platform/soc_camera/mx3_camera.c b/trunk/drivers/media/platform/soc_camera/mx3_camera.c index 261f6e9e1b17..3557ac97e430 100644 --- a/trunk/drivers/media/platform/soc_camera/mx3_camera.c +++ b/trunk/drivers/media/platform/soc_camera/mx3_camera.c @@ -799,10 +799,9 @@ static inline void stride_align(__u32 *width) * default g_crop and cropcap from soc_camera.c */ static int mx3_camera_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) + struct v4l2_crop *a) { - struct v4l2_crop a_writable = *a; - struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &a->c; struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx3_camera_dev *mx3_cam = ici->priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); diff --git a/trunk/drivers/media/platform/soc_camera/omap1_camera.c b/trunk/drivers/media/platform/soc_camera/omap1_camera.c index 13636a585106..fa08c7695ccb 100644 --- a/trunk/drivers/media/platform/soc_camera/omap1_camera.c +++ b/trunk/drivers/media/platform/soc_camera/omap1_camera.c @@ -1215,9 +1215,9 @@ static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev, } static int omap1_cam_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *crop) + struct v4l2_crop *crop) { - const struct v4l2_rect *rect = &crop->c; + struct v4l2_rect *rect = &crop->c; const struct soc_camera_format_xlate *xlate = icd->current_fmt; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; diff --git a/trunk/drivers/media/platform/soc_camera/pxa_camera.c b/trunk/drivers/media/platform/soc_camera/pxa_camera.c index 3434ffe79c6e..1e3776d08dac 100644 --- a/trunk/drivers/media/platform/soc_camera/pxa_camera.c +++ b/trunk/drivers/media/platform/soc_camera/pxa_camera.c @@ -1337,9 +1337,9 @@ static int pxa_camera_check_frame(u32 width, u32 height) } static int pxa_camera_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) + struct v4l2_crop *a) { - const struct v4l2_rect *rect = &a->c; + struct v4l2_rect *rect = &a->c; struct device *dev = icd->parent; struct soc_camera_host *ici = to_soc_camera_host(dev); struct pxa_camera_dev *pcdev = ici->priv; diff --git a/trunk/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/trunk/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 2d8861c0e8f2..0a24253dcda2 100644 --- a/trunk/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1182,13 +1182,13 @@ static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd) } /* Check if any dimension of r1 is smaller than respective one of r2 */ -static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2) +static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2) { return r1->width < r2->width || r1->height < r2->height; } /* Check if r1 fails to cover r2 */ -static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2) +static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2) { return r1->left > r2->left || r1->top > r2->top || r1->left + r1->width < r2->left + r2->width || @@ -1263,7 +1263,7 @@ static void update_subrect(struct sh_mobile_ceu_cam *cam) * 3. if (2) failed, try to request the maximum image */ static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop, - struct v4l2_crop *cam_crop) + const struct v4l2_crop *cam_crop) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c; @@ -1519,8 +1519,7 @@ static int client_scale(struct soc_camera_device *icd, static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, const struct v4l2_crop *a) { - struct v4l2_crop a_writable = *a; - const struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &a->c; struct device *dev = icd->parent; struct soc_camera_host *ici = to_soc_camera_host(dev); struct sh_mobile_ceu_dev *pcdev = ici->priv; @@ -1546,7 +1545,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, * 1. - 2. Apply iterative camera S_CROP for new input window, read back * actual camera rectangle. */ - ret = client_s_crop(icd, &a_writable, &cam_crop); + ret = client_s_crop(icd, a, &cam_crop); if (ret < 0) return ret; @@ -1947,7 +1946,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, } static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd, - const struct v4l2_crop *a) + struct v4l2_crop *a) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); diff --git a/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index ba51f65204de..9859d2a2449b 100644 --- a/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -283,13 +283,14 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, /* activate the pid on the device pid filter */ if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER && - adap->pid_filtering && adap->props->pid_filter) { + adap->pid_filtering && + adap->props->pid_filter) ret = adap->props->pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid, (count == 1) ? 1 : 0); - if (ret < 0) - dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n", - KBUILD_MODNAME, ret); - } + if (ret < 0) + dev_err(&d->udev->dev, "%s: pid_filter() " \ + "failed=%d\n", KBUILD_MODNAME, + ret); /* start feeding if it is first pid */ if (adap->feed_count == 1 && count == 1) { diff --git a/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c index 5716662b4834..0431beed0ef4 100644 --- a/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c +++ b/trunk/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c @@ -32,7 +32,9 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, return -EINVAL; } - mutex_lock(&d->usb_mutex); + ret = mutex_lock_interruptible(&d->usb_mutex); + if (ret < 0) + return ret; dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf); diff --git a/trunk/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/trunk/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 093f1acce403..adabba8d28bc 100644 --- a/trunk/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/trunk/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1346,10 +1346,6 @@ static const struct usb_device_id rtl28xxu_id_table[] = { &rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) }, { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3, &rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) }, - { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102, - &rtl2832u_props, "Dexatek DK mini DVB-T Dongle", NULL) }, - { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d7, - &rtl2832u_props, "TerraTec Cinergy T Stick+", NULL) }, { } }; MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table); diff --git a/trunk/drivers/mfd/arizona-core.c b/trunk/drivers/mfd/arizona-core.c index f4f9bf84bc7b..1b48f2094806 100644 --- a/trunk/drivers/mfd/arizona-core.c +++ b/trunk/drivers/mfd/arizona-core.c @@ -96,11 +96,11 @@ static irqreturn_t arizona_underclocked(int irq, void *data) return IRQ_NONE; } + if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) + dev_err(arizona->dev, "AIF3 underclocked\n"); if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) dev_err(arizona->dev, "AIF3 underclocked\n"); if (val & ARIZONA_AIF2_UNDERCLOCKED_STS) - dev_err(arizona->dev, "AIF2 underclocked\n"); - if (val & ARIZONA_AIF1_UNDERCLOCKED_STS) dev_err(arizona->dev, "AIF1 underclocked\n"); if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS) dev_err(arizona->dev, "ISRC2 underclocked\n"); @@ -415,19 +415,11 @@ int __devinit arizona_dev_init(struct arizona *arizona) /* If we have a /RESET GPIO we'll already be reset */ if (!arizona->pdata.reset) { - regcache_mark_dirty(arizona->regmap); - ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err_reset; } - - ret = regcache_sync(arizona->regmap); - if (ret != 0) { - dev_err(dev, "Failed to sync device: %d\n", ret); - goto err_reset; - } } ret = arizona_wait_for_boot(arizona); @@ -528,7 +520,7 @@ int __devinit arizona_dev_init(struct arizona *arizona) break; case WM5110: ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, - ARRAY_SIZE(wm5110_devs), NULL, 0, NULL); + ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); break; } diff --git a/trunk/drivers/mfd/arizona-irq.c b/trunk/drivers/mfd/arizona-irq.c index b1b009177405..ef0f2d001df2 100644 --- a/trunk/drivers/mfd/arizona-irq.c +++ b/trunk/drivers/mfd/arizona-irq.c @@ -178,7 +178,6 @@ int arizona_irq_init(struct arizona *arizona) switch (arizona->rev) { case 0: - case 1: ctrlif_error = false; break; default: diff --git a/trunk/drivers/mfd/twl-core.c b/trunk/drivers/mfd/twl-core.c index a071a8643a47..4ae642320205 100644 --- a/trunk/drivers/mfd/twl-core.c +++ b/trunk/drivers/mfd/twl-core.c @@ -671,7 +671,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, } if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) { - child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0, + child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0, false, 0, 0); if (IS_ERR(child)) return PTR_ERR(child); diff --git a/trunk/drivers/mfd/twl4030-irq.c b/trunk/drivers/mfd/twl4030-irq.c index cdd1173ed4e9..ad733d76207a 100644 --- a/trunk/drivers/mfd/twl4030-irq.c +++ b/trunk/drivers/mfd/twl4030-irq.c @@ -672,8 +672,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) irq = sih_mod + twl4030_irq_base; irq_set_handler_data(irq, agent); agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); - status = request_threaded_irq(irq, NULL, handle_twl4030_sih, - IRQF_EARLY_RESUME, + status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, agent->irq_name ?: sih->name, NULL); dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, diff --git a/trunk/drivers/mfd/wm5102-tables.c b/trunk/drivers/mfd/wm5102-tables.c index 14490cc785d2..01b9255ed631 100644 --- a/trunk/drivers/mfd/wm5102-tables.c +++ b/trunk/drivers/mfd/wm5102-tables.c @@ -43,7 +43,6 @@ static const struct reg_default wm5102_reva_patch[] = { { 0x479, 0x0A30 }, { 0x47B, 0x0810 }, { 0x47D, 0x0510 }, - { 0x4D1, 0x017F }, { 0x500, 0x000D }, { 0x507, 0x1820 }, { 0x508, 0x1820 }, @@ -53,6 +52,524 @@ static const struct reg_default wm5102_reva_patch[] = { { 0x580, 0x000D }, { 0x587, 0x1820 }, { 0x588, 0x1820 }, + { 0x101, 0x8140 }, + { 0x3000, 0x2225 }, + { 0x3001, 0x3a03 }, + { 0x3002, 0x0225 }, + { 0x3003, 0x0801 }, + { 0x3004, 0x6249 }, + { 0x3005, 0x0c04 }, + { 0x3006, 0x0225 }, + { 0x3007, 0x5901 }, + { 0x3008, 0xe249 }, + { 0x3009, 0x030d }, + { 0x300a, 0x0249 }, + { 0x300b, 0x2c01 }, + { 0x300c, 0xe249 }, + { 0x300d, 0x4342 }, + { 0x300e, 0xe249 }, + { 0x300f, 0x73c0 }, + { 0x3010, 0x4249 }, + { 0x3011, 0x0c00 }, + { 0x3012, 0x0225 }, + { 0x3013, 0x1f01 }, + { 0x3014, 0x0225 }, + { 0x3015, 0x1e01 }, + { 0x3016, 0x0225 }, + { 0x3017, 0xfa00 }, + { 0x3018, 0x0000 }, + { 0x3019, 0xf000 }, + { 0x301a, 0x0000 }, + { 0x301b, 0xf000 }, + { 0x301c, 0x0000 }, + { 0x301d, 0xf000 }, + { 0x301e, 0x0000 }, + { 0x301f, 0xf000 }, + { 0x3020, 0x0000 }, + { 0x3021, 0xf000 }, + { 0x3022, 0x0000 }, + { 0x3023, 0xf000 }, + { 0x3024, 0x0000 }, + { 0x3025, 0xf000 }, + { 0x3026, 0x0000 }, + { 0x3027, 0xf000 }, + { 0x3028, 0x0000 }, + { 0x3029, 0xf000 }, + { 0x302a, 0x0000 }, + { 0x302b, 0xf000 }, + { 0x302c, 0x0000 }, + { 0x302d, 0xf000 }, + { 0x302e, 0x0000 }, + { 0x302f, 0xf000 }, + { 0x3030, 0x0225 }, + { 0x3031, 0x1a01 }, + { 0x3032, 0x0225 }, + { 0x3033, 0x1e00 }, + { 0x3034, 0x0225 }, + { 0x3035, 0x1f00 }, + { 0x3036, 0x6225 }, + { 0x3037, 0xf800 }, + { 0x3038, 0x0000 }, + { 0x3039, 0xf000 }, + { 0x303a, 0x0000 }, + { 0x303b, 0xf000 }, + { 0x303c, 0x0000 }, + { 0x303d, 0xf000 }, + { 0x303e, 0x0000 }, + { 0x303f, 0xf000 }, + { 0x3040, 0x2226 }, + { 0x3041, 0x3a03 }, + { 0x3042, 0x0226 }, + { 0x3043, 0x0801 }, + { 0x3044, 0x6249 }, + { 0x3045, 0x0c06 }, + { 0x3046, 0x0226 }, + { 0x3047, 0x5901 }, + { 0x3048, 0xe249 }, + { 0x3049, 0x030d }, + { 0x304a, 0x0249 }, + { 0x304b, 0x2c01 }, + { 0x304c, 0xe249 }, + { 0x304d, 0x4342 }, + { 0x304e, 0xe249 }, + { 0x304f, 0x73c0 }, + { 0x3050, 0x4249 }, + { 0x3051, 0x0c00 }, + { 0x3052, 0x0226 }, + { 0x3053, 0x1f01 }, + { 0x3054, 0x0226 }, + { 0x3055, 0x1e01 }, + { 0x3056, 0x0226 }, + { 0x3057, 0xfa00 }, + { 0x3058, 0x0000 }, + { 0x3059, 0xf000 }, + { 0x305a, 0x0000 }, + { 0x305b, 0xf000 }, + { 0x305c, 0x0000 }, + { 0x305d, 0xf000 }, + { 0x305e, 0x0000 }, + { 0x305f, 0xf000 }, + { 0x3060, 0x0000 }, + { 0x3061, 0xf000 }, + { 0x3062, 0x0000 }, + { 0x3063, 0xf000 }, + { 0x3064, 0x0000 }, + { 0x3065, 0xf000 }, + { 0x3066, 0x0000 }, + { 0x3067, 0xf000 }, + { 0x3068, 0x0000 }, + { 0x3069, 0xf000 }, + { 0x306a, 0x0000 }, + { 0x306b, 0xf000 }, + { 0x306c, 0x0000 }, + { 0x306d, 0xf000 }, + { 0x306e, 0x0000 }, + { 0x306f, 0xf000 }, + { 0x3070, 0x0226 }, + { 0x3071, 0x1a01 }, + { 0x3072, 0x0226 }, + { 0x3073, 0x1e00 }, + { 0x3074, 0x0226 }, + { 0x3075, 0x1f00 }, + { 0x3076, 0x6226 }, + { 0x3077, 0xf800 }, + { 0x3078, 0x0000 }, + { 0x3079, 0xf000 }, + { 0x307a, 0x0000 }, + { 0x307b, 0xf000 }, + { 0x307c, 0x0000 }, + { 0x307d, 0xf000 }, + { 0x307e, 0x0000 }, + { 0x307f, 0xf000 }, + { 0x3080, 0x2227 }, + { 0x3081, 0x3a03 }, + { 0x3082, 0x0227 }, + { 0x3083, 0x0801 }, + { 0x3084, 0x6255 }, + { 0x3085, 0x0c04 }, + { 0x3086, 0x0227 }, + { 0x3087, 0x5901 }, + { 0x3088, 0xe255 }, + { 0x3089, 0x030d }, + { 0x308a, 0x0255 }, + { 0x308b, 0x2c01 }, + { 0x308c, 0xe255 }, + { 0x308d, 0x4342 }, + { 0x308e, 0xe255 }, + { 0x308f, 0x73c0 }, + { 0x3090, 0x4255 }, + { 0x3091, 0x0c00 }, + { 0x3092, 0x0227 }, + { 0x3093, 0x1f01 }, + { 0x3094, 0x0227 }, + { 0x3095, 0x1e01 }, + { 0x3096, 0x0227 }, + { 0x3097, 0xfa00 }, + { 0x3098, 0x0000 }, + { 0x3099, 0xf000 }, + { 0x309a, 0x0000 }, + { 0x309b, 0xf000 }, + { 0x309c, 0x0000 }, + { 0x309d, 0xf000 }, + { 0x309e, 0x0000 }, + { 0x309f, 0xf000 }, + { 0x30a0, 0x0000 }, + { 0x30a1, 0xf000 }, + { 0x30a2, 0x0000 }, + { 0x30a3, 0xf000 }, + { 0x30a4, 0x0000 }, + { 0x30a5, 0xf000 }, + { 0x30a6, 0x0000 }, + { 0x30a7, 0xf000 }, + { 0x30a8, 0x0000 }, + { 0x30a9, 0xf000 }, + { 0x30aa, 0x0000 }, + { 0x30ab, 0xf000 }, + { 0x30ac, 0x0000 }, + { 0x30ad, 0xf000 }, + { 0x30ae, 0x0000 }, + { 0x30af, 0xf000 }, + { 0x30b0, 0x0227 }, + { 0x30b1, 0x1a01 }, + { 0x30b2, 0x0227 }, + { 0x30b3, 0x1e00 }, + { 0x30b4, 0x0227 }, + { 0x30b5, 0x1f00 }, + { 0x30b6, 0x6227 }, + { 0x30b7, 0xf800 }, + { 0x30b8, 0x0000 }, + { 0x30b9, 0xf000 }, + { 0x30ba, 0x0000 }, + { 0x30bb, 0xf000 }, + { 0x30bc, 0x0000 }, + { 0x30bd, 0xf000 }, + { 0x30be, 0x0000 }, + { 0x30bf, 0xf000 }, + { 0x30c0, 0x2228 }, + { 0x30c1, 0x3a03 }, + { 0x30c2, 0x0228 }, + { 0x30c3, 0x0801 }, + { 0x30c4, 0x6255 }, + { 0x30c5, 0x0c06 }, + { 0x30c6, 0x0228 }, + { 0x30c7, 0x5901 }, + { 0x30c8, 0xe255 }, + { 0x30c9, 0x030d }, + { 0x30ca, 0x0255 }, + { 0x30cb, 0x2c01 }, + { 0x30cc, 0xe255 }, + { 0x30cd, 0x4342 }, + { 0x30ce, 0xe255 }, + { 0x30cf, 0x73c0 }, + { 0x30d0, 0x4255 }, + { 0x30d1, 0x0c00 }, + { 0x30d2, 0x0228 }, + { 0x30d3, 0x1f01 }, + { 0x30d4, 0x0228 }, + { 0x30d5, 0x1e01 }, + { 0x30d6, 0x0228 }, + { 0x30d7, 0xfa00 }, + { 0x30d8, 0x0000 }, + { 0x30d9, 0xf000 }, + { 0x30da, 0x0000 }, + { 0x30db, 0xf000 }, + { 0x30dc, 0x0000 }, + { 0x30dd, 0xf000 }, + { 0x30de, 0x0000 }, + { 0x30df, 0xf000 }, + { 0x30e0, 0x0000 }, + { 0x30e1, 0xf000 }, + { 0x30e2, 0x0000 }, + { 0x30e3, 0xf000 }, + { 0x30e4, 0x0000 }, + { 0x30e5, 0xf000 }, + { 0x30e6, 0x0000 }, + { 0x30e7, 0xf000 }, + { 0x30e8, 0x0000 }, + { 0x30e9, 0xf000 }, + { 0x30ea, 0x0000 }, + { 0x30eb, 0xf000 }, + { 0x30ec, 0x0000 }, + { 0x30ed, 0xf000 }, + { 0x30ee, 0x0000 }, + { 0x30ef, 0xf000 }, + { 0x30f0, 0x0228 }, + { 0x30f1, 0x1a01 }, + { 0x30f2, 0x0228 }, + { 0x30f3, 0x1e00 }, + { 0x30f4, 0x0228 }, + { 0x30f5, 0x1f00 }, + { 0x30f6, 0x6228 }, + { 0x30f7, 0xf800 }, + { 0x30f8, 0x0000 }, + { 0x30f9, 0xf000 }, + { 0x30fa, 0x0000 }, + { 0x30fb, 0xf000 }, + { 0x30fc, 0x0000 }, + { 0x30fd, 0xf000 }, + { 0x30fe, 0x0000 }, + { 0x30ff, 0xf000 }, + { 0x3100, 0x222b }, + { 0x3101, 0x3a03 }, + { 0x3102, 0x222b }, + { 0x3103, 0x5803 }, + { 0x3104, 0xe26f }, + { 0x3105, 0x030d }, + { 0x3106, 0x626f }, + { 0x3107, 0x2c01 }, + { 0x3108, 0xe26f }, + { 0x3109, 0x4342 }, + { 0x310a, 0xe26f }, + { 0x310b, 0x73c0 }, + { 0x310c, 0x026f }, + { 0x310d, 0x0c00 }, + { 0x310e, 0x022b }, + { 0x310f, 0x1f01 }, + { 0x3110, 0x022b }, + { 0x3111, 0x1e01 }, + { 0x3112, 0x022b }, + { 0x3113, 0xfa00 }, + { 0x3114, 0x0000 }, + { 0x3115, 0xf000 }, + { 0x3116, 0x0000 }, + { 0x3117, 0xf000 }, + { 0x3118, 0x0000 }, + { 0x3119, 0xf000 }, + { 0x311a, 0x0000 }, + { 0x311b, 0xf000 }, + { 0x311c, 0x0000 }, + { 0x311d, 0xf000 }, + { 0x311e, 0x0000 }, + { 0x311f, 0xf000 }, + { 0x3120, 0x022b }, + { 0x3121, 0x0a01 }, + { 0x3122, 0x022b }, + { 0x3123, 0x1e00 }, + { 0x3124, 0x022b }, + { 0x3125, 0x1f00 }, + { 0x3126, 0x622b }, + { 0x3127, 0xf800 }, + { 0x3128, 0x0000 }, + { 0x3129, 0xf000 }, + { 0x312a, 0x0000 }, + { 0x312b, 0xf000 }, + { 0x312c, 0x0000 }, + { 0x312d, 0xf000 }, + { 0x312e, 0x0000 }, + { 0x312f, 0xf000 }, + { 0x3130, 0x0000 }, + { 0x3131, 0xf000 }, + { 0x3132, 0x0000 }, + { 0x3133, 0xf000 }, + { 0x3134, 0x0000 }, + { 0x3135, 0xf000 }, + { 0x3136, 0x0000 }, + { 0x3137, 0xf000 }, + { 0x3138, 0x0000 }, + { 0x3139, 0xf000 }, + { 0x313a, 0x0000 }, + { 0x313b, 0xf000 }, + { 0x313c, 0x0000 }, + { 0x313d, 0xf000 }, + { 0x313e, 0x0000 }, + { 0x313f, 0xf000 }, + { 0x3140, 0x0000 }, + { 0x3141, 0xf000 }, + { 0x3142, 0x0000 }, + { 0x3143, 0xf000 }, + { 0x3144, 0x0000 }, + { 0x3145, 0xf000 }, + { 0x3146, 0x0000 }, + { 0x3147, 0xf000 }, + { 0x3148, 0x0000 }, + { 0x3149, 0xf000 }, + { 0x314a, 0x0000 }, + { 0x314b, 0xf000 }, + { 0x314c, 0x0000 }, + { 0x314d, 0xf000 }, + { 0x314e, 0x0000 }, + { 0x314f, 0xf000 }, + { 0x3150, 0x0000 }, + { 0x3151, 0xf000 }, + { 0x3152, 0x0000 }, + { 0x3153, 0xf000 }, + { 0x3154, 0x0000 }, + { 0x3155, 0xf000 }, + { 0x3156, 0x0000 }, + { 0x3157, 0xf000 }, + { 0x3158, 0x0000 }, + { 0x3159, 0xf000 }, + { 0x315a, 0x0000 }, + { 0x315b, 0xf000 }, + { 0x315c, 0x0000 }, + { 0x315d, 0xf000 }, + { 0x315e, 0x0000 }, + { 0x315f, 0xf000 }, + { 0x3160, 0x0000 }, + { 0x3161, 0xf000 }, + { 0x3162, 0x0000 }, + { 0x3163, 0xf000 }, + { 0x3164, 0x0000 }, + { 0x3165, 0xf000 }, + { 0x3166, 0x0000 }, + { 0x3167, 0xf000 }, + { 0x3168, 0x0000 }, + { 0x3169, 0xf000 }, + { 0x316a, 0x0000 }, + { 0x316b, 0xf000 }, + { 0x316c, 0x0000 }, + { 0x316d, 0xf000 }, + { 0x316e, 0x0000 }, + { 0x316f, 0xf000 }, + { 0x3170, 0x0000 }, + { 0x3171, 0xf000 }, + { 0x3172, 0x0000 }, + { 0x3173, 0xf000 }, + { 0x3174, 0x0000 }, + { 0x3175, 0xf000 }, + { 0x3176, 0x0000 }, + { 0x3177, 0xf000 }, + { 0x3178, 0x0000 }, + { 0x3179, 0xf000 }, + { 0x317a, 0x0000 }, + { 0x317b, 0xf000 }, + { 0x317c, 0x0000 }, + { 0x317d, 0xf000 }, + { 0x317e, 0x0000 }, + { 0x317f, 0xf000 }, + { 0x3180, 0x2001 }, + { 0x3181, 0xf101 }, + { 0x3182, 0x0000 }, + { 0x3183, 0xf000 }, + { 0x3184, 0x0000 }, + { 0x3185, 0xf000 }, + { 0x3186, 0x0000 }, + { 0x3187, 0xf000 }, + { 0x3188, 0x0000 }, + { 0x3189, 0xf000 }, + { 0x318a, 0x0000 }, + { 0x318b, 0xf000 }, + { 0x318c, 0x0000 }, + { 0x318d, 0xf000 }, + { 0x318e, 0x0000 }, + { 0x318f, 0xf000 }, + { 0x3190, 0x0000 }, + { 0x3191, 0xf000 }, + { 0x3192, 0x0000 }, + { 0x3193, 0xf000 }, + { 0x3194, 0x0000 }, + { 0x3195, 0xf000 }, + { 0x3196, 0x0000 }, + { 0x3197, 0xf000 }, + { 0x3198, 0x0000 }, + { 0x3199, 0xf000 }, + { 0x319a, 0x0000 }, + { 0x319b, 0xf000 }, + { 0x319c, 0x0000 }, + { 0x319d, 0xf000 }, + { 0x319e, 0x0000 }, + { 0x319f, 0xf000 }, + { 0x31a0, 0x0000 }, + { 0x31a1, 0xf000 }, + { 0x31a2, 0x0000 }, + { 0x31a3, 0xf000 }, + { 0x31a4, 0x0000 }, + { 0x31a5, 0xf000 }, + { 0x31a6, 0x0000 }, + { 0x31a7, 0xf000 }, + { 0x31a8, 0x0000 }, + { 0x31a9, 0xf000 }, + { 0x31aa, 0x0000 }, + { 0x31ab, 0xf000 }, + { 0x31ac, 0x0000 }, + { 0x31ad, 0xf000 }, + { 0x31ae, 0x0000 }, + { 0x31af, 0xf000 }, + { 0x31b0, 0x0000 }, + { 0x31b1, 0xf000 }, + { 0x31b2, 0x0000 }, + { 0x31b3, 0xf000 }, + { 0x31b4, 0x0000 }, + { 0x31b5, 0xf000 }, + { 0x31b6, 0x0000 }, + { 0x31b7, 0xf000 }, + { 0x31b8, 0x0000 }, + { 0x31b9, 0xf000 }, + { 0x31ba, 0x0000 }, + { 0x31bb, 0xf000 }, + { 0x31bc, 0x0000 }, + { 0x31bd, 0xf000 }, + { 0x31be, 0x0000 }, + { 0x31bf, 0xf000 }, + { 0x31c0, 0x0000 }, + { 0x31c1, 0xf000 }, + { 0x31c2, 0x0000 }, + { 0x31c3, 0xf000 }, + { 0x31c4, 0x0000 }, + { 0x31c5, 0xf000 }, + { 0x31c6, 0x0000 }, + { 0x31c7, 0xf000 }, + { 0x31c8, 0x0000 }, + { 0x31c9, 0xf000 }, + { 0x31ca, 0x0000 }, + { 0x31cb, 0xf000 }, + { 0x31cc, 0x0000 }, + { 0x31cd, 0xf000 }, + { 0x31ce, 0x0000 }, + { 0x31cf, 0xf000 }, + { 0x31d0, 0x0000 }, + { 0x31d1, 0xf000 }, + { 0x31d2, 0x0000 }, + { 0x31d3, 0xf000 }, + { 0x31d4, 0x0000 }, + { 0x31d5, 0xf000 }, + { 0x31d6, 0x0000 }, + { 0x31d7, 0xf000 }, + { 0x31d8, 0x0000 }, + { 0x31d9, 0xf000 }, + { 0x31da, 0x0000 }, + { 0x31db, 0xf000 }, + { 0x31dc, 0x0000 }, + { 0x31dd, 0xf000 }, + { 0x31de, 0x0000 }, + { 0x31df, 0xf000 }, + { 0x31e0, 0x0000 }, + { 0x31e1, 0xf000 }, + { 0x31e2, 0x0000 }, + { 0x31e3, 0xf000 }, + { 0x31e4, 0x0000 }, + { 0x31e5, 0xf000 }, + { 0x31e6, 0x0000 }, + { 0x31e7, 0xf000 }, + { 0x31e8, 0x0000 }, + { 0x31e9, 0xf000 }, + { 0x31ea, 0x0000 }, + { 0x31eb, 0xf000 }, + { 0x31ec, 0x0000 }, + { 0x31ed, 0xf000 }, + { 0x31ee, 0x0000 }, + { 0x31ef, 0xf000 }, + { 0x31f0, 0x0000 }, + { 0x31f1, 0xf000 }, + { 0x31f2, 0x0000 }, + { 0x31f3, 0xf000 }, + { 0x31f4, 0x0000 }, + { 0x31f5, 0xf000 }, + { 0x31f6, 0x0000 }, + { 0x31f7, 0xf000 }, + { 0x31f8, 0x0000 }, + { 0x31f9, 0xf000 }, + { 0x31fa, 0x0000 }, + { 0x31fb, 0xf000 }, + { 0x31fc, 0x0000 }, + { 0x31fd, 0xf000 }, + { 0x31fe, 0x0000 }, + { 0x31ff, 0xf000 }, + { 0x024d, 0xff50 }, + { 0x0252, 0xff50 }, + { 0x0259, 0x0112 }, + { 0x025e, 0x0112 }, + { 0x101, 0x0304 }, { 0x80, 0x0000 }, }; diff --git a/trunk/drivers/mtd/ubi/wl.c b/trunk/drivers/mtd/ubi/wl.c index 2144f611196e..da7b44998b40 100644 --- a/trunk/drivers/mtd/ubi/wl.c +++ b/trunk/drivers/mtd/ubi/wl.c @@ -498,7 +498,7 @@ struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor) * @ubi: UBI device description object * * This function returns a physical eraseblock in case of success and a - * negative error code in case of failure. + * negative error code in case of failure. Might sleep. */ static int __wl_get_peb(struct ubi_device *ubi) { @@ -540,6 +540,13 @@ static int __wl_get_peb(struct ubi_device *ubi) * ubi_wl_get_peb() after removing e from the pool. */ prot_queue_add(ubi, e); #endif + err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, + ubi->peb_size - ubi->vid_hdr_aloffset); + if (err) { + ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); + return err; + } + return e->pnum; } @@ -672,30 +679,17 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) #else static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) { - struct ubi_wl_entry *e; - - e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); - self_check_in_wl_tree(ubi, e, &ubi->free); - rb_erase(&e->u.rb, &ubi->free); - - return e; + return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); } int ubi_wl_get_peb(struct ubi_device *ubi) { - int peb, err; + int peb; spin_lock(&ubi->wl_lock); peb = __wl_get_peb(ubi); spin_unlock(&ubi->wl_lock); - err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, - ubi->peb_size - ubi->vid_hdr_aloffset); - if (err) { - ubi_err("new PEB %d does not contain all 0xFF bytes", peb); - return err; - } - return peb; } #endif diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index a7d47350ea4b..5f5b69f37d2e 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -3459,28 +3459,6 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) /*-------------------------- Device entry points ----------------------------*/ -static void bond_work_init_all(struct bonding *bond) -{ - INIT_DELAYED_WORK(&bond->mcast_work, - bond_resend_igmp_join_requests_delayed); - INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); - INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); - if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) - INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon); - else - INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon); - INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); -} - -static void bond_work_cancel_all(struct bonding *bond) -{ - cancel_delayed_work_sync(&bond->mii_work); - cancel_delayed_work_sync(&bond->arp_work); - cancel_delayed_work_sync(&bond->alb_work); - cancel_delayed_work_sync(&bond->ad_work); - cancel_delayed_work_sync(&bond->mcast_work); -} - static int bond_open(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); @@ -3503,27 +3481,41 @@ static int bond_open(struct net_device *bond_dev) } read_unlock(&bond->lock); - bond_work_init_all(bond); + INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); if (bond_is_lb(bond)) { /* bond_alb_initialize must be called before the timer * is started. */ - if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) + if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) { + /* something went wrong - fail the open operation */ return -ENOMEM; + } + + INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); queue_delayed_work(bond->wq, &bond->alb_work, 0); } - if (bond->params.miimon) /* link check interval, in milliseconds. */ + if (bond->params.miimon) { /* link check interval, in milliseconds. */ + INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); queue_delayed_work(bond->wq, &bond->mii_work, 0); + } if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) + INIT_DELAYED_WORK(&bond->arp_work, + bond_activebackup_arp_mon); + else + INIT_DELAYED_WORK(&bond->arp_work, + bond_loadbalance_arp_mon); + queue_delayed_work(bond->wq, &bond->arp_work, 0); if (bond->params.arp_validate) bond->recv_probe = bond_arp_rcv; } if (bond->params.mode == BOND_MODE_8023AD) { + INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); queue_delayed_work(bond->wq, &bond->ad_work, 0); /* register to receive LACPDUs */ bond->recv_probe = bond_3ad_lacpdu_recv; @@ -3538,10 +3530,34 @@ static int bond_close(struct net_device *bond_dev) struct bonding *bond = netdev_priv(bond_dev); write_lock_bh(&bond->lock); + bond->send_peer_notif = 0; + write_unlock_bh(&bond->lock); - bond_work_cancel_all(bond); + if (bond->params.miimon) { /* link check interval, in milliseconds. */ + cancel_delayed_work_sync(&bond->mii_work); + } + + if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ + cancel_delayed_work_sync(&bond->arp_work); + } + + switch (bond->params.mode) { + case BOND_MODE_8023AD: + cancel_delayed_work_sync(&bond->ad_work); + break; + case BOND_MODE_TLB: + case BOND_MODE_ALB: + cancel_delayed_work_sync(&bond->alb_work); + break; + default: + break; + } + + if (delayed_work_pending(&bond->mcast_work)) + cancel_delayed_work_sync(&bond->mcast_work); + if (bond_is_lb(bond)) { /* Must be called only after all * slaves have been released @@ -4420,6 +4436,26 @@ static void bond_setup(struct net_device *bond_dev) bond_dev->features |= bond_dev->hw_features; } +static void bond_work_cancel_all(struct bonding *bond) +{ + if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) + cancel_delayed_work_sync(&bond->mii_work); + + if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) + cancel_delayed_work_sync(&bond->arp_work); + + if (bond->params.mode == BOND_MODE_ALB && + delayed_work_pending(&bond->alb_work)) + cancel_delayed_work_sync(&bond->alb_work); + + if (bond->params.mode == BOND_MODE_8023AD && + delayed_work_pending(&bond->ad_work)) + cancel_delayed_work_sync(&bond->ad_work); + + if (delayed_work_pending(&bond->mcast_work)) + cancel_delayed_work_sync(&bond->mcast_work); +} + /* * Destroy a bonding device. * Must be under rtnl_lock when this function is called. @@ -4670,13 +4706,12 @@ static int bond_check_params(struct bond_params *params) arp_ip_count++) { /* not complete check, but should be good enough to catch mistakes */ - __be32 ip = in_aton(arp_ip_target[arp_ip_count]); - if (!isdigit(arp_ip_target[arp_ip_count][0]) || - ip == 0 || ip == htonl(INADDR_BROADCAST)) { + if (!isdigit(arp_ip_target[arp_ip_count][0])) { pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", arp_ip_target[arp_ip_count]); arp_interval = 0; } else { + __be32 ip = in_aton(arp_ip_target[arp_ip_count]); arp_target[arp_ip_count] = ip; } } diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index 1877ed7ca086..ef8d2a080d17 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -513,8 +513,6 @@ static ssize_t bonding_store_arp_interval(struct device *d, int new_value, ret = count; struct bonding *bond = to_bond(d); - if (!rtnl_trylock()) - return restart_syscall(); if (sscanf(buf, "%d", &new_value) != 1) { pr_err("%s: no arp_interval value specified.\n", bond->dev->name); @@ -541,6 +539,10 @@ static ssize_t bonding_store_arp_interval(struct device *d, pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", bond->dev->name, bond->dev->name); bond->params.miimon = 0; + if (delayed_work_pending(&bond->mii_work)) { + cancel_delayed_work(&bond->mii_work); + flush_workqueue(bond->wq); + } } if (!bond->params.arp_targets[0]) { pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", @@ -552,12 +554,19 @@ static ssize_t bonding_store_arp_interval(struct device *d, * timer will get fired off when the open function * is called. */ - cancel_delayed_work_sync(&bond->mii_work); - queue_delayed_work(bond->wq, &bond->arp_work, 0); + if (!delayed_work_pending(&bond->arp_work)) { + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) + INIT_DELAYED_WORK(&bond->arp_work, + bond_activebackup_arp_mon); + else + INIT_DELAYED_WORK(&bond->arp_work, + bond_loadbalance_arp_mon); + + queue_delayed_work(bond->wq, &bond->arp_work, 0); + } } out: - rtnl_unlock(); return ret; } static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, @@ -953,8 +962,6 @@ static ssize_t bonding_store_miimon(struct device *d, int new_value, ret = count; struct bonding *bond = to_bond(d); - if (!rtnl_trylock()) - return restart_syscall(); if (sscanf(buf, "%d", &new_value) != 1) { pr_err("%s: no miimon value specified.\n", bond->dev->name); @@ -986,6 +993,10 @@ static ssize_t bonding_store_miimon(struct device *d, bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; } + if (delayed_work_pending(&bond->arp_work)) { + cancel_delayed_work(&bond->arp_work); + flush_workqueue(bond->wq); + } } if (bond->dev->flags & IFF_UP) { @@ -994,12 +1005,15 @@ static ssize_t bonding_store_miimon(struct device *d, * timer will get fired off when the open function * is called. */ - cancel_delayed_work_sync(&bond->arp_work); - queue_delayed_work(bond->wq, &bond->mii_work, 0); + if (!delayed_work_pending(&bond->mii_work)) { + INIT_DELAYED_WORK(&bond->mii_work, + bond_mii_monitor); + queue_delayed_work(bond->wq, + &bond->mii_work, 0); + } } } out: - rtnl_unlock(); return ret; } static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, @@ -1568,7 +1582,6 @@ static ssize_t bonding_store_slaves_active(struct device *d, goto out; } - read_lock(&bond->lock); bond_for_each_slave(bond, slave, i) { if (!bond_is_active_slave(slave)) { if (new_value) @@ -1577,7 +1590,6 @@ static ssize_t bonding_store_slaves_active(struct device *d, slave->inactive = 1; } } - read_unlock(&bond->lock); out: return ret; } diff --git a/trunk/drivers/net/can/usb/peak_usb/pcan_usb.c b/trunk/drivers/net/can/usb/peak_usb/pcan_usb.c index 25723d8ee201..86f26a1ede4c 100644 --- a/trunk/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/trunk/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -519,10 +519,8 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, mc->pdev->dev.can.state = new_state; if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { - struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); - peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); - hwts->hwtstamp = timeval_to_ktime(tv); + skb->tstamp = timeval_to_ktime(tv); } netif_rx(skb); @@ -607,7 +605,6 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) struct sk_buff *skb; struct can_frame *cf; struct timeval tv; - struct skb_shared_hwtstamps *hwts; skb = alloc_can_skb(mc->netdev, &cf); if (!skb) @@ -655,8 +652,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) /* convert timestamp into kernel time */ peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); - hwts = skb_hwtstamps(skb); - hwts->hwtstamp = timeval_to_ktime(tv); + skb->tstamp = timeval_to_ktime(tv); /* push the skb */ netif_rx(skb); diff --git a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 30d79bfa5b10..e1626d92511a 100644 --- a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -532,7 +532,6 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, struct can_frame *can_frame; struct sk_buff *skb; struct timeval tv; - struct skb_shared_hwtstamps *hwts; skb = alloc_can_skb(netdev, &can_frame); if (!skb) @@ -550,8 +549,7 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, memcpy(can_frame->data, rx->data, can_frame->can_dlc); peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv); - hwts = skb_hwtstamps(skb); - hwts->hwtstamp = timeval_to_ktime(tv); + skb->tstamp = timeval_to_ktime(tv); netif_rx(skb); netdev->stats.rx_packets++; @@ -572,7 +570,6 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, u8 err_mask = 0; struct sk_buff *skb; struct timeval tv; - struct skb_shared_hwtstamps *hwts; /* nothing should be sent while in BUS_OFF state */ if (dev->can.state == CAN_STATE_BUS_OFF) @@ -667,8 +664,7 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, dev->can.state = new_state; peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv); - hwts = skb_hwtstamps(skb); - hwts->hwtstamp = timeval_to_ktime(tv); + skb->tstamp = timeval_to_ktime(tv); netif_rx(skb); netdev->stats.rx_packets++; netdev->stats.rx_bytes += can_frame->can_dlc; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c index b799ab12a291..5d36795877cb 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c @@ -237,7 +237,7 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev, if (err) return err; - memcpy(priv->maxrate, tmp, sizeof(priv->maxrate)); + memcpy(priv->maxrate, tmp, sizeof(*priv->maxrate)); return 0; } diff --git a/trunk/drivers/net/ethernet/realtek/8139cp.c b/trunk/drivers/net/ethernet/realtek/8139cp.c index 609125a249d9..b01f83a044c4 100644 --- a/trunk/drivers/net/ethernet/realtek/8139cp.c +++ b/trunk/drivers/net/ethernet/realtek/8139cp.c @@ -1060,22 +1060,17 @@ static int cp_init_rings (struct cp_private *cp) static int cp_alloc_rings (struct cp_private *cp) { - struct device *d = &cp->pdev->dev; void *mem; - int rc; - mem = dma_alloc_coherent(d, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL); + mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES, + &cp->ring_dma, GFP_KERNEL); if (!mem) return -ENOMEM; cp->rx_ring = mem; cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE]; - rc = cp_init_rings(cp); - if (rc < 0) - dma_free_coherent(d, CP_RING_BYTES, cp->rx_ring, cp->ring_dma); - - return rc; + return cp_init_rings(cp); } static void cp_clean_rings (struct cp_private *cp) diff --git a/trunk/drivers/net/team/team.c b/trunk/drivers/net/team/team.c index ad86660fb8f9..d44cca327588 100644 --- a/trunk/drivers/net/team/team.c +++ b/trunk/drivers/net/team/team.c @@ -1794,12 +1794,10 @@ static void team_setup(struct net_device *dev) dev->features |= NETIF_F_LLTX; dev->features |= NETIF_F_GRO; - dev->hw_features = TEAM_VLAN_FEATURES | - NETIF_F_HW_VLAN_TX | + dev->hw_features = NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM); dev->features |= dev->hw_features; } diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index 1ea91f4237f0..3b566fa0f8e6 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -385,7 +385,6 @@ static const struct usb_device_id products[] = { }, /* 3. Combined interface devices matching on interface number */ - {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, diff --git a/trunk/drivers/net/wan/ixp4xx_hss.c b/trunk/drivers/net/wan/ixp4xx_hss.c index 760776b3d66c..e9a3da588e95 100644 --- a/trunk/drivers/net/wan/ixp4xx_hss.c +++ b/trunk/drivers/net/wan/ixp4xx_hss.c @@ -1365,7 +1365,7 @@ static int __devinit hss_init_one(struct platform_device *pdev) platform_set_drvdata(pdev, port); - netdev_info(dev, "initialized\n"); + netdev_info(dev, "HSS-%i\n", port->id); return 0; err_free_netdev: diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c index 2830ea290502..10896393e5a0 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv, * As a consequence, it's not as complicated as it sounds, just add * any lower rates to the ACK rate bitmap. */ - if (IWL_RATE_11M_INDEX < lowest_present_cck) - cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; - if (IWL_RATE_5M_INDEX < lowest_present_cck) - cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; - if (IWL_RATE_2M_INDEX < lowest_present_cck) - cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_11M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_5M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_2M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; /* 1M already there or needed so always add */ cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; diff --git a/trunk/drivers/remoteproc/remoteproc_virtio.c b/trunk/drivers/remoteproc/remoteproc_virtio.c index 9e198e590675..e7a4780e93db 100644 --- a/trunk/drivers/remoteproc/remoteproc_virtio.c +++ b/trunk/drivers/remoteproc/remoteproc_virtio.c @@ -120,11 +120,15 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev, return vq; } -static void __rproc_virtio_del_vqs(struct virtio_device *vdev) +static void rproc_virtio_del_vqs(struct virtio_device *vdev) { struct virtqueue *vq, *n; + struct rproc *rproc = vdev_to_rproc(vdev); struct rproc_vring *rvring; + /* power down the remote processor before deleting vqs */ + rproc_shutdown(rproc); + list_for_each_entry_safe(vq, n, &vdev->vqs, list) { rvring = vq->priv; rvring->vq = NULL; @@ -133,16 +137,6 @@ static void __rproc_virtio_del_vqs(struct virtio_device *vdev) } } -static void rproc_virtio_del_vqs(struct virtio_device *vdev) -{ - struct rproc *rproc = vdev_to_rproc(vdev); - - /* power down the remote processor before deleting vqs */ - rproc_shutdown(rproc); - - __rproc_virtio_del_vqs(vdev); -} - static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, struct virtqueue *vqs[], vq_callback_t *callbacks[], @@ -169,7 +163,7 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, return 0; error: - __rproc_virtio_del_vqs(vdev); + rproc_virtio_del_vqs(vdev); return ret; } diff --git a/trunk/drivers/rtc/rtc-tps65910.c b/trunk/drivers/rtc/rtc-tps65910.c index 073108dcf9e7..7a82337e4dee 100644 --- a/trunk/drivers/rtc/rtc-tps65910.c +++ b/trunk/drivers/rtc/rtc-tps65910.c @@ -288,11 +288,11 @@ static int __devinit tps65910_rtc_probe(struct platform_device *pdev) static int __devexit tps65910_rtc_remove(struct platform_device *pdev) { /* leave rtc running, but disable irqs */ - struct tps65910_rtc *tps_rtc = platform_get_drvdata(pdev); + struct rtc_device *rtc = platform_get_drvdata(pdev); - tps65910_rtc_alarm_irq_enable(&pdev->dev, 0); + tps65910_rtc_alarm_irq_enable(&rtc->dev, 0); - rtc_device_unregister(tps_rtc->rtc); + rtc_device_unregister(rtc); return 0; } diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index 3b2365c8eab2..16b7a72a70c4 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -1276,7 +1276,7 @@ struct megasas_evt_detail { } __attribute__ ((packed)); struct megasas_aen_event { - struct delayed_work hotplug_work; + struct work_struct hotplug_work; struct megasas_instance *instance; }; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c index e4f2baacf1e1..d2c5366aff7f 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2060,9 +2060,9 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) } else { ev->instance = instance; instance->ev = ev; - INIT_DELAYED_WORK(&ev->hotplug_work, - megasas_aen_polling); - schedule_delayed_work(&ev->hotplug_work, 0); + INIT_WORK(&ev->hotplug_work, megasas_aen_polling); + schedule_delayed_work( + (struct delayed_work *)&ev->hotplug_work, 0); } } } @@ -4352,7 +4352,8 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) /* cancel the delayed work if this work still in queue */ if (instance->ev != NULL) { struct megasas_aen_event *ev = instance->ev; - cancel_delayed_work_sync(&ev->hotplug_work); + cancel_delayed_work_sync( + (struct delayed_work *)&ev->hotplug_work); instance->ev = NULL; } @@ -4544,7 +4545,8 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev) /* cancel the delayed work if this work still in queue*/ if (instance->ev != NULL) { struct megasas_aen_event *ev = instance->ev; - cancel_delayed_work_sync(&ev->hotplug_work); + cancel_delayed_work_sync( + (struct delayed_work *)&ev->hotplug_work); instance->ev = NULL; } @@ -5188,7 +5190,7 @@ static void megasas_aen_polling(struct work_struct *work) { struct megasas_aen_event *ev = - container_of(work, struct megasas_aen_event, hotplug_work.work); + container_of(work, struct megasas_aen_event, hotplug_work); struct megasas_instance *instance = ev->instance; union megasas_evt_class_locale class_locale; struct Scsi_Host *host; diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index dcecbfb17243..9097155e9ebe 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -1819,10 +1819,8 @@ void target_execute_cmd(struct se_cmd *cmd) /* * If the received CDB has aleady been aborted stop processing it here. */ - if (transport_check_aborted_status(cmd, 1)) { - complete(&cmd->t_transport_stop_comp); + if (transport_check_aborted_status(cmd, 1)) return; - } /* * Determine if IOCTL context caller in requesting the stopping of this @@ -3069,7 +3067,7 @@ void transport_send_task_abort(struct se_cmd *cmd) unsigned long flags; spin_lock_irqsave(&cmd->t_state_lock, flags); - if (cmd->se_cmd_flags & (SCF_SENT_CHECK_CONDITION | SCF_SENT_DELAYED_TAS)) { + if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); return; } diff --git a/trunk/drivers/tty/vt/vt.c b/trunk/drivers/tty/vt/vt.c index 4e0d0c3734b3..f87d7e8964bf 100644 --- a/trunk/drivers/tty/vt/vt.c +++ b/trunk/drivers/tty/vt/vt.c @@ -539,25 +539,25 @@ static void insert_char(struct vc_data *vc, unsigned int nr) { unsigned short *p = (unsigned short *) vc->vc_pos; - scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2); + scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x); scr_memsetw(p, vc->vc_video_erase_char, nr * 2); vc->vc_need_wrap = 0; if (DO_UPDATE(vc)) do_update_region(vc, (unsigned long) p, - vc->vc_cols - vc->vc_x); + (vc->vc_cols - vc->vc_x) / 2 + 1); } static void delete_char(struct vc_data *vc, unsigned int nr) { unsigned short *p = (unsigned short *) vc->vc_pos; - scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2); + scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr); scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, nr * 2); vc->vc_need_wrap = 0; if (DO_UPDATE(vc)) do_update_region(vc, (unsigned long) p, - vc->vc_cols - vc->vc_x); + (vc->vc_cols - vc->vc_x) / 2); } static int softcursor_original; diff --git a/trunk/drivers/vhost/vhost.c b/trunk/drivers/vhost/vhost.c index dedaf81d8f36..99ac2cb08b43 100644 --- a/trunk/drivers/vhost/vhost.c +++ b/trunk/drivers/vhost/vhost.c @@ -1076,7 +1076,7 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len, } _iov = iov + ret; size = reg->memory_size - addr + reg->guest_phys_addr; - _iov->iov_len = min((u64)len - s, size); + _iov->iov_len = min((u64)len, size); _iov->iov_base = (void __user *)(unsigned long) (reg->userspace_addr + addr - reg->guest_phys_addr); s += size; diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index a1e09b4fe1ba..1a1e5e3b1eaf 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -70,6 +70,19 @@ static void bdev_inode_switch_bdi(struct inode *inode, spin_unlock(&dst->wb.list_lock); } +sector_t blkdev_max_block(struct block_device *bdev) +{ + sector_t retval = ~((sector_t)0); + loff_t sz = i_size_read(bdev->bd_inode); + + if (sz) { + unsigned int size = block_size(bdev); + unsigned int sizebits = blksize_bits(size); + retval = (sz >> sizebits); + } + return retval; +} + /* Kill _all_ buffers and pagecache , dirty or not.. */ void kill_bdev(struct block_device *bdev) { @@ -103,6 +116,8 @@ EXPORT_SYMBOL(invalidate_bdev); int set_blocksize(struct block_device *bdev, int size) { + struct address_space *mapping; + /* Size must be a power of two, and between 512 and PAGE_SIZE */ if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size)) return -EINVAL; @@ -111,6 +126,19 @@ int set_blocksize(struct block_device *bdev, int size) if (size < bdev_logical_block_size(bdev)) return -EINVAL; + /* Prevent starting I/O or mapping the device */ + percpu_down_write(&bdev->bd_block_size_semaphore); + + /* Check that the block device is not memory mapped */ + mapping = bdev->bd_inode->i_mapping; + mutex_lock(&mapping->i_mmap_mutex); + if (mapping_mapped(mapping)) { + mutex_unlock(&mapping->i_mmap_mutex); + percpu_up_write(&bdev->bd_block_size_semaphore); + return -EBUSY; + } + mutex_unlock(&mapping->i_mmap_mutex); + /* Don't change the size if it is same as current */ if (bdev->bd_block_size != size) { sync_blockdev(bdev); @@ -118,6 +146,9 @@ int set_blocksize(struct block_device *bdev, int size) bdev->bd_inode->i_blkbits = blksize_bits(size); kill_bdev(bdev); } + + percpu_up_write(&bdev->bd_block_size_semaphore); + return 0; } @@ -150,12 +181,52 @@ static int blkdev_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh, int create) { + if (iblock >= blkdev_max_block(I_BDEV(inode))) { + if (create) + return -EIO; + + /* + * for reads, we're just trying to fill a partial page. + * return a hole, they will have to call get_block again + * before they can fill it, and they will get -EIO at that + * time + */ + return 0; + } bh->b_bdev = I_BDEV(inode); bh->b_blocknr = iblock; set_buffer_mapped(bh); return 0; } +static int +blkdev_get_blocks(struct inode *inode, sector_t iblock, + struct buffer_head *bh, int create) +{ + sector_t end_block = blkdev_max_block(I_BDEV(inode)); + unsigned long max_blocks = bh->b_size >> inode->i_blkbits; + + if ((iblock + max_blocks) > end_block) { + max_blocks = end_block - iblock; + if ((long)max_blocks <= 0) { + if (create) + return -EIO; /* write fully beyond EOF */ + /* + * It is a read which is fully beyond EOF. We return + * a !buffer_mapped buffer + */ + max_blocks = 0; + } + } + + bh->b_bdev = I_BDEV(inode); + bh->b_blocknr = iblock; + bh->b_size = max_blocks << inode->i_blkbits; + if (max_blocks) + set_buffer_mapped(bh); + return 0; +} + static ssize_t blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t offset, unsigned long nr_segs) @@ -164,7 +235,7 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, struct inode *inode = file->f_mapping->host; return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset, - nr_segs, blkdev_get_block, NULL, NULL, 0); + nr_segs, blkdev_get_blocks, NULL, NULL, 0); } int __sync_blockdev(struct block_device *bdev, int wait) @@ -388,6 +459,12 @@ static struct inode *bdev_alloc_inode(struct super_block *sb) struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); if (!ei) return NULL; + + if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) { + kmem_cache_free(bdev_cachep, ei); + return NULL; + } + return &ei->vfs_inode; } @@ -396,6 +473,8 @@ static void bdev_i_callback(struct rcu_head *head) struct inode *inode = container_of(head, struct inode, i_rcu); struct bdev_inode *bdi = BDEV_I(inode); + percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore); + kmem_cache_free(bdev_cachep, bdi); } @@ -1514,6 +1593,22 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) return blkdev_ioctl(bdev, mode, cmd, arg); } +ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + ssize_t ret; + struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host); + + percpu_down_read(&bdev->bd_block_size_semaphore); + + ret = generic_file_aio_read(iocb, iov, nr_segs, pos); + + percpu_up_read(&bdev->bd_block_size_semaphore); + + return ret; +} +EXPORT_SYMBOL_GPL(blkdev_aio_read); + /* * Write data to the block device. Only intended for the block device itself * and the raw driver which basically is a fake block device. @@ -1525,12 +1620,16 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct file *file = iocb->ki_filp; + struct block_device *bdev = I_BDEV(file->f_mapping->host); struct blk_plug plug; ssize_t ret; BUG_ON(iocb->ki_pos != pos); blk_start_plug(&plug); + + percpu_down_read(&bdev->bd_block_size_semaphore); + ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); if (ret > 0 || ret == -EIOCBQUEUED) { ssize_t err; @@ -1539,11 +1638,62 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, if (err < 0 && ret > 0) ret = err; } + + percpu_up_read(&bdev->bd_block_size_semaphore); + blk_finish_plug(&plug); + return ret; } EXPORT_SYMBOL_GPL(blkdev_aio_write); +static int blkdev_mmap(struct file *file, struct vm_area_struct *vma) +{ + int ret; + struct block_device *bdev = I_BDEV(file->f_mapping->host); + + percpu_down_read(&bdev->bd_block_size_semaphore); + + ret = generic_file_mmap(file, vma); + + percpu_up_read(&bdev->bd_block_size_semaphore); + + return ret; +} + +static ssize_t blkdev_splice_read(struct file *file, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + ssize_t ret; + struct block_device *bdev = I_BDEV(file->f_mapping->host); + + percpu_down_read(&bdev->bd_block_size_semaphore); + + ret = generic_file_splice_read(file, ppos, pipe, len, flags); + + percpu_up_read(&bdev->bd_block_size_semaphore); + + return ret; +} + +static ssize_t blkdev_splice_write(struct pipe_inode_info *pipe, + struct file *file, loff_t *ppos, size_t len, + unsigned int flags) +{ + ssize_t ret; + struct block_device *bdev = I_BDEV(file->f_mapping->host); + + percpu_down_read(&bdev->bd_block_size_semaphore); + + ret = generic_file_splice_write(pipe, file, ppos, len, flags); + + percpu_up_read(&bdev->bd_block_size_semaphore); + + return ret; +} + + /* * Try to release a page associated with block device when the system * is under memory pressure. @@ -1574,16 +1724,16 @@ const struct file_operations def_blk_fops = { .llseek = block_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = generic_file_aio_read, + .aio_read = blkdev_aio_read, .aio_write = blkdev_aio_write, - .mmap = generic_file_mmap, + .mmap = blkdev_mmap, .fsync = blkdev_fsync, .unlocked_ioctl = block_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_blkdev_ioctl, #endif - .splice_read = generic_file_splice_read, - .splice_write = generic_file_splice_write, + .splice_read = blkdev_splice_read, + .splice_write = blkdev_splice_write, }; int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index ec0aca8ba6bf..b5f044283edb 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -911,18 +911,6 @@ link_dev_buffers(struct page *page, struct buffer_head *head) attach_page_buffers(page, head); } -static sector_t blkdev_max_block(struct block_device *bdev, unsigned int size) -{ - sector_t retval = ~((sector_t)0); - loff_t sz = i_size_read(bdev->bd_inode); - - if (sz) { - unsigned int sizebits = blksize_bits(size); - retval = (sz >> sizebits); - } - return retval; -} - /* * Initialise the state of a blockdev page's buffers. */ @@ -933,7 +921,7 @@ init_page_buffers(struct page *page, struct block_device *bdev, struct buffer_head *head = page_buffers(page); struct buffer_head *bh = head; int uptodate = PageUptodate(page); - sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode), size); + sector_t end_block = blkdev_max_block(I_BDEV(bdev->bd_inode)); do { if (!buffer_mapped(bh)) { @@ -1564,28 +1552,6 @@ void unmap_underlying_metadata(struct block_device *bdev, sector_t block) } EXPORT_SYMBOL(unmap_underlying_metadata); -/* - * Size is a power-of-two in the range 512..PAGE_SIZE, - * and the case we care about most is PAGE_SIZE. - * - * So this *could* possibly be written with those - * constraints in mind (relevant mostly if some - * architecture has a slow bit-scan instruction) - */ -static inline int block_size_bits(unsigned int blocksize) -{ - return ilog2(blocksize); -} - -static struct buffer_head *create_page_buffers(struct page *page, struct inode *inode, unsigned int b_state) -{ - BUG_ON(!PageLocked(page)); - - if (!page_has_buffers(page)) - create_empty_buffers(page, 1 << ACCESS_ONCE(inode->i_blkbits), b_state); - return page_buffers(page); -} - /* * NOTE! All mapped/uptodate combinations are valid: * @@ -1623,13 +1589,19 @@ static int __block_write_full_page(struct inode *inode, struct page *page, sector_t block; sector_t last_block; struct buffer_head *bh, *head; - unsigned int blocksize, bbits; + const unsigned blocksize = 1 << inode->i_blkbits; int nr_underway = 0; int write_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE); - head = create_page_buffers(page, inode, + BUG_ON(!PageLocked(page)); + + last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; + + if (!page_has_buffers(page)) { + create_empty_buffers(page, blocksize, (1 << BH_Dirty)|(1 << BH_Uptodate)); + } /* * Be very careful. We have no exclusion from __set_page_dirty_buffers @@ -1641,12 +1613,9 @@ static int __block_write_full_page(struct inode *inode, struct page *page, * handle that here by just cleaning them. */ + block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); + head = page_buffers(page); bh = head; - blocksize = bh->b_size; - bbits = block_size_bits(blocksize); - - block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits); - last_block = (i_size_read(inode) - 1) >> bbits; /* * Get all the dirty buffers mapped to disk addresses and @@ -1837,10 +1806,12 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len, BUG_ON(to > PAGE_CACHE_SIZE); BUG_ON(from > to); - head = create_page_buffers(page, inode, 0); - blocksize = head->b_size; - bbits = block_size_bits(blocksize); + blocksize = 1 << inode->i_blkbits; + if (!page_has_buffers(page)) + create_empty_buffers(page, blocksize, 0); + head = page_buffers(page); + bbits = inode->i_blkbits; block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits); for(bh = head, block_start = 0; bh != head || !block_start; @@ -1910,11 +1881,11 @@ static int __block_commit_write(struct inode *inode, struct page *page, unsigned blocksize; struct buffer_head *bh, *head; - bh = head = page_buffers(page); - blocksize = bh->b_size; + blocksize = 1 << inode->i_blkbits; - block_start = 0; - do { + for(bh = head = page_buffers(page), block_start = 0; + bh != head || !block_start; + block_start=block_end, bh = bh->b_this_page) { block_end = block_start + blocksize; if (block_end <= from || block_start >= to) { if (!buffer_uptodate(bh)) @@ -1924,10 +1895,7 @@ static int __block_commit_write(struct inode *inode, struct page *page, mark_buffer_dirty(bh); } clear_buffer_new(bh); - - block_start = block_end; - bh = bh->b_this_page; - } while (bh != head); + } /* * If this is a partial write which happened to make all buffers @@ -2052,6 +2020,7 @@ EXPORT_SYMBOL(generic_write_end); int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc, unsigned long from) { + struct inode *inode = page->mapping->host; unsigned block_start, block_end, blocksize; unsigned to; struct buffer_head *bh, *head; @@ -2060,13 +2029,13 @@ int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc, if (!page_has_buffers(page)) return 0; - head = page_buffers(page); - blocksize = head->b_size; + blocksize = 1 << inode->i_blkbits; to = min_t(unsigned, PAGE_CACHE_SIZE - from, desc->count); to = from + to; if (from < blocksize && to > PAGE_CACHE_SIZE - blocksize) return 0; + head = page_buffers(page); bh = head; block_start = 0; do { @@ -2099,16 +2068,18 @@ int block_read_full_page(struct page *page, get_block_t *get_block) struct inode *inode = page->mapping->host; sector_t iblock, lblock; struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE]; - unsigned int blocksize, bbits; + unsigned int blocksize; int nr, i; int fully_mapped = 1; - head = create_page_buffers(page, inode, 0); - blocksize = head->b_size; - bbits = block_size_bits(blocksize); + BUG_ON(!PageLocked(page)); + blocksize = 1 << inode->i_blkbits; + if (!page_has_buffers(page)) + create_empty_buffers(page, blocksize, 0); + head = page_buffers(page); - iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits); - lblock = (i_size_read(inode)+blocksize-1) >> bbits; + iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); + lblock = (i_size_read(inode)+blocksize-1) >> inode->i_blkbits; bh = head; nr = 0; i = 0; @@ -2893,55 +2864,6 @@ static void end_bio_bh_io_sync(struct bio *bio, int err) bio_put(bio); } -/* - * This allows us to do IO even on the odd last sectors - * of a device, even if the bh block size is some multiple - * of the physical sector size. - * - * We'll just truncate the bio to the size of the device, - * and clear the end of the buffer head manually. - * - * Truly out-of-range accesses will turn into actual IO - * errors, this only handles the "we need to be able to - * do IO at the final sector" case. - */ -static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh) -{ - sector_t maxsector; - unsigned bytes; - - maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9; - if (!maxsector) - return; - - /* - * If the *whole* IO is past the end of the device, - * let it through, and the IO layer will turn it into - * an EIO. - */ - if (unlikely(bio->bi_sector >= maxsector)) - return; - - maxsector -= bio->bi_sector; - bytes = bio->bi_size; - if (likely((bytes >> 9) <= maxsector)) - return; - - /* Uhhuh. We've got a bh that straddles the device size! */ - bytes = maxsector << 9; - - /* Truncate the bio.. */ - bio->bi_size = bytes; - bio->bi_io_vec[0].bv_len = bytes; - - /* ..and clear the end of the buffer for reads */ - if ((rw & RW_MASK) == READ) { - void *kaddr = kmap_atomic(bh->b_page); - memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes); - kunmap_atomic(kaddr); - } -} - int submit_bh(int rw, struct buffer_head * bh) { struct bio *bio; @@ -2978,9 +2900,6 @@ int submit_bh(int rw, struct buffer_head * bh) bio->bi_end_io = end_bio_bh_io_sync; bio->bi_private = bh; - /* Take care of bh's that straddle the end of the device */ - guard_bh_eod(rw, bio, bh); - bio_get(bio); submit_bio(rw, bio); diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 70b6f4c3a0c1..edb25b4bbb95 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -1794,6 +1794,7 @@ static int cifs_writepages(struct address_space *mapping, struct TCP_Server_Info *server; struct page *page; int rc = 0; + loff_t isize = i_size_read(mapping->host); /* * If wsize is smaller than the page cache size, default to writing @@ -1898,7 +1899,7 @@ static int cifs_writepages(struct address_space *mapping, */ set_page_writeback(page); - if (page_offset(page) >= i_size_read(mapping->host)) { + if (page_offset(page) >= isize) { done = true; unlock_page(page); end_page_writeback(page); @@ -1931,8 +1932,7 @@ static int cifs_writepages(struct address_space *mapping, wdata->offset = page_offset(wdata->pages[0]); wdata->pagesz = PAGE_CACHE_SIZE; wdata->tailsz = - min(i_size_read(mapping->host) - - page_offset(wdata->pages[nr_pages - 1]), + min(isize - page_offset(wdata->pages[nr_pages - 1]), (loff_t)PAGE_CACHE_SIZE); wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) + wdata->tailsz; diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index 1c576e871366..f9b5d3d6cf33 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -86,17 +86,14 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, dentry = d_lookup(parent, name); if (dentry) { - int err; inode = dentry->d_inode; /* update inode in place if i_ino didn't change */ if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { cifs_fattr_to_inode(inode, fattr); return dentry; } - err = d_invalidate(dentry); + d_drop(dentry); dput(dentry); - if (err) - return NULL; } dentry = d_alloc(parent, name); diff --git a/trunk/fs/cifs/smb1ops.c b/trunk/fs/cifs/smb1ops.c index 34cea2798333..56cc4be87807 100644 --- a/trunk/fs/cifs/smb1ops.c +++ b/trunk/fs/cifs/smb1ops.c @@ -766,6 +766,7 @@ smb_set_file_info(struct inode *inode, const char *full_path, struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct tcon_link *tlink = NULL; struct cifs_tcon *tcon; + FILE_BASIC_INFO info_buf; /* if the file is already open for write, just use that fileid */ open_file = find_writable_file(cinode, true); @@ -816,7 +817,7 @@ smb_set_file_info(struct inode *inode, const char *full_path, netpid = current->tgid; set_via_filehandle: - rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid); + rc = CIFSSMBSetFileInfo(xid, tcon, &info_buf, netfid, netpid); if (!rc) cinode->cifsAttrs = le32_to_cpu(buf->Attributes); diff --git a/trunk/fs/direct-io.c b/trunk/fs/direct-io.c index cf5b44b10c67..f86c720dba0e 100644 --- a/trunk/fs/direct-io.c +++ b/trunk/fs/direct-io.c @@ -540,7 +540,6 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio, sector_t fs_endblk; /* Into file, in filesystem-sized blocks */ unsigned long fs_count; /* Number of filesystem-sized blocks */ int create; - unsigned int i_blkbits = sdio->blkbits + sdio->blkfactor; /* * If there was a memory error and we've overwritten all the @@ -555,7 +554,7 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio, fs_count = fs_endblk - fs_startblk + 1; map_bh->b_state = 0; - map_bh->b_size = fs_count << i_blkbits; + map_bh->b_size = fs_count << dio->inode->i_blkbits; /* * For writes inside i_size on a DIO_SKIP_HOLES filesystem we @@ -1054,8 +1053,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, int seg; size_t size; unsigned long addr; - unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits); - unsigned blkbits = i_blkbits; + unsigned blkbits = inode->i_blkbits; unsigned blocksize_mask = (1 << blkbits) - 1; ssize_t retval = -EINVAL; loff_t end = offset; @@ -1151,7 +1149,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, dio->inode = inode; dio->rw = rw; sdio.blkbits = blkbits; - sdio.blkfactor = i_blkbits - blkbits; + sdio.blkfactor = inode->i_blkbits - blkbits; sdio.block_in_file = offset >> blkbits; sdio.get_block = get_block; diff --git a/trunk/fs/file.c b/trunk/fs/file.c index eff23162485f..7cb71b992603 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -994,18 +994,16 @@ int iterate_fd(struct files_struct *files, unsigned n, const void *p) { struct fdtable *fdt; + struct file *file; int res = 0; if (!files) return 0; spin_lock(&files->file_lock); - for (fdt = files_fdtable(files); n < fdt->max_fds; n++) { - struct file *file; - file = rcu_dereference_check_fdtable(files, fdt->fd[n]); - if (!file) - continue; - res = f(p, file, n); - if (res) - break; + fdt = files_fdtable(files); + while (!res && n < fdt->max_fds) { + file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); + if (file) + res = f(p, file, n); } spin_unlock(&files->file_lock); return res; diff --git a/trunk/fs/fs-writeback.c b/trunk/fs/fs-writeback.c index 3e3422f7f0a4..51ea267d444c 100644 --- a/trunk/fs/fs-writeback.c +++ b/trunk/fs/fs-writeback.c @@ -228,8 +228,6 @@ static void requeue_io(struct inode *inode, struct bdi_writeback *wb) static void inode_sync_complete(struct inode *inode) { inode->i_state &= ~I_SYNC; - /* If inode is clean an unused, put it into LRU now... */ - inode_add_lru(inode); /* Waiters must see I_SYNC cleared before being woken up */ smp_mb(); wake_up_bit(&inode->i_state, __I_SYNC); diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 64999f144153..b03c71957246 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -408,19 +408,6 @@ static void inode_lru_list_add(struct inode *inode) spin_unlock(&inode->i_sb->s_inode_lru_lock); } -/* - * Add inode to LRU if needed (inode is unused and clean). - * - * Needs inode->i_lock held. - */ -void inode_add_lru(struct inode *inode) -{ - if (!(inode->i_state & (I_DIRTY | I_SYNC | I_FREEING | I_WILL_FREE)) && - !atomic_read(&inode->i_count) && inode->i_sb->s_flags & MS_ACTIVE) - inode_lru_list_add(inode); -} - - static void inode_lru_list_del(struct inode *inode) { spin_lock(&inode->i_sb->s_inode_lru_lock); @@ -1403,7 +1390,8 @@ static void iput_final(struct inode *inode) if (!drop && (sb->s_flags & MS_ACTIVE)) { inode->i_state |= I_REFERENCED; - inode_add_lru(inode); + if (!(inode->i_state & (I_DIRTY|I_SYNC))) + inode_lru_list_add(inode); spin_unlock(&inode->i_lock); return; } diff --git a/trunk/fs/internal.h b/trunk/fs/internal.h index 2f6af7f645eb..916b7cbf3e3e 100644 --- a/trunk/fs/internal.h +++ b/trunk/fs/internal.h @@ -110,7 +110,6 @@ extern int open_check_o_direct(struct file *f); * inode.c */ extern spinlock_t inode_sb_list_lock; -extern void inode_add_lru(struct inode *inode); /* * fs-writeback.c diff --git a/trunk/fs/jbd/transaction.c b/trunk/fs/jbd/transaction.c index 7f5120bf0ec2..78b7f84241d4 100644 --- a/trunk/fs/jbd/transaction.c +++ b/trunk/fs/jbd/transaction.c @@ -1961,9 +1961,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); spin_unlock(&journal->j_state_lock); - unlock_buffer(bh); log_wait_commit(journal, tid); - lock_buffer(bh); goto retry; } /* diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 5f4cdf3ad913..937f9d50c84b 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -2131,11 +2131,6 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) if (!len) return ERR_PTR(-EACCES); - if (unlikely(name[0] == '.')) { - if (len < 2 || (len == 2 && name[1] == '.')) - return ERR_PTR(-EACCES); - } - while (len--) { c = *(const unsigned char *)name++; if (c == '/' || c == '\0') diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index b9e66b7e0c14..ce8cb926526b 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -450,8 +450,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) nfs_refresh_inode(dentry->d_inode, entry->fattr); goto out; } else { - if (d_invalidate(dentry) != 0) - goto out; + d_drop(dentry); dput(dentry); } } @@ -1101,8 +1100,6 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) out_zap_parent: nfs_zap_caches(dir); out_bad: - nfs_free_fattr(fattr); - nfs_free_fhandle(fhandle); nfs_mark_for_revalidate(dir); if (inode && S_ISDIR(inode->i_mode)) { /* Purge readdir caches. */ @@ -1115,6 +1112,8 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) shrink_dcache_parent(dentry); } d_drop(dentry); + nfs_free_fattr(fattr); + nfs_free_fhandle(fhandle); dput(parent); dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", __func__, dentry->d_parent->d_name.name, diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 9e28356a959a..3c231adf8450 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -1877,9 +1877,8 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, if (!vma) goto out_no_vma; - if (vma->vm_file) - result = proc_map_files_instantiate(dir, dentry, task, - (void *)(unsigned long)vma->vm_file->f_mode); + result = proc_map_files_instantiate(dir, dentry, task, + (void *)(unsigned long)vma->vm_file->f_mode); out_no_vma: up_read(&mm->mmap_sem); diff --git a/trunk/include/linux/bug.h b/trunk/include/linux/bug.h index b1cf40de847e..aaac4bba6f5c 100644 --- a/trunk/include/linux/bug.h +++ b/trunk/include/linux/bug.h @@ -15,7 +15,6 @@ struct pt_regs; #define BUILD_BUG_ON_NOT_POWER_OF_2(n) #define BUILD_BUG_ON_ZERO(e) (0) #define BUILD_BUG_ON_NULL(e) ((void*)0) -#define BUILD_BUG_ON_INVALID(e) (0) #define BUILD_BUG_ON(condition) #define BUILD_BUG() (0) #else /* __CHECKER__ */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 75fe9a134803..b33cfc97b9ca 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -462,6 +462,8 @@ struct block_device { int bd_fsfreeze_count; /* Mutex for freeze */ struct mutex bd_fsfreeze_mutex; + /* A semaphore that prevents I/O while block size is being changed */ + struct percpu_rw_semaphore bd_block_size_semaphore; }; /* @@ -2047,6 +2049,7 @@ extern void unregister_blkdev(unsigned int, const char *); extern struct block_device *bdget(dev_t); extern struct block_device *bdgrab(struct block_device *bdev); extern void bd_set_size(struct block_device *, loff_t size); +extern sector_t blkdev_max_block(struct block_device *bdev); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); extern void invalidate_bdev(struct block_device *); @@ -2376,6 +2379,8 @@ extern int generic_segment_checks(const struct iovec *iov, unsigned long *nr_segs, size_t *count, int access_flags); /* fs/block_dev.c */ +extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos); extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end, diff --git a/trunk/include/linux/gfp.h b/trunk/include/linux/gfp.h index 76e1aa206f57..02c1c9710be0 100644 --- a/trunk/include/linux/gfp.h +++ b/trunk/include/linux/gfp.h @@ -30,9 +30,9 @@ struct vm_area_struct; #define ___GFP_HARDWALL 0x20000u #define ___GFP_THISNODE 0x40000u #define ___GFP_RECLAIMABLE 0x80000u -#define ___GFP_NOTRACK 0x100000u -#define ___GFP_OTHER_NODE 0x200000u -#define ___GFP_WRITE 0x400000u +#define ___GFP_NOTRACK 0x200000u +#define ___GFP_OTHER_NODE 0x800000u +#define ___GFP_WRITE 0x1000000u /* * GFP bitmasks.. @@ -94,7 +94,7 @@ struct vm_area_struct; */ #define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK) -#define __GFP_BITS_SHIFT 23 /* Room for N __GFP_FOO bits */ +#define __GFP_BITS_SHIFT 25 /* Room for N __GFP_FOO bits */ #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* This equals 0, but use constants in case they ever change */ diff --git a/trunk/include/linux/hw_breakpoint.h b/trunk/include/linux/hw_breakpoint.h index 0464c85e63fd..6ae9c631a1be 100644 --- a/trunk/include/linux/hw_breakpoint.h +++ b/trunk/include/linux/hw_breakpoint.h @@ -1,8 +1,35 @@ #ifndef _LINUX_HW_BREAKPOINT_H #define _LINUX_HW_BREAKPOINT_H +enum { + HW_BREAKPOINT_LEN_1 = 1, + HW_BREAKPOINT_LEN_2 = 2, + HW_BREAKPOINT_LEN_4 = 4, + HW_BREAKPOINT_LEN_8 = 8, +}; + +enum { + HW_BREAKPOINT_EMPTY = 0, + HW_BREAKPOINT_R = 1, + HW_BREAKPOINT_W = 2, + HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W, + HW_BREAKPOINT_X = 4, + HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, +}; + +enum bp_type_idx { + TYPE_INST = 0, +#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS + TYPE_DATA = 0, +#else + TYPE_DATA = 1, +#endif + TYPE_MAX +}; + +#ifdef __KERNEL__ + #include -#include #ifdef CONFIG_HAVE_HW_BREAKPOINT @@ -124,4 +151,6 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) } #endif /* CONFIG_HAVE_HW_BREAKPOINT */ +#endif /* __KERNEL__ */ + #endif /* _LINUX_HW_BREAKPOINT_H */ diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index 7d8dfc7392f1..a123b13b70fd 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -701,13 +701,6 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } #define COMPACTION_BUILD 0 #endif -/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */ -#ifdef CONFIG_SYMBOL_PREFIX -#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX -#else -#define SYMBOL_PREFIX "" -#endif - /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ #ifdef CONFIG_FTRACE_MCOUNT_RECORD # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD diff --git a/trunk/include/linux/percpu-rwsem.h b/trunk/include/linux/percpu-rwsem.h index bd1e86071e57..250a4acddb2b 100644 --- a/trunk/include/linux/percpu-rwsem.h +++ b/trunk/include/linux/percpu-rwsem.h @@ -13,7 +13,7 @@ struct percpu_rw_semaphore { }; #define light_mb() barrier() -#define heavy_mb() synchronize_sched_expedited() +#define heavy_mb() synchronize_sched() static inline void percpu_down_read(struct percpu_rw_semaphore *p) { @@ -51,7 +51,7 @@ static inline void percpu_down_write(struct percpu_rw_semaphore *p) { mutex_lock(&p->mtx); p->locked = true; - synchronize_sched_expedited(); /* make sure that all readers exit the rcu_read_lock_sched region */ + synchronize_sched(); /* make sure that all readers exit the rcu_read_lock_sched region */ while (__percpu_count(p->counters)) msleep(1); heavy_mb(); /* C, between read of p->counter and write to data, paired with B */ diff --git a/trunk/include/media/adv7604.h b/trunk/include/media/adv7604.h index dc004bc926c9..171b957db743 100644 --- a/trunk/include/media/adv7604.h +++ b/trunk/include/media/adv7604.h @@ -40,6 +40,14 @@ enum adv7604_op_ch_sel { ADV7604_OP_CH_SEL_RBG = 5, }; +/* Primary mode (IO register 0x01, [3:0]) */ +enum adv7604_prim_mode { + ADV7604_PRIM_MODE_COMP = 1, + ADV7604_PRIM_MODE_RGB = 2, + ADV7604_PRIM_MODE_HDMI_COMP = 5, + ADV7604_PRIM_MODE_HDMI_GR = 6, +}; + /* Input Color Space (IO register 0x02, [7:4]) */ enum adv7604_inp_color_space { ADV7604_INP_COLOR_SPACE_LIM_RGB = 0, @@ -95,6 +103,9 @@ struct adv7604_platform_data { /* Bus rotation and reordering */ enum adv7604_op_ch_sel op_ch_sel; + /* Primary mode */ + enum adv7604_prim_mode prim_mode; + /* Select output format */ enum adv7604_op_format_sel op_format_sel; @@ -131,16 +142,6 @@ struct adv7604_platform_data { u8 i2c_vdp; }; -/* - * Mode of operation. - * This is used as the input argument of the s_routing video op. - */ -enum adv7604_mode { - ADV7604_MODE_COMP, - ADV7604_MODE_GR, - ADV7604_MODE_HDMI, -}; - #define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000) #define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001) #define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002) diff --git a/trunk/include/uapi/linux/Kbuild b/trunk/include/uapi/linux/Kbuild index 19e765fbfef7..e194387ef784 100644 --- a/trunk/include/uapi/linux/Kbuild +++ b/trunk/include/uapi/linux/Kbuild @@ -415,4 +415,3 @@ header-y += wireless.h header-y += x25.h header-y += xattr.h header-y += xfrm.h -header-y += hw_breakpoint.h diff --git a/trunk/include/uapi/linux/hw_breakpoint.h b/trunk/include/uapi/linux/hw_breakpoint.h deleted file mode 100644 index b04000a2296a..000000000000 --- a/trunk/include/uapi/linux/hw_breakpoint.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _UAPI_LINUX_HW_BREAKPOINT_H -#define _UAPI_LINUX_HW_BREAKPOINT_H - -enum { - HW_BREAKPOINT_LEN_1 = 1, - HW_BREAKPOINT_LEN_2 = 2, - HW_BREAKPOINT_LEN_4 = 4, - HW_BREAKPOINT_LEN_8 = 8, -}; - -enum { - HW_BREAKPOINT_EMPTY = 0, - HW_BREAKPOINT_R = 1, - HW_BREAKPOINT_W = 2, - HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W, - HW_BREAKPOINT_X = 4, - HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, -}; - -enum bp_type_idx { - TYPE_INST = 0, -#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS - TYPE_DATA = 0, -#else - TYPE_DATA = 1, -#endif - TYPE_MAX -}; - -#endif /* _UAPI_LINUX_HW_BREAKPOINT_H */ diff --git a/trunk/kernel/events/hw_breakpoint.c b/trunk/kernel/events/hw_breakpoint.c index fe8a916507ed..9a7b487c6fe2 100644 --- a/trunk/kernel/events/hw_breakpoint.c +++ b/trunk/kernel/events/hw_breakpoint.c @@ -111,16 +111,14 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type) * Count the number of breakpoints of the same type and same task. * The given event must be not on the list. */ -static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type) +static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type) { struct task_struct *tsk = bp->hw.bp_target; struct perf_event *iter; int count = 0; list_for_each_entry(iter, &bp_task_head, hw.bp_list) { - if (iter->hw.bp_target == tsk && - find_slot_idx(iter) == type && - cpu == iter->cpu) + if (iter->hw.bp_target == tsk && find_slot_idx(iter) == type) count += hw_breakpoint_weight(iter); } @@ -143,7 +141,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, if (!tsk) slots->pinned += max_task_bp_pinned(cpu, type); else - slots->pinned += task_bp_pinned(cpu, bp, type); + slots->pinned += task_bp_pinned(bp, type); slots->flexible = per_cpu(nr_bp_flexible[type], cpu); return; @@ -156,7 +154,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, if (!tsk) nr += max_task_bp_pinned(cpu, type); else - nr += task_bp_pinned(cpu, bp, type); + nr += task_bp_pinned(bp, type); if (nr > slots->pinned) slots->pinned = nr; @@ -190,7 +188,7 @@ static void toggle_bp_task_slot(struct perf_event *bp, int cpu, bool enable, int old_idx = 0; int idx = 0; - old_count = task_bp_pinned(cpu, bp, type); + old_count = task_bp_pinned(bp, type); old_idx = old_count - 1; idx = old_idx + weight; diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 19eb089ca003..20ef219bbe9b 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -843,9 +843,6 @@ static void wake_futex(struct futex_q *q) { struct task_struct *p = q->task; - if (WARN(q->pi_state || q->rt_waiter, "refusing to wake PI futex\n")) - return; - /* * We set q->lock_ptr = NULL _before_ we wake up the task. If * a non-futex wake up happens on another CPU then the task @@ -1081,10 +1078,6 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, plist_for_each_entry_safe(this, next, head, list) { if (match_futex (&this->key, &key1)) { - if (this->pi_state || this->rt_waiter) { - ret = -EINVAL; - goto out_unlock; - } wake_futex(this); if (++ret >= nr_wake) break; @@ -1097,10 +1090,6 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, op_ret = 0; plist_for_each_entry_safe(this, next, head, list) { if (match_futex (&this->key, &key2)) { - if (this->pi_state || this->rt_waiter) { - ret = -EINVAL; - goto out_unlock; - } wake_futex(this); if (++op_ret >= nr_wake2) break; @@ -1109,7 +1098,6 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, ret += op_ret; } -out_unlock: double_unlock_hb(hb1, hb2); out_put_keys: put_futex_key(&key2); @@ -1399,13 +1387,9 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, /* * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always * be paired with each other and no other futex ops. - * - * We should never be requeueing a futex_q with a pi_state, - * which is awaiting a futex_unlock_pi(). */ if ((requeue_pi && !this->rt_waiter) || - (!requeue_pi && this->rt_waiter) || - this->pi_state) { + (!requeue_pi && this->rt_waiter)) { ret = -EINVAL; break; } diff --git a/trunk/kernel/modsign_pubkey.c b/trunk/kernel/modsign_pubkey.c index 767e559dfb10..4646eb2c3820 100644 --- a/trunk/kernel/modsign_pubkey.c +++ b/trunk/kernel/modsign_pubkey.c @@ -21,10 +21,10 @@ struct key *modsign_keyring; extern __initdata const u8 modsign_certificate_list[]; extern __initdata const u8 modsign_certificate_list_end[]; asm(".section .init.data,\"aw\"\n" - SYMBOL_PREFIX "modsign_certificate_list:\n" + "modsign_certificate_list:\n" ".incbin \"signing_key.x509\"\n" ".incbin \"extra_certificates\"\n" - SYMBOL_PREFIX "modsign_certificate_list_end:" + "modsign_certificate_list_end:" ); /* diff --git a/trunk/kernel/module_signing.c b/trunk/kernel/module_signing.c index f2970bddc5ea..ea1b1df5dbb0 100644 --- a/trunk/kernel/module_signing.c +++ b/trunk/kernel/module_signing.c @@ -27,13 +27,13 @@ * - Information block */ struct module_signature { - u8 algo; /* Public-key crypto algorithm [enum pkey_algo] */ - u8 hash; /* Digest algorithm [enum pkey_hash_algo] */ - u8 id_type; /* Key identifier type [enum pkey_id_type] */ - u8 signer_len; /* Length of signer's name */ - u8 key_id_len; /* Length of key identifier */ - u8 __pad[3]; - __be32 sig_len; /* Length of signature data */ + enum pkey_algo algo : 8; /* Public-key crypto algorithm */ + enum pkey_hash_algo hash : 8; /* Digest algorithm */ + enum pkey_id_type id_type : 8; /* Key identifier type */ + u8 signer_len; /* Length of signer's name */ + u8 key_id_len; /* Length of key identifier */ + u8 __pad[3]; + __be32 sig_len; /* Length of signature data */ }; /* diff --git a/trunk/kernel/sched/auto_group.c b/trunk/kernel/sched/auto_group.c index 15f60d01198b..0984a21076a3 100644 --- a/trunk/kernel/sched/auto_group.c +++ b/trunk/kernel/sched/auto_group.c @@ -143,11 +143,15 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag) p->signal->autogroup = autogroup_kref_get(ag); + if (!ACCESS_ONCE(sysctl_sched_autogroup_enabled)) + goto out; + t = p; do { sched_move_task(t); } while_each_thread(p, t); +out: unlock_task_sighand(p, &flags); autogroup_kref_put(prev); } diff --git a/trunk/kernel/sched/auto_group.h b/trunk/kernel/sched/auto_group.h index 443232ebbb53..8bd047142816 100644 --- a/trunk/kernel/sched/auto_group.h +++ b/trunk/kernel/sched/auto_group.h @@ -4,6 +4,11 @@ #include struct autogroup { + /* + * reference doesn't mean how many thread attach to this + * autogroup now. It just stands for the number of task + * could use this autogroup. + */ struct kref kref; struct task_group *tg; struct rw_semaphore lock; diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index c8c21be11ab4..9d4c8d5a1f53 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -116,7 +116,7 @@ static unsigned long get_timestamp(int this_cpu) return cpu_clock(this_cpu) >> 30LL; /* 2^30 ~= 10^9 */ } -static u64 get_sample_period(void) +static unsigned long get_sample_period(void) { /* * convert watchdog_thresh from seconds to ns @@ -125,7 +125,7 @@ static u64 get_sample_period(void) * and hard thresholds) to increment before the * hardlockup detector generates a warning */ - return get_softlockup_thresh() * ((u64)NSEC_PER_SEC / 5); + return get_softlockup_thresh() * (NSEC_PER_SEC / 5); } /* Commands for resetting the watchdog */ @@ -368,9 +368,6 @@ static void watchdog_disable(unsigned int cpu) { struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); - if (!watchdog_enabled) - return; - watchdog_set_prio(SCHED_NORMAL, 0); hrtimer_cancel(hrtimer); /* disable the perf event */ diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 1dae900df798..042d221d33cc 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -1361,19 +1361,8 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq, WARN_ON_ONCE(timer->function != delayed_work_timer_fn || timer->data != (unsigned long)dwork); - WARN_ON_ONCE(timer_pending(timer)); - WARN_ON_ONCE(!list_empty(&work->entry)); - - /* - * If @delay is 0, queue @dwork->work immediately. This is for - * both optimization and correctness. The earliest @timer can - * expire is on the closest next tick and delayed_work users depend - * on that there's no such delay when @delay is 0. - */ - if (!delay) { - __queue_work(cpu, wq, &dwork->work); - return; - } + BUG_ON(timer_pending(timer)); + BUG_ON(!list_empty(&work->entry)); timer_stats_timer_set_start_info(&dwork->timer); @@ -1428,6 +1417,9 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, bool ret = false; unsigned long flags; + if (!delay) + return queue_work_on(cpu, wq, &dwork->work); + /* read the comment in __queue_work() */ local_irq_save(flags); @@ -2415,10 +2407,8 @@ static int rescuer_thread(void *__wq) repeat: set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) { - __set_current_state(TASK_RUNNING); + if (kthread_should_stop()) return 0; - } /* * See whether any cpu is asking for help. Unbounded diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index a08b791200f3..821a16229111 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -163,7 +163,7 @@ $(obj)/crc32table.h: $(obj)/gen_crc32table # obj-$(CONFIG_OID_REGISTRY) += oid_registry.o -$(obj)/oid_registry.o: $(obj)/oid_registry_data.c +$(obj)/oid_registry.c: $(obj)/oid_registry_data.c $(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \ $(src)/build_OID_registry diff --git a/trunk/lib/asn1_decoder.c b/trunk/lib/asn1_decoder.c index 5293d2433029..de2c8b5a715b 100644 --- a/trunk/lib/asn1_decoder.c +++ b/trunk/lib/asn1_decoder.c @@ -91,7 +91,7 @@ static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen /* Extract the length */ len = data[dp++]; - if (len <= 0x7f) { + if (len < 0x7f) { dp += len; goto next_tag; } diff --git a/trunk/mm/memory-failure.c b/trunk/mm/memory-failure.c index 8b20278be6a6..6c5899b9034a 100644 --- a/trunk/mm/memory-failure.c +++ b/trunk/mm/memory-failure.c @@ -1476,17 +1476,9 @@ int soft_offline_page(struct page *page, int flags) { int ret; unsigned long pfn = page_to_pfn(page); - struct page *hpage = compound_trans_head(page); if (PageHuge(page)) return soft_offline_huge_page(page, flags); - if (PageTransHuge(hpage)) { - if (PageAnon(hpage) && unlikely(split_huge_page(hpage))) { - pr_info("soft offline: %#lx: failed to split THP\n", - pfn); - return -EBUSY; - } - } ret = get_any_page(page, pfn, flags); if (ret < 0) diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index a8f2c87792c3..bcb72c6e2b2d 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -1422,7 +1422,7 @@ int capture_free_page(struct page *page, int alloc_order, int migratetype) } } - return 1UL << alloc_order; + return 1UL << order; } /* @@ -2378,15 +2378,6 @@ bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) return !!(gfp_to_alloc_flags(gfp_mask) & ALLOC_NO_WATERMARKS); } -/* Returns true if the allocation is likely for THP */ -static bool is_thp_alloc(gfp_t gfp_mask, unsigned int order) -{ - if (order == pageblock_order && - (gfp_mask & (__GFP_MOVABLE|__GFP_REPEAT)) == __GFP_MOVABLE) - return true; - return false; -} - static inline struct page * __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, enum zone_type high_zoneidx, @@ -2425,9 +2416,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, goto nopage; restart: - /* The decision whether to wake kswapd for THP is made later */ - if (!is_thp_alloc(gfp_mask, order)) - wake_all_kswapd(order, zonelist, high_zoneidx, + wake_all_kswapd(order, zonelist, high_zoneidx, zone_idx(preferred_zone)); /* @@ -2498,21 +2487,15 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, goto got_pg; sync_migration = true; - if (is_thp_alloc(gfp_mask, order)) { - /* - * If compaction is deferred for high-order allocations, it is - * because sync compaction recently failed. If this is the case - * and the caller requested a movable allocation that does not - * heavily disrupt the system then fail the allocation instead - * of entering direct reclaim. - */ - if (deferred_compaction || contended_compaction) - goto nopage; - - /* If process is willing to reclaim/compact then wake kswapd */ - wake_all_kswapd(order, zonelist, high_zoneidx, - zone_idx(preferred_zone)); - } + /* + * If compaction is deferred for high-order allocations, it is because + * sync compaction recently failed. In this is the case and the caller + * requested a movable allocation that does not heavily disrupt the + * system then fail the allocation instead of entering direct reclaim. + */ + if ((deferred_compaction || contended_compaction) && + (gfp_mask & (__GFP_MOVABLE|__GFP_REPEAT)) == __GFP_MOVABLE) + goto nopage; /* Try direct reclaim and then allocating */ page = __alloc_pages_direct_reclaim(gfp_mask, order, diff --git a/trunk/mm/sparse.c b/trunk/mm/sparse.c index a83de2f72b30..fac95f2888f2 100644 --- a/trunk/mm/sparse.c +++ b/trunk/mm/sparse.c @@ -617,7 +617,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages) { return; /* XXX: Not implemented yet */ } -static void free_map_bootmem(struct page *memmap, unsigned long nr_pages) +static void free_map_bootmem(struct page *page, unsigned long nr_pages) { } #else @@ -658,11 +658,10 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages) get_order(sizeof(struct page) * nr_pages)); } -static void free_map_bootmem(struct page *memmap, unsigned long nr_pages) +static void free_map_bootmem(struct page *page, unsigned long nr_pages) { unsigned long maps_section_nr, removing_section_nr, i; unsigned long magic; - struct page *page = virt_to_page(memmap); for (i = 0; i < nr_pages; i++, page++) { magic = (unsigned long) page->lru.next; @@ -711,10 +710,13 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap) */ if (memmap) { + struct page *memmap_page; + memmap_page = virt_to_page(memmap); + nr_pages = PAGE_ALIGN(PAGES_PER_SECTION * sizeof(struct page)) >> PAGE_SHIFT; - free_map_bootmem(memmap, nr_pages); + free_map_bootmem(memmap_page, nr_pages); } } diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 83f4d0e85601..48550c66f1f2 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -2207,12 +2207,9 @@ static bool pfmemalloc_watermark_ok(pg_data_t *pgdat) * Throttle direct reclaimers if backing storage is backed by the network * and the PFMEMALLOC reserve for the preferred node is getting dangerously * depleted. kswapd will continue to make progress and wake the processes - * when the low watermark is reached. - * - * Returns true if a fatal signal was delivered during throttling. If this - * happens, the page allocator should not consider triggering the OOM killer. + * when the low watermark is reached */ -static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, +static void throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, nodemask_t *nodemask) { struct zone *zone; @@ -2227,20 +2224,13 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, * processes to block on log_wait_commit(). */ if (current->flags & PF_KTHREAD) - goto out; - - /* - * If a fatal signal is pending, this process should not throttle. - * It should return quickly so it can exit and free its memory - */ - if (fatal_signal_pending(current)) - goto out; + return; /* Check if the pfmemalloc reserves are ok */ first_zones_zonelist(zonelist, high_zoneidx, NULL, &zone); pgdat = zone->zone_pgdat; if (pfmemalloc_watermark_ok(pgdat)) - goto out; + return; /* Account for the throttling */ count_vm_event(PGSCAN_DIRECT_THROTTLE); @@ -2256,20 +2246,12 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, if (!(gfp_mask & __GFP_FS)) { wait_event_interruptible_timeout(pgdat->pfmemalloc_wait, pfmemalloc_watermark_ok(pgdat), HZ); - - goto check_pending; + return; } /* Throttle until kswapd wakes the process */ wait_event_killable(zone->zone_pgdat->pfmemalloc_wait, pfmemalloc_watermark_ok(pgdat)); - -check_pending: - if (fatal_signal_pending(current)) - return true; - -out: - return false; } unsigned long try_to_free_pages(struct zonelist *zonelist, int order, @@ -2291,12 +2273,13 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, .gfp_mask = sc.gfp_mask, }; + throttle_direct_reclaim(gfp_mask, zonelist, nodemask); + /* - * Do not enter reclaim if fatal signal was delivered while throttled. - * 1 is returned so that the page allocator does not OOM kill at this - * point. + * Do not enter reclaim if fatal signal is pending. 1 is returned so + * that the page allocator does not consider triggering OOM */ - if (throttle_direct_reclaim(gfp_mask, zonelist, nodemask)) + if (fatal_signal_pending(current)) return 1; trace_mm_vmscan_direct_reclaim_begin(order, @@ -2414,19 +2397,6 @@ static void age_active_anon(struct zone *zone, struct scan_control *sc) } while (memcg); } -static bool zone_balanced(struct zone *zone, int order, - unsigned long balance_gap, int classzone_idx) -{ - if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone) + - balance_gap, classzone_idx, 0)) - return false; - - if (COMPACTION_BUILD && order && !compaction_suitable(zone, order)) - return false; - - return true; -} - /* * pgdat_balanced is used when checking if a node is balanced for high-order * allocations. Only zones that meet watermarks and are in a zone allowed @@ -2505,7 +2475,8 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining, continue; } - if (!zone_balanced(zone, order, 0, i)) + if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone), + i, 0)) all_zones_ok = false; else balanced += zone->present_pages; @@ -2614,7 +2585,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, break; } - if (!zone_balanced(zone, order, 0, 0)) { + if (!zone_watermark_ok_safe(zone, order, + high_wmark_pages(zone), 0, 0)) { end_zone = i; break; } else { @@ -2690,8 +2662,9 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, testorder = 0; if ((buffer_heads_over_limit && is_highmem_idx(i)) || - !zone_balanced(zone, testorder, - balance_gap, end_zone)) { + !zone_watermark_ok_safe(zone, testorder, + high_wmark_pages(zone) + balance_gap, + end_zone, 0)) { shrink_zone(zone, &sc); reclaim_state->reclaimed_slab = 0; @@ -2718,7 +2691,8 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, continue; } - if (!zone_balanced(zone, testorder, 0, end_zone)) { + if (!zone_watermark_ok_safe(zone, testorder, + high_wmark_pages(zone), end_zone, 0)) { all_zones_ok = 0; /* * We are still under min water mark. This diff --git a/trunk/net/can/bcm.c b/trunk/net/can/bcm.c index 969b7cdff59d..6f747582718e 100644 --- a/trunk/net/can/bcm.c +++ b/trunk/net/can/bcm.c @@ -1084,9 +1084,6 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, op->sk = sk; op->ifindex = ifindex; - /* ifindex for timeout events w/o previous frame reception */ - op->rx_ifindex = ifindex; - /* initialize uninitialized (kzalloc) structure */ hrtimer_init(&op->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); op->timer.function = bcm_rx_timeout_handler; diff --git a/trunk/net/ipv4/icmp.c b/trunk/net/ipv4/icmp.c index 17ff9fd7cdda..f2eccd531746 100644 --- a/trunk/net/ipv4/icmp.c +++ b/trunk/net/ipv4/icmp.c @@ -257,8 +257,7 @@ static inline bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, struct inet_peer *peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, 1); rc = inet_peer_xrlim_allow(peer, net->ipv4.sysctl_icmp_ratelimit); - if (peer) - inet_putpeer(peer); + inet_putpeer(peer); } out: return rc; diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c index 3eab2b2ffd34..6168c4dc58b1 100644 --- a/trunk/net/ipv4/ipmr.c +++ b/trunk/net/ipv4/ipmr.c @@ -1318,10 +1318,6 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi if (get_user(v, (u32 __user *)optval)) return -EFAULT; - /* "pimreg%u" should not exceed 16 bytes (IFNAMSIZ) */ - if (v != RT_TABLE_DEFAULT && v >= 1000000000) - return -EINVAL; - rtnl_lock(); ret = 0; if (sk == rtnl_dereference(mrt->mroute_sk)) { diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index e457c7ab2e28..083092e3aed6 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -830,8 +830,8 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags) return mss_now; } -static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, - size_t size, int flags) +static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, + size_t psize, int flags) { struct tcp_sock *tp = tcp_sk(sk); int mss_now, size_goal; @@ -858,9 +858,12 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) goto out_err; - while (size > 0) { + while (psize > 0) { struct sk_buff *skb = tcp_write_queue_tail(sk); + struct page *page = pages[poffset / PAGE_SIZE]; int copy, i; + int offset = poffset % PAGE_SIZE; + int size = min_t(size_t, psize, PAGE_SIZE - offset); bool can_coalesce; if (!tcp_send_head(sk) || (copy = size_goal - skb->len) <= 0) { @@ -909,8 +912,8 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; copied += copy; - offset += copy; - if (!(size -= copy)) + poffset += copy; + if (!(psize -= copy)) goto out; if (skb->len < size_goal || (flags & MSG_OOB)) @@ -957,7 +960,7 @@ int tcp_sendpage(struct sock *sk, struct page *page, int offset, flags); lock_sock(sk); - res = do_tcp_sendpages(sk, page, offset, size, flags); + res = do_tcp_sendpages(sk, &page, offset, size, flags); release_sock(sk); return res; } diff --git a/trunk/net/irda/irttp.c b/trunk/net/irda/irttp.c index ae43c62f9045..1002e3396f72 100644 --- a/trunk/net/irda/irttp.c +++ b/trunk/net/irda/irttp.c @@ -441,7 +441,6 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) lsap = irlmp_open_lsap(stsap_sel, &ttp_notify, 0); if (lsap == NULL) { IRDA_DEBUG(0, "%s: unable to allocate LSAP!!\n", __func__); - __irttp_close_tsap(self); return NULL; } diff --git a/trunk/net/mac80211/offchannel.c b/trunk/net/mac80211/offchannel.c index 2c84185dfdb0..83608ac16780 100644 --- a/trunk/net/mac80211/offchannel.c +++ b/trunk/net/mac80211/offchannel.c @@ -458,6 +458,8 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) list_move_tail(&roc->list, &tmp_list); roc->abort = true; } + + ieee80211_start_next_roc(local); mutex_unlock(&local->mtx); list_for_each_entry_safe(roc, tmp, &tmp_list, list) { diff --git a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c index 45a101439bc5..b9a63381e349 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c @@ -793,7 +793,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = { [IPSET_ATTR_IP] = { .type = NLA_NESTED }, [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, [IPSET_ATTR_IFACE] = { .type = NLA_NUL_STRING, - .len = IFNAMSIZ - 1 }, + .len = IPSET_MAXNAMELEN - 1 }, [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, diff --git a/trunk/net/openvswitch/flow.c b/trunk/net/openvswitch/flow.c index 733cbf49ed1f..98c70630ad06 100644 --- a/trunk/net/openvswitch/flow.c +++ b/trunk/net/openvswitch/flow.c @@ -702,11 +702,15 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, /* We only match on the lower 8 bits of the opcode. */ if (ntohs(arp->ar_op) <= 0xff) key->ip.proto = ntohs(arp->ar_op); - memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); - memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); - memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); - memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); - key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); + + if (key->ip.proto == ARPOP_REQUEST + || key->ip.proto == ARPOP_REPLY) { + memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); + memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); + memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); + memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); + key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); + } } } else if (key->eth.type == htons(ETH_P_IPV6)) { int nh_len; /* IPv6 Header + Extensions */ diff --git a/trunk/net/openvswitch/vport-netdev.c b/trunk/net/openvswitch/vport-netdev.c index a9033481fa5e..3c1e58ba714b 100644 --- a/trunk/net/openvswitch/vport-netdev.c +++ b/trunk/net/openvswitch/vport-netdev.c @@ -158,7 +158,7 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", - netdev_vport->dev->name, + ovs_dp_name(vport->dp), packet_length(skb), mtu); goto error; } diff --git a/trunk/net/sctp/chunk.c b/trunk/net/sctp/chunk.c index 69ce21e3716f..7c2df9c33df3 100644 --- a/trunk/net/sctp/chunk.c +++ b/trunk/net/sctp/chunk.c @@ -183,7 +183,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, msg = sctp_datamsg_new(GFP_KERNEL); if (!msg) - return ERR_PTR(-ENOMEM); + return NULL; /* Note: Calculate this outside of the loop, so that all fragments * have the same expiration. @@ -280,14 +280,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0); - if (!chunk) { - err = -ENOMEM; + if (!chunk) goto errout; - } - err = sctp_user_addto_chunk(chunk, offset, len, msgh->msg_iov); if (err < 0) - goto errout_chunk_free; + goto errout; offset += len; @@ -318,10 +315,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0); - if (!chunk) { - err = -ENOMEM; + if (!chunk) goto errout; - } err = sctp_user_addto_chunk(chunk, offset, over,msgh->msg_iov); @@ -329,7 +324,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, __skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr - (__u8 *)chunk->skb->data); if (err < 0) - goto errout_chunk_free; + goto errout; sctp_datamsg_assign(msg, chunk); list_add_tail(&chunk->frag_list, &msg->chunks); @@ -337,9 +332,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, return msg; -errout_chunk_free: - sctp_chunk_free(chunk); - errout: list_for_each_safe(pos, temp, &msg->chunks) { list_del_init(pos); @@ -347,7 +339,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, sctp_chunk_free(chunk); } sctp_datamsg_put(msg); - return ERR_PTR(err); + return NULL; } /* Check whether this message has expired. */ diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 406d957d08fb..a60d1f8b41c5 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -1915,8 +1915,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, /* Break the message into multiple chunks of maximum size. */ datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len); - if (IS_ERR(datamsg)) { - err = PTR_ERR(datamsg); + if (!datamsg) { + err = -ENOMEM; goto out_free; } diff --git a/trunk/net/sctp/transport.c b/trunk/net/sctp/transport.c index 206cf5238fd3..953c21e4af97 100644 --- a/trunk/net/sctp/transport.c +++ b/trunk/net/sctp/transport.c @@ -331,7 +331,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) * 1/8, rto_alpha would be expressed as 3. */ tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) - + (((__u32)abs64((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta); + + ((abs(tp->srtt - rtt)) >> net->sctp.rto_beta); tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) + (rtt >> net->sctp.rto_alpha); } else { diff --git a/trunk/scripts/headers_install.pl b/trunk/scripts/headers_install.pl index 6c353ae8a451..239d22d4207b 100644 --- a/trunk/scripts/headers_install.pl +++ b/trunk/scripts/headers_install.pl @@ -42,9 +42,6 @@ $line =~ s/(^|\s)(inline)\b/$1__$2__/g; $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g; $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g; - $line =~ s/#ifndef _UAPI/#ifndef /; - $line =~ s/#define _UAPI/#define /; - $line =~ s!#endif /[*] _UAPI!#endif /* !; printf {$out} "%s", $line; } close $out; diff --git a/trunk/tools/Makefile b/trunk/tools/Makefile index 1f9a529fe544..3ae43947a171 100644 --- a/trunk/tools/Makefile +++ b/trunk/tools/Makefile @@ -31,44 +31,44 @@ help: @echo ' clean: a summary clean target to clean _all_ folders' cpupower: FORCE - $(call descend,power/$@) + $(QUIET_SUBDIR0)power/$@/ $(QUIET_SUBDIR1) firewire lguest perf usb virtio vm: FORCE - $(call descend,$@) + $(QUIET_SUBDIR0)$@/ $(QUIET_SUBDIR1) selftests: FORCE - $(call descend,testing/$@) + $(QUIET_SUBDIR0)testing/$@/ $(QUIET_SUBDIR1) turbostat x86_energy_perf_policy: FORCE - $(call descend,power/x86/$@) + $(QUIET_SUBDIR0)power/x86/$@/ $(QUIET_SUBDIR1) cpupower_install: - $(call descend,power/$(@:_install=),install) + $(QUIET_SUBDIR0)power/$(@:_install=)/ $(QUIET_SUBDIR1) install firewire_install lguest_install perf_install usb_install virtio_install vm_install: - $(call descend,$(@:_install=),install) + $(QUIET_SUBDIR0)$(@:_install=)/ $(QUIET_SUBDIR1) install selftests_install: - $(call descend,testing/$(@:_clean=),install) + $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) install turbostat_install x86_energy_perf_policy_install: - $(call descend,power/x86/$(@:_install=),install) + $(QUIET_SUBDIR0)power/x86/$(@:_install=)/ $(QUIET_SUBDIR1) install install: cpupower_install firewire_install lguest_install perf_install \ selftests_install turbostat_install usb_install virtio_install \ vm_install x86_energy_perf_policy_install cpupower_clean: - $(call descend,power/cpupower,clean) + $(QUIET_SUBDIR0)power/cpupower/ $(QUIET_SUBDIR1) clean firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean: - $(call descend,$(@:_clean=),clean) + $(QUIET_SUBDIR0)$(@:_clean=)/ $(QUIET_SUBDIR1) clean selftests_clean: - $(call descend,testing/$(@:_clean=),clean) + $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) clean turbostat_clean x86_energy_perf_policy_clean: - $(call descend,power/x86/$(@:_clean=),clean) + $(QUIET_SUBDIR0)power/x86/$(@:_clean=)/ $(QUIET_SUBDIR1) clean clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \ turbostat_clean usb_clean virtio_clean vm_clean \ diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 0a619af5be43..00deed4d6159 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -169,34 +169,7 @@ endif ### --- END CONFIGURATION SECTION --- -ifeq ($(srctree),) -srctree := $(patsubst %/,%,$(dir $(shell pwd))) -srctree := $(patsubst %/,%,$(dir $(srctree))) -#$(info Determined 'srctree' to be $(srctree)) -endif - -ifneq ($(objtree),) -#$(info Determined 'objtree' to be $(objtree)) -endif - -ifneq ($(OUTPUT),) -#$(info Determined 'OUTPUT' to be $(OUTPUT)) -endif - -BASIC_CFLAGS = \ - -Iutil/include \ - -Iarch/$(ARCH)/include \ - $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \ - -I$(srctree)/arch/$(ARCH)/include/uapi \ - -I$(srctree)/arch/$(ARCH)/include \ - $(if $(objtree),-I$(objtree)/include/generated/uapi) \ - -I$(srctree)/include/uapi \ - -I$(srctree)/include \ - -I$(OUTPUT)util \ - -Iutil \ - -I. \ - -I$(TRACE_EVENT_DIR) \ - -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = # Guard against environment variables diff --git a/trunk/tools/perf/arch/x86/include/perf_regs.h b/trunk/tools/perf/arch/x86/include/perf_regs.h index 7fcdcdbee917..46fc9f15c6b3 100644 --- a/trunk/tools/perf/arch/x86/include/perf_regs.h +++ b/trunk/tools/perf/arch/x86/include/perf_regs.h @@ -3,7 +3,7 @@ #include #include "../../util/types.h" -#include +#include "../../../../../arch/x86/include/asm/perf_regs.h" #ifndef ARCH_X86_64 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1) diff --git a/trunk/tools/perf/builtin-kvm.c b/trunk/tools/perf/builtin-kvm.c index 283b4397e397..260abc535b5b 100644 --- a/trunk/tools/perf/builtin-kvm.c +++ b/trunk/tools/perf/builtin-kvm.c @@ -22,10 +22,9 @@ #include #include -#if defined(__i386__) || defined(__x86_64__) -#include -#include -#include +#include "../../arch/x86/include/asm/svm.h" +#include "../../arch/x86/include/asm/vmx.h" +#include "../../arch/x86/include/asm/kvm.h" struct event_key { #define INVALID_KEY (~0ULL) @@ -59,7 +58,7 @@ struct kvm_event_key { }; -struct perf_kvm_stat; +struct perf_kvm; struct kvm_events_ops { bool (*is_begin_event)(struct perf_evsel *evsel, @@ -67,7 +66,7 @@ struct kvm_events_ops { struct event_key *key); bool (*is_end_event)(struct perf_evsel *evsel, struct perf_sample *sample, struct event_key *key); - void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, + void (*decode_key)(struct perf_kvm *kvm, struct event_key *key, char decode[20]); const char *name; }; @@ -80,7 +79,7 @@ struct exit_reasons_table { #define EVENTS_BITS 12 #define EVENTS_CACHE_SIZE (1UL << EVENTS_BITS) -struct perf_kvm_stat { +struct perf_kvm { struct perf_tool tool; struct perf_session *session; @@ -147,7 +146,7 @@ static struct exit_reasons_table svm_exit_reasons[] = { SVM_EXIT_REASONS }; -static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code) +static const char *get_exit_reason(struct perf_kvm *kvm, u64 exit_code) { int i = kvm->exit_reasons_size; struct exit_reasons_table *tbl = kvm->exit_reasons; @@ -163,7 +162,7 @@ static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code) return "UNKNOWN"; } -static void exit_event_decode_key(struct perf_kvm_stat *kvm, +static void exit_event_decode_key(struct perf_kvm *kvm, struct event_key *key, char decode[20]) { @@ -229,7 +228,7 @@ static bool mmio_event_end(struct perf_evsel *evsel, struct perf_sample *sample, return false; } -static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, +static void mmio_event_decode_key(struct perf_kvm *kvm __maybe_unused, struct event_key *key, char decode[20]) { @@ -272,7 +271,7 @@ static bool ioport_event_end(struct perf_evsel *evsel, return kvm_entry_event(evsel); } -static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, +static void ioport_event_decode_key(struct perf_kvm *kvm __maybe_unused, struct event_key *key, char decode[20]) { @@ -287,7 +286,7 @@ static struct kvm_events_ops ioport_events = { .name = "IO Port Access" }; -static bool register_kvm_events_ops(struct perf_kvm_stat *kvm) +static bool register_kvm_events_ops(struct perf_kvm *kvm) { bool ret = true; @@ -312,7 +311,7 @@ struct vcpu_event_record { }; -static void init_kvm_event_record(struct perf_kvm_stat *kvm) +static void init_kvm_event_record(struct perf_kvm *kvm) { int i; @@ -361,7 +360,7 @@ static struct kvm_event *kvm_alloc_init_event(struct event_key *key) return event; } -static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm, +static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm, struct event_key *key) { struct kvm_event *event; @@ -382,7 +381,7 @@ static struct kvm_event *find_create_kvm_event(struct perf_kvm_stat *kvm, return event; } -static bool handle_begin_event(struct perf_kvm_stat *kvm, +static bool handle_begin_event(struct perf_kvm *kvm, struct vcpu_event_record *vcpu_record, struct event_key *key, u64 timestamp) { @@ -426,7 +425,7 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id, return true; } -static bool handle_end_event(struct perf_kvm_stat *kvm, +static bool handle_end_event(struct perf_kvm *kvm, struct vcpu_event_record *vcpu_record, struct event_key *key, u64 timestamp) @@ -487,7 +486,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread, return thread->priv; } -static bool handle_kvm_event(struct perf_kvm_stat *kvm, +static bool handle_kvm_event(struct perf_kvm *kvm, struct thread *thread, struct perf_evsel *evsel, struct perf_sample *sample) @@ -542,7 +541,7 @@ static struct kvm_event_key keys[] = { { NULL, NULL } }; -static bool select_key(struct perf_kvm_stat *kvm) +static bool select_key(struct perf_kvm *kvm) { int i; @@ -578,8 +577,7 @@ static void insert_to_result(struct rb_root *result, struct kvm_event *event, rb_insert_color(&event->rb, result); } -static void -update_total_count(struct perf_kvm_stat *kvm, struct kvm_event *event) +static void update_total_count(struct perf_kvm *kvm, struct kvm_event *event) { int vcpu = kvm->trace_vcpu; @@ -592,7 +590,7 @@ static bool event_is_valid(struct kvm_event *event, int vcpu) return !!get_event_count(event, vcpu); } -static void sort_result(struct perf_kvm_stat *kvm) +static void sort_result(struct perf_kvm *kvm) { unsigned int i; int vcpu = kvm->trace_vcpu; @@ -629,7 +627,7 @@ static void print_vcpu_info(int vcpu) pr_info("VCPU %d:\n\n", vcpu); } -static void print_result(struct perf_kvm_stat *kvm) +static void print_result(struct perf_kvm *kvm) { char decode[20]; struct kvm_event *event; @@ -672,8 +670,7 @@ static int process_sample_event(struct perf_tool *tool, struct machine *machine) { struct thread *thread = machine__findnew_thread(machine, sample->tid); - struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, - tool); + struct perf_kvm *kvm = container_of(tool, struct perf_kvm, tool); if (thread == NULL) { pr_debug("problem processing %d event, skipping it.\n", @@ -704,7 +701,7 @@ static int get_cpu_isa(struct perf_session *session) return isa; } -static int read_events(struct perf_kvm_stat *kvm) +static int read_events(struct perf_kvm *kvm) { int ret; @@ -753,7 +750,7 @@ static bool verify_vcpu(int vcpu) return true; } -static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm) +static int kvm_events_report_vcpu(struct perf_kvm *kvm) { int ret = -EINVAL; int vcpu = kvm->trace_vcpu; @@ -801,8 +798,7 @@ static const char * const record_args[] = { _p; \ }) -static int -kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) +static int kvm_events_record(struct perf_kvm *kvm, int argc, const char **argv) { unsigned int rec_argc, i, j; const char **rec_argv; @@ -825,8 +821,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) return cmd_record(i, rec_argv, NULL); } -static int -kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv) +static int kvm_events_report(struct perf_kvm *kvm, int argc, const char **argv) { const struct option kvm_events_report_options[] = { OPT_STRING(0, "event", &kvm->report_event, "report event", @@ -869,37 +864,24 @@ static void print_kvm_stat_usage(void) printf("\nOtherwise, it is the alias of 'perf stat':\n"); } -static int kvm_cmd_stat(const char *file_name, int argc, const char **argv) +static int kvm_cmd_stat(struct perf_kvm *kvm, int argc, const char **argv) { - struct perf_kvm_stat kvm = { - .file_name = file_name, - - .trace_vcpu = -1, - .report_event = "vmexit", - .sort_key = "sample", - - .exit_reasons = svm_exit_reasons, - .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons), - .exit_reasons_isa = "SVM", - }; - if (argc == 1) { print_kvm_stat_usage(); goto perf_stat; } if (!strncmp(argv[1], "rec", 3)) - return kvm_events_record(&kvm, argc - 1, argv + 1); + return kvm_events_record(kvm, argc - 1, argv + 1); if (!strncmp(argv[1], "rep", 3)) - return kvm_events_report(&kvm, argc - 1 , argv + 1); + return kvm_events_report(kvm, argc - 1 , argv + 1); perf_stat: return cmd_stat(argc, argv, NULL); } -#endif -static int __cmd_record(const char *file_name, int argc, const char **argv) +static int __cmd_record(struct perf_kvm *kvm, int argc, const char **argv) { int rec_argc, i = 0, j; const char **rec_argv; @@ -908,7 +890,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv) rec_argv = calloc(rec_argc + 1, sizeof(char *)); rec_argv[i++] = strdup("record"); rec_argv[i++] = strdup("-o"); - rec_argv[i++] = strdup(file_name); + rec_argv[i++] = strdup(kvm->file_name); for (j = 1; j < argc; j++, i++) rec_argv[i] = argv[j]; @@ -917,7 +899,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv) return cmd_record(i, rec_argv, NULL); } -static int __cmd_report(const char *file_name, int argc, const char **argv) +static int __cmd_report(struct perf_kvm *kvm, int argc, const char **argv) { int rec_argc, i = 0, j; const char **rec_argv; @@ -926,7 +908,7 @@ static int __cmd_report(const char *file_name, int argc, const char **argv) rec_argv = calloc(rec_argc + 1, sizeof(char *)); rec_argv[i++] = strdup("report"); rec_argv[i++] = strdup("-i"); - rec_argv[i++] = strdup(file_name); + rec_argv[i++] = strdup(kvm->file_name); for (j = 1; j < argc; j++, i++) rec_argv[i] = argv[j]; @@ -935,8 +917,7 @@ static int __cmd_report(const char *file_name, int argc, const char **argv) return cmd_report(i, rec_argv, NULL); } -static int -__cmd_buildid_list(const char *file_name, int argc, const char **argv) +static int __cmd_buildid_list(struct perf_kvm *kvm, int argc, const char **argv) { int rec_argc, i = 0, j; const char **rec_argv; @@ -945,7 +926,7 @@ __cmd_buildid_list(const char *file_name, int argc, const char **argv) rec_argv = calloc(rec_argc + 1, sizeof(char *)); rec_argv[i++] = strdup("buildid-list"); rec_argv[i++] = strdup("-i"); - rec_argv[i++] = strdup(file_name); + rec_argv[i++] = strdup(kvm->file_name); for (j = 1; j < argc; j++, i++) rec_argv[i] = argv[j]; @@ -956,12 +937,20 @@ __cmd_buildid_list(const char *file_name, int argc, const char **argv) int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused) { - const char *file_name; + struct perf_kvm kvm = { + .trace_vcpu = -1, + .report_event = "vmexit", + .sort_key = "sample", + + .exit_reasons = svm_exit_reasons, + .exit_reasons_size = ARRAY_SIZE(svm_exit_reasons), + .exit_reasons_isa = "SVM", + }; const struct option kvm_options[] = { - OPT_STRING('i', "input", &file_name, "file", + OPT_STRING('i', "input", &kvm.file_name, "file", "Input file name"), - OPT_STRING('o', "output", &file_name, "file", + OPT_STRING('o', "output", &kvm.file_name, "file", "Output file name"), OPT_BOOLEAN(0, "guest", &perf_guest, "Collect guest os data"), @@ -996,34 +985,32 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused) if (!perf_host) perf_guest = 1; - if (!file_name) { + if (!kvm.file_name) { if (perf_host && !perf_guest) - file_name = strdup("perf.data.host"); + kvm.file_name = strdup("perf.data.host"); else if (!perf_host && perf_guest) - file_name = strdup("perf.data.guest"); + kvm.file_name = strdup("perf.data.guest"); else - file_name = strdup("perf.data.kvm"); + kvm.file_name = strdup("perf.data.kvm"); - if (!file_name) { + if (!kvm.file_name) { pr_err("Failed to allocate memory for filename\n"); return -ENOMEM; } } if (!strncmp(argv[0], "rec", 3)) - return __cmd_record(file_name, argc, argv); + return __cmd_record(&kvm, argc, argv); else if (!strncmp(argv[0], "rep", 3)) - return __cmd_report(file_name, argc, argv); + return __cmd_report(&kvm, argc, argv); else if (!strncmp(argv[0], "diff", 4)) return cmd_diff(argc, argv, NULL); else if (!strncmp(argv[0], "top", 3)) return cmd_top(argc, argv, NULL); else if (!strncmp(argv[0], "buildid-list", 12)) - return __cmd_buildid_list(file_name, argc, argv); -#if defined(__i386__) || defined(__x86_64__) + return __cmd_buildid_list(&kvm, argc, argv); else if (!strncmp(argv[0], "stat", 4)) - return kvm_cmd_stat(file_name, argc, argv); -#endif + return kvm_cmd_stat(&kvm, argc, argv); else usage_with_options(kvm_usage, kvm_options); diff --git a/trunk/tools/perf/builtin-test.c b/trunk/tools/perf/builtin-test.c index 5acd6e8e658b..484f26cc0c00 100644 --- a/trunk/tools/perf/builtin-test.c +++ b/trunk/tools/perf/builtin-test.c @@ -15,7 +15,7 @@ #include "util/thread_map.h" #include "util/pmu.h" #include "event-parse.h" -#include +#include "../../include/linux/hw_breakpoint.h" #include diff --git a/trunk/tools/perf/perf.h b/trunk/tools/perf/perf.h index 238f923f2218..c50985eaec41 100644 --- a/trunk/tools/perf/perf.h +++ b/trunk/tools/perf/perf.h @@ -5,9 +5,8 @@ struct winsize; void get_term_dimensions(struct winsize *ws); -#include - #if defined(__i386__) +#include "../../arch/x86/include/asm/unistd.h" #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC "model name" @@ -17,6 +16,7 @@ void get_term_dimensions(struct winsize *ws); #endif #if defined(__x86_64__) +#include "../../arch/x86/include/asm/unistd.h" #define rmb() asm volatile("lfence" ::: "memory") #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC "model name" @@ -26,17 +26,20 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __powerpc__ +#include "../../arch/powerpc/include/asm/unistd.h" #define rmb() asm volatile ("sync" ::: "memory") #define cpu_relax() asm volatile ("" ::: "memory"); #define CPUINFO_PROC "cpu" #endif #ifdef __s390__ +#include "../../arch/s390/include/asm/unistd.h" #define rmb() asm volatile("bcr 15,0" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory"); #endif #ifdef __sh__ +#include "../../arch/sh/include/asm/unistd.h" #if defined(__SH4A__) || defined(__SH5__) # define rmb() asm volatile("synco" ::: "memory") #else @@ -47,30 +50,35 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __hppa__ +#include "../../arch/parisc/include/asm/unistd.h" #define rmb() asm volatile("" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory"); #define CPUINFO_PROC "cpu" #endif #ifdef __sparc__ +#include "../../arch/sparc/include/uapi/asm/unistd.h" #define rmb() asm volatile("":::"memory") #define cpu_relax() asm volatile("":::"memory") #define CPUINFO_PROC "cpu" #endif #ifdef __alpha__ +#include "../../arch/alpha/include/asm/unistd.h" #define rmb() asm volatile("mb" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory") #define CPUINFO_PROC "cpu model" #endif #ifdef __ia64__ +#include "../../arch/ia64/include/asm/unistd.h" #define rmb() asm volatile ("mf" ::: "memory") #define cpu_relax() asm volatile ("hint @pause" ::: "memory") #define CPUINFO_PROC "model name" #endif #ifdef __arm__ +#include "../../arch/arm/include/asm/unistd.h" /* * Use the __kuser_memory_barrier helper in the CPU helper page. See * arch/arm/kernel/entry-armv.S in the kernel source for details. @@ -81,11 +89,13 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __aarch64__ +#include "../../arch/arm64/include/asm/unistd.h" #define rmb() asm volatile("dmb ld" ::: "memory") #define cpu_relax() asm volatile("yield" ::: "memory") #endif #ifdef __mips__ +#include "../../arch/mips/include/asm/unistd.h" #define rmb() asm volatile( \ ".set mips2\n\t" \ "sync\n\t" \ @@ -102,7 +112,7 @@ void get_term_dimensions(struct winsize *ws); #include #include -#include +#include "../../include/uapi/linux/perf_event.h" #include "util/types.h" #include diff --git a/trunk/tools/perf/util/evsel.c b/trunk/tools/perf/util/evsel.c index d144d464ce39..618d41140abd 100644 --- a/trunk/tools/perf/util/evsel.c +++ b/trunk/tools/perf/util/evsel.c @@ -18,8 +18,8 @@ #include "cpumap.h" #include "thread_map.h" #include "target.h" -#include -#include +#include "../../../include/linux/hw_breakpoint.h" +#include "../../../include/uapi/linux/perf_event.h" #include "perf_regs.h" #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) diff --git a/trunk/tools/perf/util/evsel.h b/trunk/tools/perf/util/evsel.h index d99b476ef37c..6f94d6dea00f 100644 --- a/trunk/tools/perf/util/evsel.h +++ b/trunk/tools/perf/util/evsel.h @@ -3,8 +3,7 @@ #include #include -#include -#include +#include "../../../include/uapi/linux/perf_event.h" #include "types.h" #include "xyarray.h" #include "cgroup.h" diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index 566b84c695c8..7daad237dea5 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -1378,8 +1378,6 @@ static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused, str = tmp + 1; fprintf(fp, "# node%u cpu list : %s\n", c, str); - - str += strlen(str) + 1; } return; error: diff --git a/trunk/tools/perf/util/header.h b/trunk/tools/perf/util/header.h index 9bc00783f24f..879d215cdac9 100644 --- a/trunk/tools/perf/util/header.h +++ b/trunk/tools/perf/util/header.h @@ -1,7 +1,7 @@ #ifndef __PERF_HEADER_H #define __PERF_HEADER_H -#include +#include "../../../include/uapi/linux/perf_event.h" #include #include #include "types.h" diff --git a/trunk/tools/perf/util/parse-events-test.c b/trunk/tools/perf/util/parse-events-test.c index 6ef213b35ecd..516ecd9ddd6e 100644 --- a/trunk/tools/perf/util/parse-events-test.c +++ b/trunk/tools/perf/util/parse-events-test.c @@ -3,7 +3,7 @@ #include "evsel.h" #include "evlist.h" #include "sysfs.h" -#include +#include "../../../include/linux/hw_breakpoint.h" #define TEST_ASSERT_VAL(text, cond) \ do { \ diff --git a/trunk/tools/perf/util/parse-events.c b/trunk/tools/perf/util/parse-events.c index 6b6d03e93c3d..75c7b0fca6d9 100644 --- a/trunk/tools/perf/util/parse-events.c +++ b/trunk/tools/perf/util/parse-events.c @@ -1,4 +1,4 @@ -#include +#include "../../../include/linux/hw_breakpoint.h" #include "util.h" #include "../perf.h" #include "evlist.h" diff --git a/trunk/tools/perf/util/parse-events.h b/trunk/tools/perf/util/parse-events.h index 2820c407adb2..839230ceb18b 100644 --- a/trunk/tools/perf/util/parse-events.h +++ b/trunk/tools/perf/util/parse-events.h @@ -7,7 +7,7 @@ #include #include #include "types.h" -#include +#include "../../../include/uapi/linux/perf_event.h" #include "types.h" struct list_head; diff --git a/trunk/tools/perf/util/pmu.h b/trunk/tools/perf/util/pmu.h index fdeb8ac7c5d2..39f3abac7744 100644 --- a/trunk/tools/perf/util/pmu.h +++ b/trunk/tools/perf/util/pmu.h @@ -2,7 +2,7 @@ #define __PMU_H #include -#include +#include "../../../include/uapi/linux/perf_event.h" enum { PERF_PMU_FORMAT_VALUE_CONFIG, diff --git a/trunk/tools/perf/util/session.h b/trunk/tools/perf/util/session.h index 0eae00ad5fe7..dd6426163ba6 100644 --- a/trunk/tools/perf/util/session.h +++ b/trunk/tools/perf/util/session.h @@ -7,7 +7,7 @@ #include "symbol.h" #include "thread.h" #include -#include +#include "../../../include/uapi/linux/perf_event.h" struct sample_queue; struct ip_callchain; diff --git a/trunk/tools/perf/util/strbuf.c b/trunk/tools/perf/util/strbuf.c index cfa906882e2c..2eeb51baf077 100644 --- a/trunk/tools/perf/util/strbuf.c +++ b/trunk/tools/perf/util/strbuf.c @@ -90,17 +90,17 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...) if (!strbuf_avail(sb)) strbuf_grow(sb, 64); va_start(ap, fmt); - len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); va_end(ap); if (len < 0) - die("your vsnprintf is broken"); + die("your vscnprintf is broken"); if (len > strbuf_avail(sb)) { strbuf_grow(sb, len); va_start(ap, fmt); - len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); va_end(ap); if (len > strbuf_avail(sb)) { - die("this should not happen, your vsnprintf is broken"); + die("this should not happen, your snprintf is broken"); } } strbuf_setlen(sb, sb->len + len); diff --git a/trunk/tools/scripts/Makefile.include b/trunk/tools/scripts/Makefile.include index 2964b96aa55f..96ce80a3743b 100644 --- a/trunk/tools/scripts/Makefile.include +++ b/trunk/tools/scripts/Makefile.include @@ -1,11 +1,8 @@ -ifeq ($(origin O), command line) +ifeq ("$(origin O)", "command line") dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),) ABSOLUTE_O := $(shell cd $(O) ; pwd) - OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/) + OUTPUT := $(ABSOLUTE_O)/ COMMAND_O := O=$(ABSOLUTE_O) -ifeq ($(objtree),) - objtree := $(O) -endif endif ifneq ($(OUTPUT),) @@ -44,16 +41,7 @@ else NO_SUBDIR = : endif -# -# Define a callable command for descending to a new directory -# -# Call by doing: $(call descend,directory[,target]) -# -descend = \ - +mkdir -p $(OUTPUT)$(1) && \ - $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) - -QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir +QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir QUIET_SUBDIR1 = ifneq ($(findstring $(MAKEFLAGS),s),s) @@ -68,10 +56,5 @@ ifndef V $(MAKE) $(PRINT_DIR) -C $$subdir QUIET_FLEX = @echo ' ' FLEX $@; QUIET_BISON = @echo ' ' BISON $@; - - descend = \ - @echo ' ' DESCEND $(1); \ - mkdir -p $(OUTPUT)$(1) && \ - $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) endif endif