aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-pci-devices-cciss28
-rw-r--r--Documentation/SubmittingPatches2
-rw-r--r--Documentation/arm/tcm.txt10
-rw-r--r--Documentation/cgroups/cgroups.txt11
-rw-r--r--Documentation/connector/cn_test.c2
-rw-r--r--Documentation/connector/connector.txt8
-rw-r--r--Documentation/hwmon/ltc42157
-rw-r--r--Documentation/hwmon/ltc42457
-rw-r--r--Documentation/i2c/instantiating-devices2
-rw-r--r--Documentation/infiniband/user_mad.txt4
-rw-r--r--Documentation/infiniband/user_verbs.txt2
-rw-r--r--Documentation/isdn/INTERFACE.CAPI83
-rw-r--r--Documentation/kernel-parameters.txt1
-rw-r--r--Documentation/misc-devices/eeprom (renamed from Documentation/i2c/chips/eeprom)0
-rw-r--r--Documentation/misc-devices/max6875 (renamed from Documentation/i2c/chips/max6875)6
-rw-r--r--Documentation/networking/pktgen.txt8
-rw-r--r--Documentation/networking/timestamping/timestamping.c2
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt1
-rw-r--r--Documentation/vm/ksm.txt13
-rw-r--r--Documentation/vm/page-types.c304
-rw-r--r--Documentation/vm/pagemap.txt8
-rw-r--r--Documentation/w1/masters/ds24826
-rw-r--r--MAINTAINERS44
-rw-r--r--Makefile2
-rw-r--r--arch/arm/common/sa1111.c25
-rw-r--r--arch/arm/configs/h3600_defconfig1
-rw-r--r--arch/arm/configs/iop33x_defconfig554
-rw-r--r--arch/arm/include/asm/glue.h26
-rw-r--r--arch/arm/include/asm/hardware/iop3xx.h1
-rw-r--r--arch/arm/include/asm/smp_plat.h16
-rw-r--r--arch/arm/include/asm/unistd.h1
-rw-r--r--arch/arm/kernel/entry-armv.S18
-rw-r--r--arch/arm/kernel/entry-common.S11
-rw-r--r--arch/arm/kernel/head-common.S4
-rw-r--r--arch/arm/kernel/smp.c13
-rw-r--r--arch/arm/kernel/smp_twd.c4
-rw-r--r--arch/arm/kernel/traps.c5
-rw-r--r--arch/arm/mach-bcmring/core.c2
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c1
-rw-r--r--arch/arm/mach-integrator/pci_v3.c2
-rw-r--r--arch/arm/mach-iop32x/include/mach/iop32x.h2
-rw-r--r--arch/arm/mach-iop33x/include/mach/iop33x.h2
-rw-r--r--arch/arm/mach-ns9xxx/clock.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c78
-rw-r--r--arch/arm/mach-omap2/clock34xx.c35
-rw-r--r--arch/arm/mach-omap2/pm-debug.c4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c187
-rw-r--r--arch/arm/mach-omap2/powerdomain.c39
-rw-r--r--arch/arm/mach-sa1100/Kconfig5
-rw-r--r--arch/arm/mach-sa1100/time.c2
-rw-r--r--arch/arm/mach-u300/gpio.c10
-rw-r--r--arch/arm/mach-u300/include/mach/gpio.h1
-rw-r--r--arch/arm/mm/Kconfig57
-rw-r--r--arch/arm/mm/Makefile4
-rw-r--r--arch/arm/mm/fault.c53
-rw-r--r--arch/arm/mm/mmap.c2
-rw-r--r--arch/arm/mm/mmu.c39
-rw-r--r--arch/arm/mm/pabort-legacy.S19
-rw-r--r--arch/arm/mm/pabort-v6.S19
-rw-r--r--arch/arm/mm/pabort-v7.S20
-rw-r--r--arch/arm/mm/proc-arm1020.S2
-rw-r--r--arch/arm/mm/proc-arm1020e.S2
-rw-r--r--arch/arm/mm/proc-arm1022.S2
-rw-r--r--arch/arm/mm/proc-arm1026.S2
-rw-r--r--arch/arm/mm/proc-arm6_7.S4
-rw-r--r--arch/arm/mm/proc-arm720.S2
-rw-r--r--arch/arm/mm/proc-arm740.S2
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S2
-rw-r--r--arch/arm/mm/proc-arm920.S2
-rw-r--r--arch/arm/mm/proc-arm922.S2
-rw-r--r--arch/arm/mm/proc-arm925.S2
-rw-r--r--arch/arm/mm/proc-arm926.S2
-rw-r--r--arch/arm/mm/proc-arm940.S2
-rw-r--r--arch/arm/mm/proc-arm946.S2
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S2
-rw-r--r--arch/arm/mm/proc-fa526.S2
-rw-r--r--arch/arm/mm/proc-feroceon.S2
-rw-r--r--arch/arm/mm/proc-mohawk.S2
-rw-r--r--arch/arm/mm/proc-sa110.S2
-rw-r--r--arch/arm/mm/proc-sa1100.S2
-rw-r--r--arch/arm/mm/proc-v6.S2
-rw-r--r--arch/arm/mm/proc-v7.S2
-rw-r--r--arch/arm/mm/proc-xsc3.S2
-rw-r--r--arch/arm/mm/proc-xscale.S2
-rw-r--r--arch/arm/plat-iop/pci.c3
-rw-r--r--arch/arm/plat-iop/time.c2
-rw-r--r--arch/arm/plat-omap/include/mach/cpu.h37
-rw-r--r--arch/arm/plat-omap/include/mach/powerdomain.h2
-rw-r--r--arch/arm/plat-omap/iovmm.c9
-rw-r--r--arch/arm/plat-omap/sram.c3
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/mci.h3
-rw-r--r--arch/blackfin/ADI_BSD.txt41
-rw-r--r--arch/blackfin/Kconfig13
-rw-r--r--arch/blackfin/include/asm/atomic.h6
-rw-r--r--arch/blackfin/include/asm/bfin-global.h26
-rw-r--r--arch/blackfin/include/asm/bfin5xx_spi.h2
-rw-r--r--arch/blackfin/include/asm/bfin_rotary.h4
-rw-r--r--arch/blackfin/include/asm/bfin_simple_timer.h6
-rw-r--r--arch/blackfin/include/asm/bitops.h6
-rw-r--r--arch/blackfin/include/asm/blackfin.h5
-rw-r--r--arch/blackfin/include/asm/bug.h6
-rw-r--r--arch/blackfin/include/asm/byteorder.h5
-rw-r--r--arch/blackfin/include/asm/cache.h9
-rw-r--r--arch/blackfin/include/asm/cacheflush.h27
-rw-r--r--arch/blackfin/include/asm/cdef_LPBlackfin.h32
-rw-r--r--arch/blackfin/include/asm/checksum.h9
-rw-r--r--arch/blackfin/include/asm/clocks.h27
-rw-r--r--arch/blackfin/include/asm/context.S27
-rw-r--r--arch/blackfin/include/asm/cplb.h27
-rw-r--r--arch/blackfin/include/asm/cplbinit.h27
-rw-r--r--arch/blackfin/include/asm/cpu.h21
-rw-r--r--arch/blackfin/include/asm/def_LPBlackfin.h36
-rw-r--r--arch/blackfin/include/asm/dma-mapping.h6
-rw-r--r--arch/blackfin/include/asm/dpmc.h6
-rw-r--r--arch/blackfin/include/asm/early_printk.h22
-rw-r--r--arch/blackfin/include/asm/elf.h6
-rw-r--r--arch/blackfin/include/asm/entry.h6
-rw-r--r--arch/blackfin/include/asm/fcntl.h6
-rw-r--r--arch/blackfin/include/asm/fixed_code.h10
-rw-r--r--arch/blackfin/include/asm/flat.h5
-rw-r--r--arch/blackfin/include/asm/gpio.h27
-rw-r--r--arch/blackfin/include/asm/hardirq.h6
-rw-r--r--arch/blackfin/include/asm/io.h6
-rw-r--r--arch/blackfin/include/asm/irq.h19
-rw-r--r--arch/blackfin/include/asm/irq_handler.h6
-rw-r--r--arch/blackfin/include/asm/l1layout.h5
-rw-r--r--arch/blackfin/include/asm/linkage.h6
-rw-r--r--arch/blackfin/include/asm/mmu.h9
-rw-r--r--arch/blackfin/include/asm/mmu_context.h27
-rw-r--r--arch/blackfin/include/asm/module.h6
-rw-r--r--arch/blackfin/include/asm/mutex.h4
-rw-r--r--arch/blackfin/include/asm/nand.h12
-rw-r--r--arch/blackfin/include/asm/page.h6
-rw-r--r--arch/blackfin/include/asm/page_offset.h9
-rw-r--r--arch/blackfin/include/asm/pda.h21
-rw-r--r--arch/blackfin/include/asm/pgtable.h12
-rw-r--r--arch/blackfin/include/asm/poll.h7
-rw-r--r--arch/blackfin/include/asm/portmux.h5
-rw-r--r--arch/blackfin/include/asm/posix_types.h6
-rw-r--r--arch/blackfin/include/asm/processor.h6
-rw-r--r--arch/blackfin/include/asm/ptrace.h6
-rw-r--r--arch/blackfin/include/asm/sections.h6
-rw-r--r--arch/blackfin/include/asm/segment.h6
-rw-r--r--arch/blackfin/include/asm/sigcontext.h6
-rw-r--r--arch/blackfin/include/asm/siginfo.h6
-rw-r--r--arch/blackfin/include/asm/smp.h21
-rw-r--r--arch/blackfin/include/asm/spinlock.h6
-rw-r--r--arch/blackfin/include/asm/spinlock_types.h6
-rw-r--r--arch/blackfin/include/asm/stat.h6
-rw-r--r--arch/blackfin/include/asm/string.h6
-rw-r--r--arch/blackfin/include/asm/swab.h6
-rw-r--r--arch/blackfin/include/asm/system.h32
-rw-r--r--arch/blackfin/include/asm/thread_info.h24
-rw-r--r--arch/blackfin/include/asm/tlb.h6
-rw-r--r--arch/blackfin/include/asm/trace.h5
-rw-r--r--arch/blackfin/include/asm/traps.h13
-rw-r--r--arch/blackfin/include/asm/uaccess.h5
-rw-r--r--arch/blackfin/include/asm/unistd.h6
-rw-r--r--arch/blackfin/kernel/asm-offsets.c27
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c1
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c27
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbinit.c20
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c19
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinit.c19
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.c16
-rw-r--r--arch/blackfin/kernel/cplbinfo.c26
-rw-r--r--arch/blackfin/kernel/dma-mapping.c27
-rw-r--r--arch/blackfin/kernel/early_printk.c23
-rw-r--r--arch/blackfin/kernel/entry.S27
-rw-r--r--arch/blackfin/kernel/fixed_code.S5
-rw-r--r--arch/blackfin/kernel/flat.c18
-rw-r--r--arch/blackfin/kernel/init_task.c27
-rw-r--r--arch/blackfin/kernel/irqchip.c27
-rw-r--r--arch/blackfin/kernel/module.c27
-rw-r--r--arch/blackfin/kernel/process.c27
-rw-r--r--arch/blackfin/kernel/ptrace.c28
-rw-r--r--arch/blackfin/kernel/setup.c6
-rw-r--r--arch/blackfin/kernel/shadow_console.c2
-rw-r--r--arch/blackfin/kernel/signal.c27
-rw-r--r--arch/blackfin/kernel/sys_bfin.c41
-rw-r--r--arch/blackfin/kernel/time-ts.c10
-rw-r--r--arch/blackfin/kernel/time.c63
-rw-r--r--arch/blackfin/kernel/traps.c27
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S27
-rw-r--r--arch/blackfin/lib/ashldi3.c27
-rw-r--r--arch/blackfin/lib/ashrdi3.c27
-rw-r--r--arch/blackfin/lib/checksum.c30
-rw-r--r--arch/blackfin/lib/divsi3.S28
-rw-r--r--arch/blackfin/lib/gcclib.h27
-rw-r--r--arch/blackfin/lib/lshrdi3.c27
-rw-r--r--arch/blackfin/lib/memchr.S27
-rw-r--r--arch/blackfin/lib/memcmp.S27
-rw-r--r--arch/blackfin/lib/memcpy.S37
-rw-r--r--arch/blackfin/lib/memmove.S27
-rw-r--r--arch/blackfin/lib/memset.S27
-rw-r--r--arch/blackfin/lib/modsi3.S36
-rw-r--r--arch/blackfin/lib/muldi3.S6
-rw-r--r--arch/blackfin/lib/outs.S29
-rw-r--r--arch/blackfin/lib/smulsi3_highpart.S6
-rw-r--r--arch/blackfin/lib/udivsi3.S27
-rw-r--r--arch/blackfin/lib/umodsi3.S27
-rw-r--r--arch/blackfin/lib/umulsi3_highpart.S6
-rw-r--r--arch/blackfin/mach-bf518/boards/ezbrd.c45
-rw-r--r--arch/blackfin/mach-bf518/dma.c28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/bf518.h27
-rw-r--r--arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF512.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF514.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF516.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF518.h70
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF512.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF514.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF516.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF518.h56
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF51x_base.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf518/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf518/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf527/boards/cm_bf527.c61
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c45
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c60
-rw-r--r--arch/blackfin/mach-bf527/dma.c28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bf527.h27
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF522.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF525.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF527.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF522.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF525.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF527.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF52x_base.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf527/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf527/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf533/boards/H8606.c33
-rw-r--r--arch/blackfin/mach-bf533/boards/blackstamp.c29
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c45
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c132
-rw-r--r--arch/blackfin/mach-bf533/boards/ip0x.c37
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c60
-rw-r--r--arch/blackfin/mach-bf533/dma.c28
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bf533.h27
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf533/include/mach/blackfin.h28
-rw-r--r--arch/blackfin/mach-bf533/include/mach/cdefBF532.h28
-rw-r--r--arch/blackfin/mach-bf533/include/mach/defBF532.h44
-rw-r--r--arch/blackfin/mach-bf533/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf533/include/mach/irq.h28
-rw-r--r--arch/blackfin/mach-bf533/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf533/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537e.c46
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537u.c46
-rw-r--r--arch/blackfin/mach-bf537/boards/minotaur.c6
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c31
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c60
-rw-r--r--arch/blackfin/mach-bf537/boards/tcm_bf537.c46
-rw-r--r--arch/blackfin/mach-bf537/dma.c28
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bf537.h27
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/cdefBF534.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/cdefBF537.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/defBF534.h28
-rw-r--r--arch/blackfin/mach-bf537/include/mach/defBF537.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf537/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf537/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf538/boards/ezkit.c46
-rw-r--r--arch/blackfin/mach-bf538/dma.c28
-rw-r--r--arch/blackfin/mach-bf538/include/mach/bf538.h27
-rw-r--r--arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf538/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf538/include/mach/cdefBF538.h28
-rw-r--r--arch/blackfin/mach-bf538/include/mach/defBF539.h44
-rw-r--r--arch/blackfin/mach-bf538/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf538/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf538/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf538/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf548/boards/cm_bf548.c48
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c49
-rw-r--r--arch/blackfin/mach-bf548/dma.c27
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bf548.h27
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h6
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bf54x_keys.h6
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf548/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF542.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF544.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF547.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF548.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF549.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF542.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF544.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF547.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF548.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF549.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF54x_base.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/gpio.h30
-rw-r--r--arch/blackfin/mach-bf548/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf548/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf548/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf561/atomic.S21
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c45
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c44
-rw-r--r--arch/blackfin/mach-bf561/boards/tepla.c14
-rw-r--r--arch/blackfin/mach-bf561/coreb.c2
-rw-r--r--arch/blackfin/mach-bf561/dma.c28
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bf561.h27
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf561/include/mach/blackfin.h28
-rw-r--r--arch/blackfin/mach-bf561/include/mach/cdefBF561.h28
-rw-r--r--arch/blackfin/mach-bf561/include/mach/defBF561.h29
-rw-r--r--arch/blackfin/mach-bf561/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf561/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf561/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf561/include/mach/smp.h6
-rw-r--r--arch/blackfin/mach-bf561/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf561/secondary.S24
-rw-r--r--arch/blackfin/mach-bf561/smp.c21
-rw-r--r--arch/blackfin/mach-common/arch_checks.c27
-rw-r--r--arch/blackfin/mach-common/cache-c.c2
-rw-r--r--arch/blackfin/mach-common/cache.S2
-rw-r--r--arch/blackfin/mach-common/cpufreq.c27
-rw-r--r--arch/blackfin/mach-common/entry.S31
-rw-r--r--arch/blackfin/mach-common/head.S2
-rw-r--r--arch/blackfin/mach-common/interrupt.S30
-rw-r--r--arch/blackfin/mach-common/ints-priority.c35
-rw-r--r--arch/blackfin/mach-common/irqpanic.c27
-rw-r--r--arch/blackfin/mach-common/pm.c34
-rw-r--r--arch/blackfin/mach-common/smp.c22
-rw-r--r--arch/blackfin/mm/blackfin_sram.h27
-rw-r--r--arch/blackfin/mm/init.c27
-rw-r--r--arch/blackfin/mm/isram-driver.c14
-rw-r--r--arch/blackfin/mm/sram-alloc.c27
-rw-r--r--arch/cris/arch-v10/drivers/sync_serial.c2
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/gpio.c2
-rw-r--r--arch/m32r/include/asm/io.h7
-rw-r--r--arch/m32r/kernel/m32r_ksyms.c6
-rw-r--r--arch/m32r/kernel/time.c9
-rw-r--r--arch/m32r/kernel/traps.c4
-rw-r--r--arch/m32r/lib/delay.c4
-rw-r--r--arch/m32r/mm/discontig.c5
-rw-r--r--arch/m32r/mm/mmu.S12
-rw-r--r--arch/m68k/include/asm/hardirq_mm.h12
-rw-r--r--arch/m68knommu/kernel/asm-offsets.c28
-rw-r--r--arch/m68knommu/kernel/entry.S6
-rw-r--r--arch/m68knommu/mm/init.c2
-rw-r--r--arch/m68knommu/platform/5206e/config.c1
-rw-r--r--arch/m68knommu/platform/68328/entry.S32
-rw-r--r--arch/m68knommu/platform/68360/entry.S16
-rw-r--r--arch/m68knommu/platform/coldfire/entry.S20
-rw-r--r--arch/microblaze/kernel/entry.S2
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S2
-rw-r--r--arch/microblaze/kernel/process.c2
-rw-r--r--arch/mn10300/include/asm/uaccess.h73
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/clock.h6
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/clock.h6
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/include/asm/fixmap.h4
-rw-r--r--arch/parisc/include/asm/hardirq.h20
-rw-r--r--arch/parisc/include/asm/ptrace.h5
-rw-r--r--arch/parisc/include/asm/syscall.h40
-rw-r--r--arch/parisc/include/asm/thread_info.h14
-rw-r--r--arch/parisc/kernel/asm-offsets.c4
-rw-r--r--arch/parisc/kernel/entry.S21
-rw-r--r--arch/parisc/kernel/irq.c5
-rw-r--r--arch/parisc/kernel/module.c2
-rw-r--r--arch/parisc/kernel/ptrace.c42
-rw-r--r--arch/parisc/kernel/signal.c5
-rw-r--r--arch/parisc/kernel/syscall.S22
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S10
-rw-r--r--arch/parisc/mm/init.c11
-rw-r--r--arch/powerpc/kvm/timing.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c2
-rw-r--r--arch/powerpc/platforms/pseries/dtl.c2
-rw-r--r--arch/s390/kvm/kvm-s390.h2
-rw-r--r--arch/sh/boards/board-magicpanelr2.c2
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c2
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c63
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S2
-rw-r--r--arch/sh/kernel/io_generic.c3
-rw-r--r--arch/sh/kernel/machvec.c3
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c1
-rw-r--r--arch/sh/kernel/traps_32.c4
-rw-r--r--arch/sh/mm/cache-sh4.c2
-rw-r--r--arch/sh/mm/cache-sh7705.c4
-rw-r--r--arch/sh/mm/ioremap_32.c2
-rw-r--r--arch/sh/mm/pmb.c37
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/sparc/include/asm/hardirq_32.h12
-rw-r--r--arch/sparc/include/asm/irq_32.h4
-rw-r--r--arch/sparc/include/asm/pgtable_64.h4
-rw-r--r--arch/sparc/kernel/ktlb.S8
-rw-r--r--arch/sparc/kernel/perf_event.c577
-rw-r--r--arch/sparc/oprofile/init.c1
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/Kconfig.cpu3
-rw-r--r--arch/x86/ia32/ia32entry.S36
-rw-r--r--arch/x86/include/asm/checksum_32.h3
-rw-r--r--arch/x86/include/asm/cmpxchg_32.h30
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/include/asm/mce.h2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c58
-rw-r--r--arch/x86/kernel/cpu/mtrr/if.c17
-rw-r--r--arch/x86/kernel/early_printk.c5
-rw-r--r--arch/x86/kernel/i386_ksyms_32.c10
-rw-r--r--arch/x86/kernel/irq.c2
-rw-r--r--arch/x86/kernel/pci-dma.c2
-rw-r--r--arch/x86/kernel/smp.c1
-rw-r--r--arch/x86/kvm/lapic.c2
-rw-r--r--arch/x86/kvm/mmu.c84
-rw-r--r--arch/x86/kvm/paging_tmpl.h18
-rw-r--r--arch/x86/kvm/svm.c25
-rw-r--r--arch/x86/kvm/vmx.c2
-rw-r--r--arch/x86/kvm/x86.c2
-rw-r--r--arch/x86/lib/Makefile4
-rw-r--r--arch/x86/lib/cmpxchg8b_emu.S57
-rw-r--r--arch/x86/xen/debugfs.c2
-rw-r--r--block/blk-barrier.c45
-rw-r--r--block/blk-core.c21
-rw-r--r--block/blk-merge.c2
-rw-r--r--block/blk-settings.c34
-rw-r--r--block/blk-sysfs.c11
-rw-r--r--block/cfq-iosched.c63
-rw-r--r--block/compat_ioctl.c13
-rw-r--r--block/genhd.c4
-rw-r--r--block/ioctl.c17
-rw-r--r--drivers/acpi/Kconfig12
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/acpi_pad.c514
-rw-r--r--drivers/acpi/dock.c16
-rw-r--r--drivers/acpi/ec.c56
-rw-r--r--drivers/acpi/proc.c2
-rw-r--r--drivers/acpi/processor_core.c7
-rw-r--r--drivers/acpi/scan.c7
-rw-r--r--drivers/acpi/video.c2
-rw-r--r--drivers/ata/ahci.c198
-rw-r--r--drivers/ata/libata-acpi.c40
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--drivers/ata/libata-eh.c50
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_ali.c2
-rw-r--r--drivers/ata/pata_atp867x.c101
-rw-r--r--drivers/atm/ambassador.c8
-rw-r--r--drivers/atm/eni.c2
-rw-r--r--drivers/atm/firestream.c2
-rw-r--r--drivers/atm/fore200e.c2
-rw-r--r--drivers/atm/horizon.c2
-rw-r--r--drivers/atm/iphase.c2
-rw-r--r--drivers/atm/zatm.c2
-rw-r--r--drivers/block/DAC960.c156
-rw-r--r--drivers/block/cciss.c755
-rw-r--r--drivers/block/cciss.h12
-rw-r--r--drivers/block/cpqarray.c63
-rw-r--r--drivers/char/agp/parisc-agp.c2
-rw-r--r--drivers/char/apm-emulation.c2
-rw-r--r--drivers/char/bfin-otp.c2
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/dtlk.c1
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c1
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c1
-rw-r--r--drivers/char/serial167.c7
-rw-r--r--drivers/char/tpm/tpm.c3
-rw-r--r--drivers/char/tty_ldisc.c7
-rw-r--r--drivers/char/vt_ioctl.c6
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c2
-rw-r--r--drivers/connector/cn_proc.c3
-rw-r--r--drivers/connector/cn_queue.c12
-rw-r--r--drivers/connector/connector.c22
-rw-r--r--drivers/edac/Kconfig14
-rw-r--r--drivers/edac/Makefile5
-rw-r--r--drivers/edac/amd64_edac.c104
-rw-r--r--drivers/edac/amd64_edac.h23
-rw-r--r--drivers/edac/amd64_edac_inj.c49
-rw-r--r--drivers/edac/edac_mce_amd.c32
-rw-r--r--drivers/firewire/core-cdev.c1
-rw-r--r--drivers/firmware/iscsi_ibft.c2
-rw-r--r--drivers/firmware/iscsi_ibft_find.c4
-rw-r--r--drivers/gpio/gpiolib.c2
-rw-r--r--drivers/gpu/drm/drm_crtc.c2
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c138
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c1
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c10
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c10
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h49
-rw-r--r--drivers/gpu/drm/i915/intel_display.c15
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c10
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c2
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c3
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/r100.c432
-rw-r--r--drivers/gpu/drm/radeon/r100d.h145
-rw-r--r--drivers/gpu/drm/radeon/r200.c3
-rw-r--r--drivers/gpu/drm/radeon/r300.c308
-rw-r--r--drivers/gpu/drm/radeon/r300d.h205
-rw-r--r--drivers/gpu/drm/radeon/r420.c6
-rw-r--r--drivers/gpu/drm/radeon/r420d.h24
-rw-r--r--drivers/gpu/drm/radeon/r520.c3
-rw-r--r--drivers/gpu/drm/radeon/r600.c314
-rw-r--r--drivers/gpu/drm/radeon/r600_blit.c10
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c3
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c2
-rw-r--r--drivers/gpu/drm/radeon/r600d.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h58
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h253
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c49
-rw-r--r--drivers/gpu/drm/radeon/radeon_clocks.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c237
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c45
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c17
-rw-r--r--drivers/gpu/drm/radeon/rs100d.h40
-rw-r--r--drivers/gpu/drm/radeon/rs400.c275
-rw-r--r--drivers/gpu/drm/radeon/rs400d.h160
-rw-r--r--drivers/gpu/drm/radeon/rs600.c481
-rw-r--r--drivers/gpu/drm/radeon/rs600d.h470
-rw-r--r--drivers/gpu/drm/radeon/rs690.c355
-rw-r--r--drivers/gpu/drm/radeon/rs690d.h307
-rw-r--r--drivers/gpu/drm/radeon/rs690r.h99
-rw-r--r--drivers/gpu/drm/radeon/rv200d.h36
-rw-r--r--drivers/gpu/drm/radeon/rv250d.h123
-rw-r--r--drivers/gpu/drm/radeon/rv350d.h52
-rw-r--r--drivers/gpu/drm/radeon/rv515.c5
-rw-r--r--drivers/gpu/drm/radeon/rv770.c199
-rw-r--r--drivers/gpu/drm/ttm/ttm_global.c2
-rw-r--r--drivers/hid/hidraw.c1
-rw-r--r--drivers/hwmon/fschmd.c2
-rw-r--r--drivers/hwmon/lis3lv02d_spi.c3
-rw-r--r--drivers/hwmon/ltc4215.c47
-rw-r--r--drivers/hwmon/ltc4245.c131
-rw-r--r--drivers/i2c/busses/i2c-amd756.c2
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c4
-rw-r--r--drivers/i2c/busses/i2c-i801.c4
-rw-r--r--drivers/i2c/busses/i2c-isch.c2
-rw-r--r--drivers/i2c/busses/i2c-piix4.c4
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c2
-rw-r--r--drivers/i2c/busses/i2c-viapro.c2
-rw-r--r--drivers/ide/ide-proc.c8
-rw-r--r--drivers/ide/sis5513.c10
-rw-r--r--drivers/infiniband/core/addr.c2
-rw-r--r--drivers/infiniband/core/iwcm.c2
-rw-r--r--drivers/infiniband/core/ucm.c1
-rw-r--r--drivers/infiniband/core/user_mad.c1
-rw-r--r--drivers/infiniband/core/uverbs_main.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c11
-rw-r--r--drivers/input/evdev.c1
-rw-r--r--drivers/input/input.c3
-rw-r--r--drivers/input/joydev.c1
-rw-r--r--drivers/input/joystick/xpad.c2
-rw-r--r--drivers/input/misc/rotary_encoder.c4
-rw-r--r--drivers/input/misc/sparcspkr.c4
-rw-r--r--drivers/input/misc/uinput.c1
-rw-r--r--drivers/input/misc/wistron_btns.c9
-rw-r--r--drivers/input/mousedev.c1
-rw-r--r--drivers/input/serio/Kconfig13
-rw-r--r--drivers/input/serio/i8042.c3
-rw-r--r--drivers/input/touchscreen/ad7879.c4
-rw-r--r--drivers/isdn/capi/capi.c2
-rw-r--r--drivers/isdn/capi/capidrv.c27
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/gigaset/asyncdata.c28
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c87
-rw-r--r--drivers/isdn/gigaset/common.c134
-rw-r--r--drivers/isdn/gigaset/ev-layer.c30
-rw-r--r--drivers/isdn/gigaset/i4l.c23
-rw-r--r--drivers/isdn/gigaset/interface.c9
-rw-r--r--drivers/isdn/gigaset/isocdata.c30
-rw-r--r--drivers/isdn/mISDN/socket.c2
-rw-r--r--drivers/leds/leds-pca9532.c3
-rw-r--r--drivers/lguest/lguest_user.c2
-rw-r--r--drivers/macintosh/therm_adt746x.c4
-rw-r--r--drivers/macintosh/therm_pm72.c4
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c4
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c4
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c4
-rw-r--r--drivers/md/dm-log-userspace-transfer.c6
-rw-r--r--drivers/md/dm.c16
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c1
-rw-r--r--drivers/media/dvb/firewire/firedtv-ci.c2
-rw-r--r--drivers/media/radio/radio-cadet.c1
-rw-r--r--drivers/media/video/cpia.c1
-rw-r--r--drivers/mfd/ab3100-core.c4
-rw-r--r--drivers/mfd/ucb1400_core.c1
-rw-r--r--drivers/misc/eeprom/max6875.c29
-rw-r--r--drivers/misc/phantom.c2
-rw-r--r--drivers/misc/sgi-gru/grufile.c3
-rw-r--r--drivers/mmc/core/debugfs.c2
-rw-r--r--drivers/mmc/core/sdio_cis.c72
-rw-r--r--drivers/mmc/host/Kconfig41
-rw-r--r--drivers/mmc/host/mmci.c2
-rw-r--r--drivers/mmc/host/s3cmci.c608
-rw-r--r--drivers/mmc/host/s3cmci.h14
-rw-r--r--drivers/mtd/mtd_blkdevs.c19
-rw-r--r--drivers/net/3c59x.c77
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/au1000_eth.c4
-rw-r--r--drivers/net/bcm63xx_enet.c2
-rw-r--r--drivers/net/benet/be.h1
-rw-r--r--drivers/net/benet/be_cmds.c4
-rw-r--r--drivers/net/benet/be_cmds.h5
-rw-r--r--drivers/net/benet/be_ethtool.c2
-rw-r--r--drivers/net/benet/be_main.c29
-rw-r--r--drivers/net/bonding/bond_sysfs.c1
-rw-r--r--drivers/net/cnic.c3
-rw-r--r--drivers/net/cnic_if.h4
-rw-r--r--drivers/net/e1000e/82571.c4
-rw-r--r--drivers/net/e1000e/netdev.c13
-rw-r--r--drivers/net/ethoc.c81
-rw-r--r--drivers/net/hamradio/mkiss.c4
-rw-r--r--drivers/net/igb/igb_main.c13
-rw-r--r--drivers/net/iseries_veth.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c232
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c4
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c56
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h11
-rw-r--r--drivers/net/ks8851_mll.c1697
-rw-r--r--drivers/net/meth.c2
-rw-r--r--drivers/net/mlx4/main.c1
-rw-r--r--drivers/net/netxen/netxen_nic_main.c2
-rw-r--r--drivers/net/pasemi_mac_ethtool.c3
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c10
-rw-r--r--drivers/net/pppol2tp.c2
-rw-r--r--drivers/net/qlge/qlge.h26
-rw-r--r--drivers/net/qlge/qlge_ethtool.c2
-rw-r--r--drivers/net/qlge/qlge_main.c44
-rw-r--r--drivers/net/qlge/qlge_mpi.c12
-rw-r--r--drivers/net/sgiseeq.c2
-rw-r--r--drivers/net/skge.c16
-rw-r--r--drivers/net/skge.h2
-rw-r--r--drivers/net/sky2.c7
-rw-r--r--drivers/net/sky2.h2
-rw-r--r--drivers/net/tg3.c41
-rw-r--r--drivers/net/tg3.h2
-rw-r--r--drivers/net/usb/rndis_host.c1
-rw-r--r--drivers/net/virtio_net.c2
-rw-r--r--drivers/net/wireless/Kconfig13
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c6
-rw-r--r--drivers/net/wireless/b43/pio.c60
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/pcmcia/sa1100_assabet.c2
-rw-r--r--drivers/pcmcia/sa1100_neponset.c2
-rw-r--r--drivers/platform/x86/sony-laptop.c127
-rw-r--r--drivers/s390/cio/qdio_debug.c2
-rw-r--r--drivers/s390/cio/qdio_perf.c2
-rw-r--r--drivers/scsi/sg.c43
-rw-r--r--drivers/serial/8250.c7
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/icom.c54
-rw-r--r--drivers/serial/sa1100.c2
-rw-r--r--drivers/serial/serial_cs.c12
-rw-r--r--drivers/serial/serial_txx9.c39
-rw-r--r--drivers/sfi/sfi_core.c17
-rw-r--r--drivers/spi/Makefile2
-rw-r--r--drivers/spi/spi_imx.c (renamed from drivers/spi/mxc_spi.c)383
-rw-r--r--drivers/spi/spidev.c2
-rw-r--r--drivers/staging/dst/dcore.c9
-rw-r--r--drivers/staging/iio/light/tsl2561.c4
-rw-r--r--drivers/staging/pohmelfs/config.c5
-rw-r--r--drivers/usb/class/usbtmc.c2
-rw-r--r--drivers/usb/gadget/inode.c1
-rw-r--r--drivers/usb/gadget/printer.c2
-rw-r--r--drivers/usb/gadget/r8a66597-udc.h105
-rw-r--r--drivers/usb/host/whci/debug.c6
-rw-r--r--drivers/usb/misc/rio500.c3
-rw-r--r--drivers/uwb/uwb-debug.c6
-rw-r--r--drivers/video/da8xx-fb.c1
-rw-r--r--drivers/video/msm/mddi.c2
-rw-r--r--drivers/video/omap/blizzard.c10
-rw-r--r--drivers/video/omap/omapfb_main.c22
-rw-r--r--drivers/video/uvesafb.c5
-rw-r--r--drivers/w1/masters/ds2482.c35
-rw-r--r--drivers/w1/w1_netlink.c2
-rw-r--r--drivers/xen/xenfs/xenbus.c1
-rw-r--r--firmware/Makefile7
-rw-r--r--firmware/WHENCE5
-rw-r--r--firmware/cis/COMpad2.cis.ihex11
-rw-r--r--firmware/cis/COMpad4.cis.ihex9
-rw-r--r--firmware/cis/DP83903.cis.ihex14
-rw-r--r--firmware/cis/NE2K.cis.ihex8
-rw-r--r--firmware/cis/tamarack.cis.ihex10
-rw-r--r--fs/afs/cache.h12
-rw-r--r--fs/afs/internal.h2
-rw-r--r--fs/anon_inodes.c2
-rw-r--r--fs/bio.c49
-rw-r--r--fs/btrfs/acl.c6
-rw-r--r--fs/btrfs/btrfs_inode.h8
-rw-r--r--fs/btrfs/ctree.h27
-rw-r--r--fs/btrfs/disk-io.c10
-rw-r--r--fs/btrfs/extent-tree.c391
-rw-r--r--fs/btrfs/extent_io.c92
-rw-r--r--fs/btrfs/extent_io.h13
-rw-r--r--fs/btrfs/file.c35
-rw-r--r--fs/btrfs/inode.c239
-rw-r--r--fs/btrfs/ioctl.c62
-rw-r--r--fs/btrfs/ordered-data.c93
-rw-r--r--fs/btrfs/ordered-data.h4
-rw-r--r--fs/btrfs/super.c2
-rw-r--r--fs/btrfs/transaction.c10
-rw-r--r--fs/btrfs/volumes.c4
-rw-r--r--fs/btrfs/xattr.c2
-rw-r--r--fs/coda/psdev.c1
-rw-r--r--fs/ecryptfs/Kconfig3
-rw-r--r--fs/ecryptfs/main.c7
-rw-r--r--fs/ext4/Kconfig14
-rw-r--r--fs/ext4/inode.c28
-rw-r--r--fs/ext4/super.c31
-rw-r--r--fs/jbd2/journal.c2
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/nfs4namespace.c12
-rw-r--r--fs/nfs/nfs4renewd.c6
-rw-r--r--fs/nfs/super.c36
-rw-r--r--fs/nfsd/nfsctl.c2
-rw-r--r--fs/nilfs2/dir.c2
-rw-r--r--fs/nilfs2/file.c2
-rw-r--r--fs/nilfs2/mdt.c2
-rw-r--r--fs/nilfs2/nilfs.h4
-rw-r--r--fs/ocfs2/cluster/heartbeat.c2
-rw-r--r--fs/ocfs2/cluster/netdebug.c4
-rw-r--r--fs/ocfs2/dlm/dlmdebug.c8
-rw-r--r--fs/ocfs2/super.c2
-rw-r--r--fs/omfs/dir.c2
-rw-r--r--fs/omfs/file.c2
-rw-r--r--fs/omfs/omfs.h4
-rw-r--r--fs/partitions/check.c12
-rw-r--r--fs/proc/kcore.c1
-rw-r--r--fs/proc/page.c5
-rw-r--r--fs/select.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c38
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c41
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c59
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c36
-rw-r--r--fs/xfs/xfs_dfrag.c8
-rw-r--r--fs/xfs/xfs_dir2_leaf.c4
-rw-r--r--fs/xfs/xfs_inode.c4
-rw-r--r--fs/xfs/xfs_inode.h2
-rw-r--r--fs/xfs/xfs_inode_item.c18
-rw-r--r--fs/xfs/xfs_itable.c21
-rw-r--r--fs/xfs/xfs_vnodeops.c6
-rw-r--r--include/asm-generic/gpio.h1
-rw-r--r--include/asm-generic/hardirq.h2
-rw-r--r--include/drm/drm_crtc_helper.h3
-rw-r--r--include/drm/drm_fb_helper.h7
-rw-r--r--include/drm/drm_pciids.h4
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/ata.h9
-rw-r--r--include/linux/atmdev.h2
-rw-r--r--include/linux/blkdev.h48
-rw-r--r--include/linux/blktrace_api.h2
-rw-r--r--include/linux/cgroup.h2
-rw-r--r--include/linux/connector.h11
-rw-r--r--include/linux/fs.h6
-rw-r--r--include/linux/ftrace.h2
-rw-r--r--include/linux/futex.h4
-rw-r--r--include/linux/genhd.h21
-rw-r--r--include/linux/i2c/twl4030.h6
-rw-r--r--include/linux/init.h1
-rw-r--r--include/linux/libata.h12
-rw-r--r--include/linux/mroute.h4
-rw-r--r--include/linux/mroute6.h4
-rw-r--r--include/linux/net.h8
-rw-r--r--include/linux/netfilter.h4
-rw-r--r--include/linux/perf_event.h5
-rw-r--r--include/linux/poll.h2
-rw-r--r--include/linux/rcupdate.h18
-rw-r--r--include/linux/rcutree.h13
-rw-r--r--include/linux/res_counter.h6
-rw-r--r--include/linux/socket.h21
-rw-r--r--include/net/compat.h4
-rw-r--r--include/net/inet_connection_sock.h6
-rw-r--r--include/net/ip.h4
-rw-r--r--include/net/ipv6.h4
-rw-r--r--include/net/sctp/structs.h4
-rw-r--r--include/net/sock.h12
-rw-r--r--include/net/tcp.h4
-rw-r--r--include/net/udp.h2
-rw-r--r--include/trace/events/block.h33
-rw-r--r--init/Kconfig18
-rw-r--r--init/main.c1
-rw-r--r--kernel/cgroup.c15
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/fork.c10
-rw-r--r--kernel/futex.c3
-rw-r--r--kernel/hrtimer.c2
-rw-r--r--kernel/kprobes.c4
-rw-r--r--kernel/module.c7
-rw-r--r--kernel/panic.c3
-rw-r--r--kernel/perf_event.c282
-rw-r--r--kernel/rcupdate.c140
-rw-r--r--kernel/rcutorture.c4
-rw-r--r--kernel/rcutree.c330
-rw-r--r--kernel/rcutree.h86
-rw-r--r--kernel/rcutree_plugin.h103
-rw-r--r--kernel/rcutree_trace.c14
-rw-r--r--kernel/res_counter.c18
-rw-r--r--kernel/sched.c22
-rw-r--r--kernel/sched_clock.c4
-rw-r--r--kernel/time/tick-sched.c9
-rw-r--r--kernel/time/timer_list.c2
-rw-r--r--kernel/time/timer_stats.c2
-rw-r--r--kernel/trace/blktrace.c39
-rw-r--r--kernel/trace/ftrace.c27
-rw-r--r--kernel/trace/kmemtrace.c2
-rw-r--r--kernel/trace/trace_branch.c8
-rw-r--r--kernel/trace/trace_event_profile.c15
-rw-r--r--kernel/trace/trace_hw_branches.c8
-rw-r--r--kernel/trace/trace_output.c18
-rw-r--r--kernel/trace/trace_syscalls.c4
-rw-r--r--lib/vsprintf.c2
-rw-r--r--mm/Kconfig4
-rw-r--r--mm/kmemleak.c5
-rw-r--r--mm/ksm.c10
-rw-r--r--mm/memcontrol.c127
-rw-r--r--mm/rmap.c4
-rw-r--r--mm/swapfile.c12
-rw-r--r--mm/vmalloc.c49
-rw-r--r--net/atm/common.c2
-rw-r--r--net/atm/common.h2
-rw-r--r--net/atm/pvc.c2
-rw-r--r--net/atm/svc.c2
-rw-r--r--net/ax25/af_ax25.c4
-rw-r--r--net/bluetooth/hci_sock.c2
-rw-r--r--net/bluetooth/l2cap.c4
-rw-r--r--net/bluetooth/rfcomm/sock.c4
-rw-r--r--net/bluetooth/sco.c2
-rw-r--r--net/can/raw.c2
-rw-r--r--net/compat.c12
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/net-sysfs.c4
-rw-r--r--net/core/pktgen.c10
-rw-r--r--net/core/sock.c27
-rw-r--r--net/dccp/dccp.h4
-rw-r--r--net/dccp/proto.c10
-rw-r--r--net/decnet/af_decnet.c6
-rw-r--r--net/ieee802154/dgram.c2
-rw-r--r--net/ieee802154/raw.c2
-rw-r--r--net/ipv4/af_inet.c1
-rw-r--r--net/ipv4/devinet.c16
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/ip_output.c1
-rw-r--r--net/ipv4/ip_sockglue.c6
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv4/raw.c6
-rw-r--r--net/ipv4/tcp.c10
-rw-r--r--net/ipv4/tcp_output.c11
-rw-r--r--net/ipv4/udp.c7
-rw-r--r--net/ipv4/udp_impl.h4
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/ipv6_sockglue.c6
-rw-r--r--net/ipv6/raw.c6
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/ipv6/udp.c4
-rw-r--r--net/ipv6/udp_impl.h4
-rw-r--r--net/ipx/af_ipx.c2
-rw-r--r--net/irda/af_irda.c2
-rw-r--r--net/iucv/af_iucv.c2
-rw-r--r--net/llc/af_llc.c2
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/netfilter/nf_sockopt.c4
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/netrom/af_netrom.c2
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/phonet/pep.c2
-rw-r--r--net/phonet/socket.c1
-rw-r--r--net/rds/af_rds.c2
-rw-r--r--net/rfkill/core.c1
-rw-r--r--net/rose/af_rose.c2
-rw-r--r--net/rxrpc/af_rxrpc.c2
-rw-r--r--net/sctp/socket.c62
-rw-r--r--net/socket.c2
-rw-r--r--net/tipc/socket.c2
-rw-r--r--net/x25/af_x25.c2
-rw-r--r--samples/tracepoints/tracepoint-sample.c2
-rw-r--r--security/integrity/ima/ima_fs.c10
-rw-r--r--sound/aoa/codecs/tas.c9
-rw-r--r--sound/drivers/opl3/opl3_midi.c28
-rw-r--r--sound/mips/hal2.c2
-rw-r--r--sound/mips/sgio2audio.c2
-rw-r--r--sound/pci/ctxfi/ctatc.c4
-rw-r--r--sound/pci/echoaudio/echoaudio.c30
-rw-r--r--sound/pci/echoaudio/mia.c1
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/hda/patch_analog.c139
-rw-r--r--sound/pci/hda/patch_conexant.c12
-rw-r--r--sound/pci/hda/patch_realtek.c333
-rw-r--r--sound/pci/hda/patch_sigmatel.c20
-rw-r--r--sound/pci/ice1712/ice1712.c2
-rw-r--r--sound/pci/ice1712/ice1724.c6
-rw-r--r--sound/pci/intel8x0.c12
-rw-r--r--sound/pci/via82xx.c27
-rw-r--r--sound/ppc/keywest.c14
-rw-r--r--sound/soc/blackfin/Kconfig98
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c8
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c8
-rw-r--r--sound/soc/codecs/wm8350.c4
-rw-r--r--sound/soc/codecs/wm8940.c2
-rw-r--r--sound/soc/davinci/davinci-i2s.c37
-rw-r--r--sound/soc/davinci/davinci-mcasp.c80
-rw-r--r--sound/soc/davinci/davinci-mcasp.h7
-rw-r--r--sound/soc/davinci/davinci-pcm.c13
-rw-r--r--sound/soc/davinci/davinci-pcm.h1
-rw-r--r--sound/soc/imx/mxc-ssi.c8
-rw-r--r--sound/soc/pxa/Kconfig2
-rw-r--r--sound/soc/soc-dapm.c5
-rw-r--r--sound/usb/usbmixer.c23
-rw-r--r--tools/perf/Documentation/perf-timechart.txt3
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/builtin-record.c6
-rw-r--r--tools/perf/builtin-stat.c8
-rw-r--r--tools/perf/builtin-timechart.c10
-rw-r--r--tools/perf/builtin-top.c1
-rw-r--r--tools/perf/builtin-trace.c6
-rw-r--r--tools/perf/design.txt3
-rw-r--r--tools/perf/util/svghelper.c14
-rw-r--r--tools/perf/util/symbol.c3
-rw-r--r--tools/perf/util/trace-event-parse.c9
-rw-r--r--virt/kvm/kvm_main.c16
938 files changed, 15467 insertions, 10966 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
index 0a92a7c93a6..4f29e5f1ebf 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
+++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
@@ -31,3 +31,31 @@ Date: March 2009
Kernel Version: 2.6.30
Contact: iss_storagedev@hp.com
Description: A symbolic link to /sys/block/cciss!cXdY
+
+Where: /sys/bus/pci/devices/<dev>/ccissX/rescan
+Date: August 2009
+Kernel Version: 2.6.31
+Contact: iss_storagedev@hp.com
+Description: Kicks of a rescan of the controller to discover logical
+ drive topology changes.
+
+Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/lunid
+Date: August 2009
+Kernel Version: 2.6.31
+Contact: iss_storagedev@hp.com
+Description: Displays the 8-byte LUN ID used to address logical
+ drive Y of controller X.
+
+Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/raid_level
+Date: August 2009
+Kernel Version: 2.6.31
+Contact: iss_storagedev@hp.com
+Description: Displays the RAID level of logical drive Y of
+ controller X.
+
+Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/usage_count
+Date: August 2009
+Kernel Version: 2.6.31
+Contact: iss_storagedev@hp.com
+Description: Displays the usage count (number of opens) of logical drive Y
+ of controller X.
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index b7f9d3b4bbf..72651f788f4 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -232,7 +232,7 @@ your e-mail client so that it sends your patches untouched.
When sending patches to Linus, always follow step #7.
Large changes are not appropriate for mailing lists, and some
-maintainers. If your patch, uncompressed, exceeds 40 kB in size,
+maintainers. If your patch, uncompressed, exceeds 300 kB in size,
it is preferred that you store your patch on an Internet-accessible
server, and provide instead a URL (link) pointing to your patch.
diff --git a/Documentation/arm/tcm.txt b/Documentation/arm/tcm.txt
index 074f4be6667..77fd9376e6d 100644
--- a/Documentation/arm/tcm.txt
+++ b/Documentation/arm/tcm.txt
@@ -29,11 +29,13 @@ TCM location and size. Notice that this is not a MMU table: you
actually move the physical location of the TCM around. At the
place you put it, it will mask any underlying RAM from the
CPU so it is usually wise not to overlap any physical RAM with
-the TCM. The TCM memory exists totally outside the MMU and will
-override any MMU mappings.
+the TCM.
-Code executing inside the ITCM does not "see" any MMU mappings
-and e.g. register accesses must be made to physical addresses.
+The TCM memory can then be remapped to another address again using
+the MMU, but notice that the TCM if often used in situations where
+the MMU is turned off. To avoid confusion the current Linux
+implementation will map the TCM 1 to 1 from physical to virtual
+memory in the location specified by the machine.
TCM is used for a few things:
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
index 455d4e6d346..0b33bfe7dde 100644
--- a/Documentation/cgroups/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
@@ -227,7 +227,14 @@ as the path relative to the root of the cgroup file system.
Each cgroup is represented by a directory in the cgroup file system
containing the following files describing that cgroup:
- - tasks: list of tasks (by pid) attached to that cgroup
+ - tasks: list of tasks (by pid) attached to that cgroup. This list
+ is not guaranteed to be sorted. Writing a thread id into this file
+ moves the thread into this cgroup.
+ - cgroup.procs: list of tgids in the cgroup. This list is not
+ guaranteed to be sorted or free of duplicate tgids, and userspace
+ should sort/uniquify the list if this property is required.
+ Writing a tgid into this file moves all threads with that tgid into
+ this cgroup.
- notify_on_release flag: run the release agent on exit?
- release_agent: the path to use for release notifications (this file
exists in the top cgroup only)
@@ -374,7 +381,7 @@ Now you want to do something with this cgroup.
In this directory you can find several files:
# ls
-notify_on_release tasks
+cgroup.procs notify_on_release tasks
(plus whatever files added by the attached subsystems)
Now attach your shell to this cgroup:
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
index 1711adc3337..b07add3467f 100644
--- a/Documentation/connector/cn_test.c
+++ b/Documentation/connector/cn_test.c
@@ -34,7 +34,7 @@ static char cn_test_name[] = "cn_test";
static struct sock *nls;
static struct timer_list cn_test_timer;
-static void cn_test_callback(struct cn_msg *msg)
+static void cn_test_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
pr_info("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n",
__func__, jiffies, msg->id.idx, msg->id.val,
diff --git a/Documentation/connector/connector.txt b/Documentation/connector/connector.txt
index 81e6bf6ead5..78c9466a9aa 100644
--- a/Documentation/connector/connector.txt
+++ b/Documentation/connector/connector.txt
@@ -23,7 +23,7 @@ handling, etc... The Connector driver allows any kernelspace agents to use
netlink based networking for inter-process communication in a significantly
easier way:
-int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
+int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask);
struct cb_id
@@ -53,15 +53,15 @@ struct cn_msg
Connector interfaces.
/*****************************************/
-int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
+int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
Registers new callback with connector core.
struct cb_id *id - unique connector's user identifier.
It must be registered in connector.h for legal in-kernel users.
char *name - connector's callback symbolic name.
- void (*callback) (void *) - connector's callback.
- Argument must be dereferenced to struct cn_msg *.
+ void (*callback) (struct cn..) - connector's callback.
+ cn_msg and the sender's credentials
void cn_del_callback(struct cb_id *id);
diff --git a/Documentation/hwmon/ltc4215 b/Documentation/hwmon/ltc4215
index 2e6a21eb656..c196a184625 100644
--- a/Documentation/hwmon/ltc4215
+++ b/Documentation/hwmon/ltc4215
@@ -22,12 +22,13 @@ Usage Notes
-----------
This driver does not probe for LTC4215 devices, due to the fact that some
-of the possible addresses are unfriendly to probing. You will need to use
-the "force" parameter to tell the driver where to find the device.
+of the possible addresses are unfriendly to probing. You will have to
+instantiate the devices explicitly.
Example: the following will load the driver for an LTC4215 at address 0x44
on I2C bus #0:
-$ modprobe ltc4215 force=0,0x44
+$ modprobe ltc4215
+$ echo ltc4215 0x44 > /sys/bus/i2c/devices/i2c-0/new_device
Sysfs entries
diff --git a/Documentation/hwmon/ltc4245 b/Documentation/hwmon/ltc4245
index bae7a3adc5d..02838a47d86 100644
--- a/Documentation/hwmon/ltc4245
+++ b/Documentation/hwmon/ltc4245
@@ -23,12 +23,13 @@ Usage Notes
-----------
This driver does not probe for LTC4245 devices, due to the fact that some
-of the possible addresses are unfriendly to probing. You will need to use
-the "force" parameter to tell the driver where to find the device.
+of the possible addresses are unfriendly to probing. You will have to
+instantiate the devices explicitly.
Example: the following will load the driver for an LTC4245 at address 0x23
on I2C bus #1:
-$ modprobe ltc4245 force=1,0x23
+$ modprobe ltc4245
+$ echo ltc4245 0x23 > /sys/bus/i2c/devices/i2c-1/new_device
Sysfs entries
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices
index c740b7b4108..e89490270ab 100644
--- a/Documentation/i2c/instantiating-devices
+++ b/Documentation/i2c/instantiating-devices
@@ -188,7 +188,7 @@ segment, the address is sufficient to uniquely identify the device to be
deleted.
Example:
-# echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device
+# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device
While this interface should only be used when in-kernel device declaration
can't be done, there is a variety of cases where it can be helpful:
diff --git a/Documentation/infiniband/user_mad.txt b/Documentation/infiniband/user_mad.txt
index 744687dd195..8a366959f5c 100644
--- a/Documentation/infiniband/user_mad.txt
+++ b/Documentation/infiniband/user_mad.txt
@@ -128,8 +128,8 @@ Setting IsSM Capability Bit
To create the appropriate character device files automatically with
udev, a rule like
- KERNEL="umad*", NAME="infiniband/%k"
- KERNEL="issm*", NAME="infiniband/%k"
+ KERNEL=="umad*", NAME="infiniband/%k"
+ KERNEL=="issm*", NAME="infiniband/%k"
can be used. This will create device nodes named
diff --git a/Documentation/infiniband/user_verbs.txt b/Documentation/infiniband/user_verbs.txt
index f847501e50b..afe3f8da901 100644
--- a/Documentation/infiniband/user_verbs.txt
+++ b/Documentation/infiniband/user_verbs.txt
@@ -58,7 +58,7 @@ Memory pinning
To create the appropriate character device files automatically with
udev, a rule like
- KERNEL="uverbs*", NAME="infiniband/%k"
+ KERNEL=="uverbs*", NAME="infiniband/%k"
can be used. This will create device nodes named
diff --git a/Documentation/isdn/INTERFACE.CAPI b/Documentation/isdn/INTERFACE.CAPI
index 686e107923e..5fe8de5cc72 100644
--- a/Documentation/isdn/INTERFACE.CAPI
+++ b/Documentation/isdn/INTERFACE.CAPI
@@ -60,10 +60,9 @@ open() operation on regular files or character devices.
After a successful return from register_appl(), CAPI messages from the
application may be passed to the driver for the device via calls to the
-send_message() callback function. The CAPI message to send is stored in the
-data portion of an skb. Conversely, the driver may call Kernel CAPI's
-capi_ctr_handle_message() function to pass a received CAPI message to Kernel
-CAPI for forwarding to an application, specifying its ApplID.
+send_message() callback function. Conversely, the driver may call Kernel
+CAPI's capi_ctr_handle_message() function to pass a received CAPI message to
+Kernel CAPI for forwarding to an application, specifying its ApplID.
Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
forwarded as calls to the release_appl() callback function, passing the same
@@ -142,6 +141,7 @@ u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
to accepting or queueing the message. Errors occurring during the
actual processing of the message should be signaled with an
appropriate reply message.
+ May be called in process or interrupt context.
Calls to this function are not serialized by Kernel CAPI, ie. it must
be prepared to be re-entered.
@@ -154,7 +154,8 @@ read_proc_t *ctr_read_proc
system entry, /proc/capi/controllers/<n>; will be called with a
pointer to the device's capi_ctr structure as the last (data) argument
-Note: Callback functions are never called in interrupt context.
+Note: Callback functions except send_message() are never called in interrupt
+context.
- to be filled in before calling capi_ctr_ready():
@@ -171,14 +172,40 @@ u8 serial[CAPI_SERIAL_LEN]
value to return for CAPI_GET_SERIAL
-4.3 The _cmsg Structure
+4.3 SKBs
+
+CAPI messages are passed between Kernel CAPI and the driver via send_message()
+and capi_ctr_handle_message(), stored in the data portion of a socket buffer
+(skb). Each skb contains a single CAPI message coded according to the CAPI 2.0
+standard.
+
+For the data transfer messages, DATA_B3_REQ and DATA_B3_IND, the actual
+payload data immediately follows the CAPI message itself within the same skb.
+The Data and Data64 parameters are not used for processing. The Data64
+parameter may be omitted by setting the length field of the CAPI message to 22
+instead of 30.
+
+
+4.4 The _cmsg Structure
(declared in <linux/isdn/capiutil.h>)
The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
-accessible form. It contains members for all possible CAPI 2.0 parameters, of
-which only those appearing in the message type currently being processed are
-actually used. Unused members should be set to zero.
+accessible form. It contains members for all possible CAPI 2.0 parameters,
+including subparameters of the Additional Info and B Protocol structured
+parameters, with the following exceptions:
+
+* second Calling party number (CONNECT_IND)
+
+* Data64 (DATA_B3_REQ and DATA_B3_IND)
+
+* Sending complete (subparameter of Additional Info, CONNECT_REQ and INFO_REQ)
+
+* Global Configuration (subparameter of B Protocol, CONNECT_REQ, CONNECT_RESP
+ and SELECT_B_PROTOCOL_REQ)
+
+Only those parameters appearing in the message type currently being processed
+are actually used. Unused members should be set to zero.
Members are named after the CAPI 2.0 standard names of the parameters they
represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
@@ -190,18 +217,19 @@ u16 for CAPI parameters of type 'word'
u32 for CAPI parameters of type 'dword'
-_cstruct for CAPI parameters of type 'struct' not containing any
- variably-sized (struct) subparameters (eg. 'Called Party Number')
+_cstruct for CAPI parameters of type 'struct'
The member is a pointer to a buffer containing the parameter in
CAPI encoding (length + content). It may also be NULL, which will
be taken to represent an empty (zero length) parameter.
+ Subparameters are stored in encoded form within the content part.
-_cmstruct for CAPI parameters of type 'struct' containing 'struct'
- subparameters ('Additional Info' and 'B Protocol')
+_cmstruct alternative representation for CAPI parameters of type 'struct'
+ (used only for the 'Additional Info' and 'B Protocol' parameters)
The representation is a single byte containing one of the values:
- CAPI_DEFAULT: the parameter is empty
- CAPI_COMPOSE: the values of the subparameters are stored
- individually in the corresponding _cmsg structure members
+ CAPI_DEFAULT: The parameter is empty/absent.
+ CAPI_COMPOSE: The parameter is present.
+ Subparameter values are stored individually in the corresponding
+ _cmsg structure members.
Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert
messages between their transport encoding described in the CAPI 2.0 standard
@@ -297,3 +325,26 @@ char *capi_cmd2str(u8 Command, u8 Subcommand)
be NULL if the command/subcommand is not one of those defined in the
CAPI 2.0 standard.
+
+7. Debugging
+
+The module kernelcapi has a module parameter showcapimsgs controlling some
+debugging output produced by the module. It can only be set when the module is
+loaded, via a parameter "showcapimsgs=<n>" to the modprobe command, either on
+the command line or in the configuration file.
+
+If the lowest bit of showcapimsgs is set, kernelcapi logs controller and
+application up and down events.
+
+In addition, every registered CAPI controller has an associated traceflag
+parameter controlling how CAPI messages sent from and to tha controller are
+logged. The traceflag parameter is initialized with the value of the
+showcapimsgs parameter when the controller is registered, but can later be
+changed via the MANUFACTURER_REQ command KCAPI_CMD_TRACE.
+
+If the value of traceflag is non-zero, CAPI messages are logged.
+DATA_B3 messages are only logged if the value of traceflag is > 2.
+
+If the lowest bit of traceflag is set, only the command/subcommand and message
+length are logged. Otherwise, kernelcapi logs a readable representation of
+the entire message.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 6fa7292947e..9107b387e91 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -671,6 +671,7 @@ and is between 256 and 4096 characters. It is defined in the file
earlyprintk= [X86,SH,BLACKFIN]
earlyprintk=vga
earlyprintk=serial[,ttySn[,baudrate]]
+ earlyprintk=ttySn[,baudrate]
earlyprintk=dbgp[debugController#]
Append ",keep" to not disable it when the real console
diff --git a/Documentation/i2c/chips/eeprom b/Documentation/misc-devices/eeprom
index f7e8104b576..f7e8104b576 100644
--- a/Documentation/i2c/chips/eeprom
+++ b/Documentation/misc-devices/eeprom
diff --git a/Documentation/i2c/chips/max6875 b/Documentation/misc-devices/max6875
index 10ca43cd1a7..1e89ee3ccc1 100644
--- a/Documentation/i2c/chips/max6875
+++ b/Documentation/misc-devices/max6875
@@ -42,10 +42,12 @@ General Remarks
Valid addresses for the MAX6875 are 0x50 and 0x52.
Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56.
-The driver does not probe any address, so you must force the address.
+The driver does not probe any address, so you explicitly instantiate the
+devices.
Example:
-$ modprobe max6875 force=0,0x50
+$ modprobe max6875
+$ echo max6875 0x50 > /sys/bus/i2c/devices/i2c-0/new_device
The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
addresses. For example, for address 0x50, it also reserves 0x51.
diff --git a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt
index c6cf4a3c16e..61bb645d50e 100644
--- a/Documentation/networking/pktgen.txt
+++ b/Documentation/networking/pktgen.txt
@@ -90,6 +90,11 @@ Examples:
pgset "dstmac 00:00:00:00:00:00" sets MAC destination address
pgset "srcmac 00:00:00:00:00:00" sets MAC source address
+ pgset "queue_map_min 0" Sets the min value of tx queue interval
+ pgset "queue_map_max 7" Sets the max value of tx queue interval, for multiqueue devices
+ To select queue 1 of a given device,
+ use queue_map_min=1 and queue_map_max=1
+
pgset "src_mac_count 1" Sets the number of MACs we'll range through.
The 'minimum' MAC is what you set with srcmac.
@@ -101,6 +106,9 @@ Examples:
IPDST_RND, UDPSRC_RND,
UDPDST_RND, MACSRC_RND, MACDST_RND
MPLS_RND, VID_RND, SVID_RND
+ QUEUE_MAP_RND # queue map random
+ QUEUE_MAP_CPU # queue map mirrors smp_processor_id()
+
pgset "udp_src_min 9" set UDP source port min, If < udp_src_max, then
cycle through the port range.
diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
index 43d14310421..a7936fe8444 100644
--- a/Documentation/networking/timestamping/timestamping.c
+++ b/Documentation/networking/timestamping/timestamping.c
@@ -381,7 +381,7 @@ int main(int argc, char **argv)
memset(&hwtstamp, 0, sizeof(hwtstamp));
strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
hwtstamp.ifr_data = (void *)&hwconfig;
- memset(&hwconfig, 0, sizeof(&hwconfig));
+ memset(&hwconfig, 0, sizeof(hwconfig));
hwconfig.tx_type =
(so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index f1708b79f96..75fddb40f41 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -209,6 +209,7 @@ AD1884A / AD1883 / AD1984A / AD1984B
laptop laptop with HP jack sensing
mobile mobile devices with HP jack sensing
thinkpad Lenovo Thinkpad X300
+ touchsmart HP Touchsmart
AD1884
======
diff --git a/Documentation/vm/ksm.txt b/Documentation/vm/ksm.txt
index 72a22f65960..262d8e6793a 100644
--- a/Documentation/vm/ksm.txt
+++ b/Documentation/vm/ksm.txt
@@ -52,15 +52,15 @@ The KSM daemon is controlled by sysfs files in /sys/kernel/mm/ksm/,
readable by all but writable only by root:
max_kernel_pages - set to maximum number of kernel pages that KSM may use
- e.g. "echo 2000 > /sys/kernel/mm/ksm/max_kernel_pages"
+ e.g. "echo 100000 > /sys/kernel/mm/ksm/max_kernel_pages"
Value 0 imposes no limit on the kernel pages KSM may use;
but note that any process using MADV_MERGEABLE can cause
KSM to allocate these pages, unswappable until it exits.
- Default: 2000 (chosen for demonstration purposes)
+ Default: quarter of memory (chosen to not pin too much)
pages_to_scan - how many present pages to scan before ksmd goes to sleep
- e.g. "echo 200 > /sys/kernel/mm/ksm/pages_to_scan"
- Default: 200 (chosen for demonstration purposes)
+ e.g. "echo 100 > /sys/kernel/mm/ksm/pages_to_scan"
+ Default: 100 (chosen for demonstration purposes)
sleep_millisecs - how many milliseconds ksmd should sleep before next scan
e.g. "echo 20 > /sys/kernel/mm/ksm/sleep_millisecs"
@@ -70,7 +70,8 @@ run - set 0 to stop ksmd from running but keep merged pages,
set 1 to run ksmd e.g. "echo 1 > /sys/kernel/mm/ksm/run",
set 2 to stop ksmd and unmerge all pages currently merged,
but leave mergeable areas registered for next run
- Default: 1 (for immediate use by apps which register)
+ Default: 0 (must be changed to 1 to activate KSM,
+ except if CONFIG_SYSFS is disabled)
The effectiveness of KSM and MADV_MERGEABLE is shown in /sys/kernel/mm/ksm/:
@@ -86,4 +87,4 @@ pages_volatile embraces several different kinds of activity, but a high
proportion there would also indicate poor use of madvise MADV_MERGEABLE.
Izik Eidus,
-Hugh Dickins, 30 July 2009
+Hugh Dickins, 24 Sept 2009
diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c
index fa1a30d9e9d..3ec4f2a2258 100644
--- a/Documentation/vm/page-types.c
+++ b/Documentation/vm/page-types.c
@@ -2,7 +2,10 @@
* page-types: Tool for querying page flags
*
* Copyright (C) 2009 Intel corporation
- * Copyright (C) 2009 Wu Fengguang <fengguang.wu@intel.com>
+ *
+ * Authors: Wu Fengguang <fengguang.wu@intel.com>
+ *
+ * Released under the General Public License (GPL).
*/
#define _LARGEFILE64_SOURCE
@@ -69,7 +72,9 @@
#define KPF_COMPOUND_TAIL 16
#define KPF_HUGE 17
#define KPF_UNEVICTABLE 18
+#define KPF_HWPOISON 19
#define KPF_NOPAGE 20
+#define KPF_KSM 21
/* [32-] kernel hacking assistances */
#define KPF_RESERVED 32
@@ -116,7 +121,9 @@ static char *page_flag_names[] = {
[KPF_COMPOUND_TAIL] = "T:compound_tail",
[KPF_HUGE] = "G:huge",
[KPF_UNEVICTABLE] = "u:unevictable",
+ [KPF_HWPOISON] = "X:hwpoison",
[KPF_NOPAGE] = "n:nopage",
+ [KPF_KSM] = "x:ksm",
[KPF_RESERVED] = "r:reserved",
[KPF_MLOCKED] = "m:mlocked",
@@ -152,9 +159,6 @@ static unsigned long opt_size[MAX_ADDR_RANGES];
static int nr_vmas;
static unsigned long pg_start[MAX_VMAS];
static unsigned long pg_end[MAX_VMAS];
-static unsigned long voffset;
-
-static int pagemap_fd;
#define MAX_BIT_FILTERS 64
static int nr_bit_filters;
@@ -163,9 +167,16 @@ static uint64_t opt_bits[MAX_BIT_FILTERS];
static int page_size;
-#define PAGES_BATCH (64 << 10) /* 64k pages */
+static int pagemap_fd;
static int kpageflags_fd;
+static int opt_hwpoison;
+static int opt_unpoison;
+
+static char *hwpoison_debug_fs = "/debug/hwpoison";
+static int hwpoison_inject_fd;
+static int hwpoison_forget_fd;
+
#define HASH_SHIFT 13
#define HASH_SIZE (1 << HASH_SHIFT)
#define HASH_MASK (HASH_SIZE - 1)
@@ -207,6 +218,74 @@ static void fatal(const char *x, ...)
exit(EXIT_FAILURE);
}
+int checked_open(const char *pathname, int flags)
+{
+ int fd = open(pathname, flags);
+
+ if (fd < 0) {
+ perror(pathname);
+ exit(EXIT_FAILURE);
+ }
+
+ return fd;
+}
+
+/*
+ * pagemap/kpageflags routines
+ */
+
+static unsigned long do_u64_read(int fd, char *name,
+ uint64_t *buf,
+ unsigned long index,
+ unsigned long count)
+{
+ long bytes;
+
+ if (index > ULONG_MAX / 8)
+ fatal("index overflow: %lu\n", index);
+
+ if (lseek(fd, index * 8, SEEK_SET) < 0) {
+ perror(name);
+ exit(EXIT_FAILURE);
+ }
+
+ bytes = read(fd, buf, count * 8);
+ if (bytes < 0) {
+ perror(name);
+ exit(EXIT_FAILURE);
+ }
+ if (bytes % 8)
+ fatal("partial read: %lu bytes\n", bytes);
+
+ return bytes / 8;
+}
+
+static unsigned long kpageflags_read(uint64_t *buf,
+ unsigned long index,
+ unsigned long pages)
+{
+ return do_u64_read(kpageflags_fd, PROC_KPAGEFLAGS, buf, index, pages);
+}
+
+static unsigned long pagemap_read(uint64_t *buf,
+ unsigned long index,
+ unsigned long pages)
+{
+ return do_u64_read(pagemap_fd, "/proc/pid/pagemap", buf, index, pages);
+}
+
+static unsigned long pagemap_pfn(uint64_t val)
+{
+ unsigned long pfn;
+
+ if (val & PM_PRESENT)
+ pfn = PM_PFRAME(val);
+ else
+ pfn = 0;
+
+ return pfn;
+}
+
/*
* page flag names
@@ -255,7 +334,8 @@ static char *page_flag_longname(uint64_t flags)
* page list and summary
*/
-static void show_page_range(unsigned long offset, uint64_t flags)
+static void show_page_range(unsigned long voffset,
+ unsigned long offset, uint64_t flags)
{
static uint64_t flags0;
static unsigned long voff;
@@ -281,7 +361,8 @@ static void show_page_range(unsigned long offset, uint64_t flags)
count = 1;
}
-static void show_page(unsigned long offset, uint64_t flags)
+static void show_page(unsigned long voffset,
+ unsigned long offset, uint64_t flags)
{
if (opt_pid)
printf("%lx\t", voffset);
@@ -362,6 +443,62 @@ static uint64_t well_known_flags(uint64_t flags)
return flags;
}
+static uint64_t kpageflags_flags(uint64_t flags)
+{
+ flags = expand_overloaded_flags(flags);
+
+ if (!opt_raw)
+ flags = well_known_flags(flags);
+
+ return flags;
+}
+
+/*
+ * page actions
+ */
+
+static void prepare_hwpoison_fd(void)
+{
+ char buf[100];
+
+ if (opt_hwpoison && !hwpoison_inject_fd) {
+ sprintf(buf, "%s/corrupt-pfn", hwpoison_debug_fs);
+ hwpoison_inject_fd = checked_open(buf, O_WRONLY);
+ }
+
+ if (opt_unpoison && !hwpoison_forget_fd) {
+ sprintf(buf, "%s/renew-pfn", hwpoison_debug_fs);
+ hwpoison_forget_fd = checked_open(buf, O_WRONLY);
+ }
+}
+
+static int hwpoison_page(unsigned long offset)
+{
+ char buf[100];
+ int len;
+
+ len = sprintf(buf, "0x%lx\n", offset);
+ len = write(hwpoison_inject_fd, buf, len);
+ if (len < 0) {
+ perror("hwpoison inject");
+ return len;
+ }
+ return 0;
+}
+
+static int unpoison_page(unsigned long offset)
+{
+ char buf[100];
+ int len;
+
+ len = sprintf(buf, "0x%lx\n", offset);
+ len = write(hwpoison_forget_fd, buf, len);
+ if (len < 0) {
+ perror("hwpoison forget");
+ return len;
+ }
+ return 0;
+}
/*
* page frame walker
@@ -394,104 +531,83 @@ static int hash_slot(uint64_t flags)
exit(EXIT_FAILURE);
}
-static void add_page(unsigned long offset, uint64_t flags)
+static void add_page(unsigned long voffset,
+ unsigned long offset, uint64_t flags)
{
- flags = expand_overloaded_flags(flags);
-
- if (!opt_raw)
- flags = well_known_flags(flags);
+ flags = kpageflags_flags(flags);
if (!bit_mask_ok(flags))
return;
+ if (opt_hwpoison)
+ hwpoison_page(offset);
+ if (opt_unpoison)
+ unpoison_page(offset);
+
if (opt_list == 1)
- show_page_range(offset, flags);
+ show_page_range(voffset, offset, flags);
else if (opt_list == 2)
- show_page(offset, flags);
+ show_page(voffset, offset, flags);
nr_pages[hash_slot(flags)]++;
total_pages++;
}
-static void walk_pfn(unsigned long index, unsigned long count)
+#define KPAGEFLAGS_BATCH (64 << 10) /* 64k pages */
+static void walk_pfn(unsigned long voffset,
+ unsigned long index,
+ unsigned long count)
{
+ uint64_t buf[KPAGEFLAGS_BATCH];
unsigned long batch;
- unsigned long n;
+ unsigned long pages;
unsigned long i;
- if (index > ULONG_MAX / KPF_BYTES)
- fatal("index overflow: %lu\n", index);
-
- lseek(kpageflags_fd, index * KPF_BYTES, SEEK_SET);
-
while (count) {
- uint64_t kpageflags_buf[KPF_BYTES * PAGES_BATCH];
-
- batch = min_t(unsigned long, count, PAGES_BATCH);
- n = read(kpageflags_fd, kpageflags_buf, batch * KPF_BYTES);
- if (n == 0)
+ batch = min_t(unsigned long, count, KPAGEFLAGS_BATCH);
+ pages = kpageflags_read(buf, index, batch);
+ if (pages == 0)
break;
- if (n < 0) {
- perror(PROC_KPAGEFLAGS);
- exit(EXIT_FAILURE);
- }
- if (n % KPF_BYTES != 0)
- fatal("partial read: %lu bytes\n", n);
- n = n / KPF_BYTES;
+ for (i = 0; i < pages; i++)
+ add_page(voffset + i, index + i, buf[i]);
- for (i = 0; i < n; i++)
- add_page(index + i, kpageflags_buf[i]);
-
- index += batch;
- count -= batch;
+ index += pages;
+ count -= pages;
}
}
-
-#define PAGEMAP_BATCH 4096
-static unsigned long task_pfn(unsigned long pgoff)
+#define PAGEMAP_BATCH (64 << 10)
+static void walk_vma(unsigned long index, unsigned long count)
{
- static uint64_t buf[PAGEMAP_BATCH];
- static unsigned long start;
- static long count;
- uint64_t pfn;
+ uint64_t buf[PAGEMAP_BATCH];
+ unsigned long batch;
+ unsigned long pages;
+ unsigned long pfn;
+ unsigned long i;
- if (pgoff < start || pgoff >= start + count) {
- if (lseek64(pagemap_fd,
- (uint64_t)pgoff * PM_ENTRY_BYTES,
- SEEK_SET) < 0) {
- perror("pagemap seek");
- exit(EXIT_FAILURE);
- }
- count = read(pagemap_fd, buf, sizeof(buf));
- if (count == 0)
- return 0;
- if (count < 0) {
- perror("pagemap read");
- exit(EXIT_FAILURE);
- }
- if (count % PM_ENTRY_BYTES) {
- fatal("pagemap read not aligned.\n");
- exit(EXIT_FAILURE);
- }
- count /= PM_ENTRY_BYTES;
- start = pgoff;
- }
+ while (count) {
+ batch = min_t(unsigned long, count, PAGEMAP_BATCH);
+ pages = pagemap_read(buf, index, batch);
+ if (pages == 0)
+ break;
- pfn = buf[pgoff - start];
- if (pfn & PM_PRESENT)
- pfn = PM_PFRAME(pfn);
- else
- pfn = 0;
+ for (i = 0; i < pages; i++) {
+ pfn = pagemap_pfn(buf[i]);
+ if (pfn)
+ walk_pfn(index + i, pfn, 1);
+ }
- return pfn;
+ index += pages;
+ count -= pages;
+ }
}
static void walk_task(unsigned long index, unsigned long count)
{
- int i = 0;
const unsigned long end = index + count;
+ unsigned long start;
+ int i = 0;
while (index < end) {
@@ -501,15 +617,11 @@ static void walk_task(unsigned long index, unsigned long count)
if (pg_start[i] >= end)
return;
- voffset = max_t(unsigned long, pg_start[i], index);
- index = min_t(unsigned long, pg_end[i], end);
+ start = max_t(unsigned long, pg_start[i], index);
+ index = min_t(unsigned long, pg_end[i], end);
- assert(voffset < index);
- for (; voffset < index; voffset++) {
- unsigned long pfn = task_pfn(voffset);
- if (pfn)
- walk_pfn(pfn, 1);
- }
+ assert(start < index);
+ walk_vma(start, index - start);
}
}
@@ -527,18 +639,14 @@ static void walk_addr_ranges(void)
{
int i;
- kpageflags_fd = open(PROC_KPAGEFLAGS, O_RDONLY);
- if (kpageflags_fd < 0) {
- perror(PROC_KPAGEFLAGS);
- exit(EXIT_FAILURE);
- }
+ kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY);
if (!nr_addr_ranges)
add_addr_range(0, ULONG_MAX);
for (i = 0; i < nr_addr_ranges; i++)
if (!opt_pid)
- walk_pfn(opt_offset[i], opt_size[i]);
+ walk_pfn(0, opt_offset[i], opt_size[i]);
else
walk_task(opt_offset[i], opt_size[i]);
@@ -575,6 +683,8 @@ static void usage(void)
" -l|--list Show page details in ranges\n"
" -L|--list-each Show page details one by one\n"
" -N|--no-summary Don't show summay info\n"
+" -X|--hwpoison hwpoison pages\n"
+" -x|--unpoison unpoison pages\n"
" -h|--help Show this usage message\n"
"addr-spec:\n"
" N one page at offset N (unit: pages)\n"
@@ -624,11 +734,7 @@ static void parse_pid(const char *str)
opt_pid = parse_number(str);
sprintf(buf, "/proc/%d/pagemap", opt_pid);
- pagemap_fd = open(buf, O_RDONLY);
- if (pagemap_fd < 0) {
- perror(buf);
- exit(EXIT_FAILURE);
- }
+ pagemap_fd = checked_open(buf, O_RDONLY);
sprintf(buf, "/proc/%d/maps", opt_pid);
file = fopen(buf, "r");
@@ -788,6 +894,8 @@ static struct option opts[] = {
{ "list" , 0, NULL, 'l' },
{ "list-each" , 0, NULL, 'L' },
{ "no-summary", 0, NULL, 'N' },
+ { "hwpoison" , 0, NULL, 'X' },
+ { "unpoison" , 0, NULL, 'x' },
{ "help" , 0, NULL, 'h' },
{ NULL , 0, NULL, 0 }
};
@@ -799,7 +907,7 @@ int main(int argc, char *argv[])
page_size = getpagesize();
while ((c = getopt_long(argc, argv,
- "rp:f:a:b:lLNh", opts, NULL)) != -1) {
+ "rp:f:a:b:lLNXxh", opts, NULL)) != -1) {
switch (c) {
case 'r':
opt_raw = 1;
@@ -825,6 +933,14 @@ int main(int argc, char *argv[])
case 'N':
opt_no_summary = 1;
break;
+ case 'X':
+ opt_hwpoison = 1;
+ prepare_hwpoison_fd();
+ break;
+ case 'x':
+ opt_unpoison = 1;
+ prepare_hwpoison_fd();
+ break;
case 'h':
usage();
exit(0);
@@ -844,7 +960,7 @@ int main(int argc, char *argv[])
walk_addr_ranges();
if (opt_list == 1)
- show_page_range(0, 0); /* drain the buffer */
+ show_page_range(0, 0, 0); /* drain the buffer */
if (opt_no_summary)
return 0;
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
index 600a304a828..df09b9650a8 100644
--- a/Documentation/vm/pagemap.txt
+++ b/Documentation/vm/pagemap.txt
@@ -57,7 +57,9 @@ There are three components to pagemap:
16. COMPOUND_TAIL
16. HUGE
18. UNEVICTABLE
+ 19. HWPOISON
20. NOPAGE
+ 21. KSM
Short descriptions to the page flags:
@@ -86,9 +88,15 @@ Short descriptions to the page flags:
17. HUGE
this is an integral part of a HugeTLB page
+19. HWPOISON
+ hardware detected memory corruption on this page: don't touch the data!
+
20. NOPAGE
no page frame exists at the requested address
+21. KSM
+ identical memory pages dynamically shared between one or more processes
+
[IO related page flags]
1. ERROR IO error occurred
3. UPTODATE page has up-to-date data
diff --git a/Documentation/w1/masters/ds2482 b/Documentation/w1/masters/ds2482
index 9210d6fa502..299b91c7609 100644
--- a/Documentation/w1/masters/ds2482
+++ b/Documentation/w1/masters/ds2482
@@ -24,8 +24,8 @@ General Remarks
Valid addresses are 0x18, 0x19, 0x1a, and 0x1b.
However, the device cannot be detected without writing to the i2c bus, so no
-detection is done.
-You should force the device address.
+detection is done. You should instantiate the device explicitly.
-$ modprobe ds2482 force=0,0x18
+$ modprobe ds2482
+$ echo ds2482 0x18 > /sys/bus/i2c/devices/i2c-0/new_device
diff --git a/MAINTAINERS b/MAINTAINERS
index db6c47b3ec5..6141bdff359 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -257,6 +257,13 @@ W: http://www.lesswatts.org/projects/acpi/
S: Supported
F: drivers/acpi/fan.c
+ACPI PROCESSOR AGGREGATOR DRIVER
+M: Shaohua Li <shaohua.li@intel.com>
+L: linux-acpi@vger.kernel.org
+W: http://www.lesswatts.org/projects/acpi/
+S: Supported
+F: drivers/acpi/acpi_pad.c
+
ACPI THERMAL DRIVER
M: Zhang Rui <rui.zhang@intel.com>
L: linux-acpi@vger.kernel.org
@@ -646,24 +653,24 @@ ARM/INTEL IOP32X ARM ARCHITECTURE
M: Lennert Buytenhek <kernel@wantstofly.org>
M: Dan Williams <dan.j.williams@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Supported
+S: Maintained
ARM/INTEL IOP33X ARM ARCHITECTURE
M: Dan Williams <dan.j.williams@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Supported
+S: Maintained
ARM/INTEL IOP13XX ARM ARCHITECTURE
M: Lennert Buytenhek <kernel@wantstofly.org>
M: Dan Williams <dan.j.williams@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Supported
+S: Maintained
ARM/INTEL IQ81342EX MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
M: Dan Williams <dan.j.williams@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Supported
+S: Maintained
ARM/INTEL IXP2000 ARM ARCHITECTURE
M: Lennert Buytenhek <kernel@wantstofly.org>
@@ -691,7 +698,7 @@ ARM/INTEL XSC3 (MANZANO) ARM CORE
M: Lennert Buytenhek <kernel@wantstofly.org>
M: Dan Williams <dan.j.williams@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Supported
+S: Maintained
ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
@@ -741,23 +748,36 @@ M: Dirk Opfer <dirk@opfer-online.de>
S: Maintained
ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
-P: Marek Vasut
-M: marek.vasut@gmail.com
+M: Marek Vasut <marek.vasut@gmail.com>
L: linux-arm-kernel@lists.infradead.org
W: http://hackndev.com
S: Maintained
+F: arch/arm/mach-pxa/include/mach/palmtx.h
+F: arch/arm/mach-pxa/palmtx.c
+F: arch/arm/mach-pxa/include/mach/palmt5.h
+F: arch/arm/mach-pxa/palmt5.c
+F: arch/arm/mach-pxa/include/mach/palmld.h
+F: arch/arm/mach-pxa/palmld.c
+F: arch/arm/mach-pxa/include/mach/palmte2.h
+F: arch/arm/mach-pxa/palmte2.c
+F: arch/arm/mach-pxa/include/mach/palmtc.h
+F: arch/arm/mach-pxa/palmtc.c
ARM/PALM TREO 680 SUPPORT
M: Tomas Cech <sleep_walker@suse.cz>
L: linux-arm-kernel@lists.infradead.org
W: http://hackndev.com
S: Maintained
+F: arch/arm/mach-pxa/include/mach/treo680.h
+F: arch/arm/mach-pxa/treo680.c
ARM/PALMZ72 SUPPORT
M: Sergey Lapin <slapin@ossfans.org>
L: linux-arm-kernel@lists.infradead.org
W: http://hackndev.com
S: Maintained
+F: arch/arm/mach-pxa/include/mach/palmz72.h
+F: arch/arm/mach-pxa/palmz72.c
ARM/PLEB SUPPORT
M: Peter Chubb <pleb@gelato.unsw.edu.au>
@@ -2689,7 +2709,7 @@ F: include/linux/intel-iommu.h
INTEL IOP-ADMA DMA DRIVER
M: Dan Williams <dan.j.williams@intel.com>
-S: Supported
+S: Maintained
F: drivers/dma/iop-adma.c
INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
@@ -3630,6 +3650,13 @@ F: Documentation/blockdev/nbd.txt
F: drivers/block/nbd.c
F: include/linux/nbd.h
+NETWORK DROP MONITOR
+M: Neil Horman <nhorman@tuxdriver.com>
+L: netdev@vger.kernel.org
+S: Maintained
+W: https://fedorahosted.org/dropwatch/
+F: net/core/drop_monitor.c
+
NETWORKING [GENERAL]
M: "David S. Miller" <davem@davemloft.net>
L: netdev@vger.kernel.org
@@ -3960,6 +3987,7 @@ F: drivers/block/paride/
PARISC ARCHITECTURE
M: Kyle McMartin <kyle@mcmartin.ca>
M: Helge Deller <deller@gmx.de>
+M: "James E.J. Bottomley" <jejb@parisc-linux.org>
L: linux-parisc@vger.kernel.org
W: http://www.parisc-linux.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
diff --git a/Makefile b/Makefile
index 00444a8e304..e50569ab5fe 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 32
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
NAME = Man-Eating Seals of Antiquity
# *DOCUMENTATION*
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ef12794c3c6..8ba7044c554 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1032,6 +1032,7 @@ unsigned int sa1111_pll_clock(struct sa1111_dev *sadev)
return __sa1111_pll_clock(sachip);
}
+EXPORT_SYMBOL(sa1111_pll_clock);
/**
* sa1111_select_audio_mode - select I2S or AC link mode
@@ -1059,6 +1060,7 @@ void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode)
spin_unlock_irqrestore(&sachip->lock, flags);
}
+EXPORT_SYMBOL(sa1111_select_audio_mode);
/**
* sa1111_set_audio_rate - set the audio sample rate
@@ -1083,6 +1085,7 @@ int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate)
return 0;
}
+EXPORT_SYMBOL(sa1111_set_audio_rate);
/**
* sa1111_get_audio_rate - get the audio sample rate
@@ -1100,6 +1103,7 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
return __sa1111_pll_clock(sachip) / (256 * div);
}
+EXPORT_SYMBOL(sa1111_get_audio_rate);
void sa1111_set_io_dir(struct sa1111_dev *sadev,
unsigned int bits, unsigned int dir,
@@ -1128,6 +1132,7 @@ void sa1111_set_io_dir(struct sa1111_dev *sadev,
MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
spin_unlock_irqrestore(&sachip->lock, flags);
}
+EXPORT_SYMBOL(sa1111_set_io_dir);
void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
{
@@ -1142,6 +1147,7 @@ void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
spin_unlock_irqrestore(&sachip->lock, flags);
}
+EXPORT_SYMBOL(sa1111_set_io);
void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
{
@@ -1156,6 +1162,7 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i
MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
spin_unlock_irqrestore(&sachip->lock, flags);
}
+EXPORT_SYMBOL(sa1111_set_sleep_io);
/*
* Individual device operations.
@@ -1176,6 +1183,7 @@ void sa1111_enable_device(struct sa1111_dev *sadev)
sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);
}
+EXPORT_SYMBOL(sa1111_enable_device);
/**
* sa1111_disable_device - disable an on-chip SA1111 function block
@@ -1192,6 +1200,7 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);
}
+EXPORT_SYMBOL(sa1111_disable_device);
/*
* SA1111 "Register Access Bus."
@@ -1259,17 +1268,20 @@ struct bus_type sa1111_bus_type = {
.suspend = sa1111_bus_suspend,
.resume = sa1111_bus_resume,
};
+EXPORT_SYMBOL(sa1111_bus_type);
int sa1111_driver_register(struct sa1111_driver *driver)
{
driver->drv.bus = &sa1111_bus_type;
return driver_register(&driver->drv);
}
+EXPORT_SYMBOL(sa1111_driver_register);
void sa1111_driver_unregister(struct sa1111_driver *driver)
{
driver_unregister(&driver->drv);
}
+EXPORT_SYMBOL(sa1111_driver_unregister);
static int __init sa1111_init(void)
{
@@ -1290,16 +1302,3 @@ module_exit(sa1111_exit);
MODULE_DESCRIPTION("Intel Corporation SA1111 core driver");
MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(sa1111_select_audio_mode);
-EXPORT_SYMBOL(sa1111_set_audio_rate);
-EXPORT_SYMBOL(sa1111_get_audio_rate);
-EXPORT_SYMBOL(sa1111_set_io_dir);
-EXPORT_SYMBOL(sa1111_set_io);
-EXPORT_SYMBOL(sa1111_set_sleep_io);
-EXPORT_SYMBOL(sa1111_enable_device);
-EXPORT_SYMBOL(sa1111_disable_device);
-EXPORT_SYMBOL(sa1111_pll_clock);
-EXPORT_SYMBOL(sa1111_bus_type);
-EXPORT_SYMBOL(sa1111_driver_register);
-EXPORT_SYMBOL(sa1111_driver_unregister);
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index 1502957db2c..f6aed7747d4 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -90,7 +90,6 @@ CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
CONFIG_SA1100_H3600=y
-CONFIG_SA1100_H3XXX=y
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index eec48829826..ed2d59d0182 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_defconfig
@@ -1,29 +1,26 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc5
-# Wed Dec 12 16:11:27 2007
+# Linux kernel version: 2.6.31-rc6
+# Tue Aug 18 13:41:41 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
-# CONFIG_GENERIC_TIME is not set
-# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_GENERIC_GPIO=y
CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -40,21 +37,39 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -67,29 +82,48 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
#
# IO Schedulers
@@ -103,6 +137,7 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
#
# System Type
@@ -112,15 +147,15 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
CONFIG_ARCH_IOP33X=y
@@ -128,19 +163,26 @@ CONFIG_ARCH_IOP33X=y
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
# CONFIG_ARCH_KS8695 is not set
# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_W90X900 is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-CONFIG_IOP3XX_ATU=y
#
# IOP33x Implementation Options
@@ -151,14 +193,6 @@ CONFIG_IOP3XX_ATU=y
#
CONFIG_ARCH_IQ80331=y
CONFIG_MACH_IQ80332=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
CONFIG_PLAT_IOP=y
#
@@ -168,6 +202,7 @@ CONFIG_CPU_32=y
CONFIG_CPU_XSCALE=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
CONFIG_CPU_CP15=y
@@ -178,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
#
# CONFIG_ARM_THUMB is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_OUTER_CACHE is not set
# CONFIG_IWMMXT is not set
CONFIG_XSCALE_PMU=y
@@ -190,41 +224,55 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
#
# Kernel Features
#
-# CONFIG_TICK_ONESHOT is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
# CONFIG_PREEMPT is not set
CONFIG_HZ=100
# CONFIG_AEABI is not set
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
#
# Boot options
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc iop3xx_init_atu=y"
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set
#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
# Floating point emulation
#
@@ -239,6 +287,8 @@ CONFIG_FPE_NWFPE=y
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
CONFIG_BINFMT_AOUT=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_ARTHUR is not set
@@ -247,11 +297,7 @@ CONFIG_BINFMT_AOUT=y
# Power management options
#
# CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
-
-#
-# Networking
-#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
#
@@ -264,6 +310,7 @@ CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -310,6 +357,7 @@ CONFIG_IPV6=y
# CONFIG_IPV6_SIT is not set
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
@@ -317,6 +365,7 @@ CONFIG_IPV6=y
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
@@ -326,24 +375,31 @@ CONFIG_IPV6=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
#
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -357,7 +413,9 @@ CONFIG_IPV6=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
@@ -366,12 +424,14 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
@@ -421,9 +481,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
@@ -447,6 +505,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -463,14 +526,29 @@ CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -492,10 +570,6 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
@@ -512,6 +586,8 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -520,13 +596,18 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -543,15 +624,18 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
CONFIG_MD_RAID456=y
-# CONFIG_MD_RAID5_RESHAPE is not set
+CONFIG_MD_RAID6_PQ=y
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=y
@@ -568,27 +652,34 @@ CONFIG_BLK_DEV_DM=y
#
# IEEE 1394 (FireWire) support
#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_NET_ETHERNET is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
CONFIG_E1000=y
-CONFIG_E1000_NAPI=y
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -596,23 +687,34 @@ CONFIG_E1000_NAPI=y
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -620,13 +722,16 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
@@ -670,10 +775,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# Character devices
#
CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
@@ -692,11 +800,12 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM is not set
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -705,16 +814,14 @@ CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
#
-# I2C Algorithms
+# I2C Hardware Bus support
#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
#
-# I2C Hardware Bus support
+# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
@@ -722,50 +829,82 @@ CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
-CONFIG_I2C_IOP3XX=y
# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IOP3XX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
# CONFIG_I2C_VOODOO3 is not set
#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
# Miscellaneous I2C Chip support
#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
#
-# SPI support
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
@@ -773,13 +912,17 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -794,16 +937,23 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
@@ -812,28 +962,38 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
+# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -854,15 +1014,16 @@ CONFIG_DAB=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -870,14 +1031,21 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
#
#
-# USB Gadget Support
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
# CONFIG_NEW_LEDS is not set
CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
@@ -893,6 +1061,12 @@ CONFIG_DMA_ENGINE=y
# DMA Clients
#
CONFIG_NET_DMA=y
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
@@ -901,10 +1075,11 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
@@ -913,17 +1088,23 @@ CONFIG_FS_MBCACHE=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -941,15 +1122,13 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -959,29 +1138,31 @@ CONFIG_TMPFS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1013,9 +1194,6 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SYSV68_PARTITION is not set
# CONFIG_NLS is not set
# CONFIG_DLM is not set
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -1023,6 +1201,7 @@ CONFIG_INSTRUMENTATION=y
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
@@ -1030,10 +1209,17 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1047,16 +1233,41 @@ CONFIG_SCHED_DEBUG=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_FORCED_INLINING is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
# CONFIG_DEBUG_ICEDCC is not set
@@ -1065,24 +1276,117 @@ CONFIG_DEBUG_LL=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
#
+CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC_ITU_T is not set
# CONFIG_CRC32 is not set
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
index a0e39d5d00c..234a3fc1c78 100644
--- a/arch/arm/include/asm/glue.h
+++ b/arch/arm/include/asm/glue.h
@@ -120,25 +120,39 @@
#endif
/*
- * Prefetch abort handler. If the CPU has an IFAR use that, otherwise
- * use the address of the aborted instruction
+ * Prefetch Abort Model
+ * ================
+ *
+ * We have the following to choose from:
+ * legacy - no IFSR, no IFAR
+ * v6 - ARMv6: IFSR, no IFAR
+ * v7 - ARMv7: IFSR and IFAR
*/
+
#undef CPU_PABORT_HANDLER
#undef MULTI_PABORT
-#ifdef CONFIG_CPU_PABRT_IFAR
+#ifdef CONFIG_CPU_PABRT_LEGACY
+# ifdef CPU_PABORT_HANDLER
+# define MULTI_PABORT 1
+# else
+# define CPU_PABORT_HANDLER legacy_pabort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_V6
# ifdef CPU_PABORT_HANDLER
# define MULTI_PABORT 1
# else
-# define CPU_PABORT_HANDLER(reg, insn) mrc p15, 0, reg, cr6, cr0, 2
+# define CPU_PABORT_HANDLER v6_pabort
# endif
#endif
-#ifdef CONFIG_CPU_PABRT_NOIFAR
+#ifdef CONFIG_CPU_PABRT_V7
# ifdef CPU_PABORT_HANDLER
# define MULTI_PABORT 1
# else
-# define CPU_PABORT_HANDLER(reg, insn) mov reg, insn
+# define CPU_PABORT_HANDLER v7_pabort
# endif
#endif
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h
index 4b8e7f55992..8d60ad267e3 100644
--- a/arch/arm/include/asm/hardware/iop3xx.h
+++ b/arch/arm/include/asm/hardware/iop3xx.h
@@ -215,6 +215,7 @@ extern int iop3xx_get_init_atu(void);
* IOP3XX I/O and Mem space regions for PCI autoconfiguration
*/
#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000
+#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x08000000
#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000
#define IOP3XX_PCI_LOWER_IO_PA 0x90000000
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
new file mode 100644
index 00000000000..59303e20084
--- /dev/null
+++ b/arch/arm/include/asm/smp_plat.h
@@ -0,0 +1,16 @@
+/*
+ * ARM specific SMP header, this contains our implementation
+ * details.
+ */
+#ifndef __ASMARM_SMP_PLAT_H
+#define __ASMARM_SMP_PLAT_H
+
+#include <asm/cputype.h>
+
+/* all SMP configurations have the extended CPUID registers */
+static inline int tlb_ops_need_broadcast(void)
+{
+ return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
+}
+
+#endif
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 89f7eade20a..7020217fc49 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -456,6 +456,7 @@
* Unimplemented (or alternatively implemented) syscalls
*/
#define __IGNORE_fadvise64_64 1
+#define __IGNORE_migrate_pages 1
#endif /* __KERNEL__ */
#endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 0a2ba51cf35..322410be573 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -311,22 +311,16 @@ __pabt_svc:
tst r3, #PSR_I_BIT
biceq r9, r9, #PSR_I_BIT
- @
- @ set args, then call main handler
- @
- @ r0 - address of faulting instruction
- @ r1 - pointer to registers on stack
- @
-#ifdef MULTI_PABORT
mov r0, r2 @ pass address of aborted instruction.
+#ifdef MULTI_PABORT
ldr r4, .LCprocfns
mov lr, pc
ldr pc, [r4, #PROCESSOR_PABT_FUNC]
#else
- CPU_PABORT_HANDLER(r0, r2)
+ bl CPU_PABORT_HANDLER
#endif
msr cpsr_c, r9 @ Maybe enable interrupts
- mov r1, sp @ regs
+ mov r2, sp @ regs
bl do_PrefetchAbort @ call abort handler
@
@@ -701,16 +695,16 @@ ENDPROC(__und_usr_unknown)
__pabt_usr:
usr_entry
-#ifdef MULTI_PABORT
mov r0, r2 @ pass address of aborted instruction.
+#ifdef MULTI_PABORT
ldr r4, .LCprocfns
mov lr, pc
ldr pc, [r4, #PROCESSOR_PABT_FUNC]
#else
- CPU_PABORT_HANDLER(r0, r2)
+ bl CPU_PABORT_HANDLER
#endif
enable_irq @ Enable interrupts
- mov r1, sp @ regs
+ mov r2, sp @ regs
bl do_PrefetchAbort @ call abort handler
UNWIND(.fnend )
/* fall through */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 807cfebb0f4..f0fe95b7085 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -126,7 +126,7 @@ ENTRY(__gnu_mcount_nc)
cmp r0, r2
bne gnu_trace
ldmia sp!, {r0-r3, ip, lr}
- bx ip
+ mov pc, ip
gnu_trace:
ldr r1, [sp, #20] @ lr of instrumented routine
@@ -135,7 +135,7 @@ gnu_trace:
mov lr, pc
mov pc, r2
ldmia sp!, {r0-r3, ip, lr}
- bx ip
+ mov pc, ip
ENTRY(mcount)
stmdb sp!, {r0-r3, lr}
@@ -425,13 +425,6 @@ sys_mmap2:
#endif
ENDPROC(sys_mmap2)
-ENTRY(pabort_ifar)
- mrc p15, 0, r0, cr6, cr0, 2
-ENTRY(pabort_noifar)
- mov pc, lr
-ENDPROC(pabort_ifar)
-ENDPROC(pabort_noifar)
-
#ifdef CONFIG_OABI_COMPAT
/*
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 93ad576b2d7..885a7214418 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -13,6 +13,7 @@
#define ATAG_CORE 0x54410001
#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
+#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
.align 2
.type __switch_data, %object
@@ -251,7 +252,8 @@ __vet_atags:
bne 1f
ldr r5, [r2, #0] @ is first tag ATAG_CORE?
- subs r5, r5, #ATAG_CORE_SIZE
+ cmp r5, #ATAG_CORE_SIZE
+ cmpne r5, #ATAG_CORE_SIZE_EMPTY
bne 1f
ldr r5, [r2, #4]
ldr r6, =ATAG_CORE
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e0d32770bb3..57162af53dc 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -36,6 +36,7 @@
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
#include <asm/localtimer.h>
+#include <asm/smp_plat.h>
/*
* as from 2.5, kernels no longer have an init_tasks structure
@@ -153,7 +154,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
/*
* __cpu_disable runs on the processor to be shutdown.
*/
-int __cpuexit __cpu_disable(void)
+int __cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
struct task_struct *p;
@@ -200,7 +201,7 @@ int __cpuexit __cpu_disable(void)
* called on the thread which is asking for a CPU to be shutdown -
* waits until shutdown has completed, or it is timed out.
*/
-void __cpuexit __cpu_die(unsigned int cpu)
+void __cpu_die(unsigned int cpu)
{
if (!platform_cpu_kill(cpu))
printk("CPU%u: unable to kill\n", cpu);
@@ -214,7 +215,7 @@ void __cpuexit __cpu_die(unsigned int cpu)
* of the other hotplug-cpu capable cores, so presumably coming
* out of idle fixes this.
*/
-void __cpuexit cpu_die(void)
+void __ref cpu_die(void)
{
unsigned int cpu = smp_processor_id();
@@ -586,12 +587,6 @@ struct tlb_args {
unsigned long ta_end;
};
-/* all SMP configurations have the extended CPUID registers */
-static inline int tlb_ops_need_broadcast(void)
-{
- return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
-}
-
static inline void ipi_flush_tlb_all(void *ignored)
{
local_flush_tlb_all();
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index d8c88c633c6..a73a34dccf2 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -166,10 +166,12 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
clockevents_register_device(clk);
}
+#ifdef CONFIG_HOTPLUG_CPU
/*
* take a local timer down
*/
-void __cpuexit twd_timer_stop(void)
+void twd_timer_stop(void)
{
__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
}
+#endif
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 57eb0f6f600..467b69ed102 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -418,12 +418,14 @@ static int bad_syscall(int n, struct pt_regs *regs)
static inline void
do_cache_op(unsigned long start, unsigned long end, int flags)
{
+ struct mm_struct *mm = current->active_mm;
struct vm_area_struct *vma;
if (end < start || flags)
return;
- vma = find_vma(current->active_mm, start);
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, start);
if (vma && vma->vm_start < end) {
if (start < vma->vm_start)
start = vma->vm_start;
@@ -432,6 +434,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
flush_cache_user_range(vma, start, end);
}
+ up_read(&mm->mmap_sem);
}
/*
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index 492c649f451..4b4f69251b3 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -31,7 +31,6 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
-#include <linux/amba/bus.h>
#include <mach/csp/mm_addr.h>
#include <mach/hardware.h>
#include <asm/clkdev.h>
@@ -45,7 +44,6 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
-#include <asm/mach/mmc.h>
#include <cfg_global.h>
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index a1d5e7dac74..52dd8046b30 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -35,7 +35,6 @@
#include <mach/common.h>
#include <mach/i2c.h>
#include <mach/serial.h>
-#include <mach/common.h>
#include <mach/mmc.h>
#include <mach/nand.h>
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index f1d72b22545..901cc205015 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -486,7 +486,7 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
return ret;
}
-struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
+struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
{
return pci_scan_bus(sys->busnr, &pci_v3_ops, sys);
}
diff --git a/arch/arm/mach-iop32x/include/mach/iop32x.h b/arch/arm/mach-iop32x/include/mach/iop32x.h
index abd9eb49f10..941f363aca5 100644
--- a/arch/arm/mach-iop32x/include/mach/iop32x.h
+++ b/arch/arm/mach-iop32x/include/mach/iop32x.h
@@ -31,7 +31,5 @@
#define IOP32X_MAX_RAM_SIZE 0x40000000UL
#define IOP3XX_MAX_RAM_SIZE IOP32X_MAX_RAM_SIZE
#define IOP3XX_PCI_LOWER_MEM_BA 0x80000000
-#define IOP32X_PCI_MEM_WINDOW_SIZE 0x04000000
-#define IOP3XX_PCI_MEM_WINDOW_SIZE IOP32X_PCI_MEM_WINDOW_SIZE
#endif
diff --git a/arch/arm/mach-iop33x/include/mach/iop33x.h b/arch/arm/mach-iop33x/include/mach/iop33x.h
index 24567316ec8..a89c0a234bf 100644
--- a/arch/arm/mach-iop33x/include/mach/iop33x.h
+++ b/arch/arm/mach-iop33x/include/mach/iop33x.h
@@ -36,8 +36,6 @@
#define IOP33X_MAX_RAM_SIZE 0x80000000UL
#define IOP3XX_MAX_RAM_SIZE IOP33X_MAX_RAM_SIZE
#define IOP3XX_PCI_LOWER_MEM_BA (PHYS_OFFSET + IOP33X_MAX_RAM_SIZE)
-#define IOP33X_PCI_MEM_WINDOW_SIZE 0x08000000
-#define IOP3XX_PCI_MEM_WINDOW_SIZE IOP33X_PCI_MEM_WINDOW_SIZE
#endif
diff --git a/arch/arm/mach-ns9xxx/clock.c b/arch/arm/mach-ns9xxx/clock.c
index 44ed20d4a38..cf81cbc5754 100644
--- a/arch/arm/mach-ns9xxx/clock.c
+++ b/arch/arm/mach-ns9xxx/clock.c
@@ -195,7 +195,7 @@ static int clk_debugfs_open(struct inode *inode, struct file *file)
return single_open(file, clk_debugfs_show, NULL);
}
-static struct file_operations clk_debugfs_operations = {
+static const struct file_operations clk_debugfs_operations = {
.open = clk_debugfs_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index b45ad312c58..c1af5326e92 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -38,49 +38,49 @@
static int board_keymap[] = {
KEY(0, 0, KEY_Q),
- KEY(0, 1, KEY_W),
- KEY(0, 2, KEY_E),
- KEY(0, 3, KEY_R),
- KEY(0, 4, KEY_T),
- KEY(0, 5, KEY_Y),
- KEY(0, 6, KEY_U),
- KEY(0, 7, KEY_I),
- KEY(1, 0, KEY_O),
+ KEY(0, 1, KEY_O),
+ KEY(0, 2, KEY_P),
+ KEY(0, 3, KEY_COMMA),
+ KEY(0, 4, KEY_BACKSPACE),
+ KEY(0, 6, KEY_A),
+ KEY(0, 7, KEY_S),
+ KEY(1, 0, KEY_W),
KEY(1, 1, KEY_D),
- KEY(1, 2, KEY_DOT),
- KEY(1, 3, KEY_V),
- KEY(1, 4, KEY_DOWN),
- KEY(2, 0, KEY_P),
- KEY(2, 1, KEY_F),
+ KEY(1, 2, KEY_F),
+ KEY(1, 3, KEY_G),
+ KEY(1, 4, KEY_H),
+ KEY(1, 5, KEY_J),
+ KEY(1, 6, KEY_K),
+ KEY(1, 7, KEY_L),
+ KEY(2, 0, KEY_E),
+ KEY(2, 1, KEY_DOT),
KEY(2, 2, KEY_UP),
- KEY(2, 3, KEY_B),
- KEY(2, 4, KEY_RIGHT),
- KEY(3, 0, KEY_COMMA),
- KEY(3, 1, KEY_G),
- KEY(3, 2, KEY_ENTER),
+ KEY(2, 3, KEY_ENTER),
+ KEY(2, 5, KEY_Z),
+ KEY(2, 6, KEY_X),
+ KEY(2, 7, KEY_C),
+ KEY(3, 0, KEY_R),
+ KEY(3, 1, KEY_V),
+ KEY(3, 2, KEY_B),
KEY(3, 3, KEY_N),
- KEY(4, 0, KEY_BACKSPACE),
- KEY(4, 1, KEY_H),
- KEY(4, 3, KEY_M),
+ KEY(3, 4, KEY_M),
+ KEY(3, 5, KEY_SPACE),
+ KEY(3, 6, KEY_SPACE),
+ KEY(3, 7, KEY_LEFT),
+ KEY(4, 0, KEY_T),
+ KEY(4, 1, KEY_DOWN),
+ KEY(4, 2, KEY_RIGHT),
KEY(4, 4, KEY_LEFTCTRL),
- KEY(5, 1, KEY_J),
- KEY(5, 2, KEY_Z),
- KEY(5, 3, KEY_SPACE),
- KEY(5, 4, KEY_LEFTSHIFT),
- KEY(6, 0, KEY_A),
- KEY(6, 1, KEY_K),
- KEY(6, 2, KEY_X),
- KEY(6, 3, KEY_SPACE),
- KEY(6, 4, KEY_FN),
- KEY(7, 0, KEY_S),
- KEY(7, 1, KEY_L),
- KEY(7, 2, KEY_C),
- KEY(7, 3, KEY_LEFT),
- KEY(0xff, 0, KEY_F6),
- KEY(0xff, 1, KEY_F7),
- KEY(0xff, 2, KEY_F8),
- KEY(0xff, 4, KEY_F9),
- KEY(0xff, 5, KEY_F10),
+ KEY(4, 5, KEY_RIGHTALT),
+ KEY(4, 6, KEY_LEFTSHIFT),
+ KEY(5, 0, KEY_Y),
+ KEY(6, 0, KEY_U),
+ KEY(7, 0, KEY_I),
+ KEY(7, 1, KEY_F7),
+ KEY(7, 2, KEY_F8),
+ KEY(0xff, 2, KEY_F9),
+ KEY(0xff, 4, KEY_F10),
+ KEY(0xff, 5, KEY_F11),
};
static struct matrix_keymap_data board_map_data = {
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index fafcd32e690..489556eecbd 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -338,6 +338,13 @@ static struct omap_clk omap34xx_clks[] = {
*/
#define SDRC_MPURATE_LOOPS 96
+/*
+ * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
+ * that are sourced by DPLL5, and both of these require this clock
+ * to be at 120 MHz for proper operation.
+ */
+#define DPLL5_FREQ_FOR_USBHOST 120000000
+
/**
* omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
* @clk: struct clk * being enabled
@@ -1056,6 +1063,28 @@ void omap2_clk_prepare_for_reboot(void)
#endif
}
+static void omap3_clk_lock_dpll5(void)
+{
+ struct clk *dpll5_clk;
+ struct clk *dpll5_m2_clk;
+
+ dpll5_clk = clk_get(NULL, "dpll5_ck");
+ clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
+ clk_enable(dpll5_clk);
+
+ /* Enable autoidle to allow it to enter low power bypass */
+ omap3_dpll_allow_idle(dpll5_clk);
+
+ /* Program dpll5_m2_clk divider for no division */
+ dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
+ clk_enable(dpll5_m2_clk);
+ clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
+
+ clk_disable(dpll5_m2_clk);
+ clk_disable(dpll5_clk);
+ return;
+}
+
/* REVISIT: Move this init stuff out into clock.c */
/*
@@ -1148,6 +1177,12 @@ int __init omap2_clk_init(void)
*/
clk_enable_init_clocks();
+ /*
+ * Lock DPLL5 and put it in autoidle.
+ */
+ if (omap_rev() >= OMAP3430_REV_ES2_0)
+ omap3_clk_lock_dpll5();
+
/* Avoid sleeping during omap2_clk_prepare_for_reboot() */
/* REVISIT: not yet ready for 343x */
#if 0
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 1b4c1600f8d..2fc4d6abbd0 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -541,7 +541,7 @@ static int __init pm_dbg_init(void)
printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
return -ENODEV;
}
-
+
d = debugfs_create_dir("pm_debug", NULL);
if (IS_ERR(d))
return PTR_ERR(d);
@@ -551,7 +551,7 @@ static int __init pm_dbg_init(void)
(void) debugfs_create_file("time", S_IRUGO,
d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
- pwrdm_for_each(pwrdms_setup, (void *)d);
+ pwrdm_for_each_nolock(pwrdms_setup, (void *)d);
pm_dbg_dir = debugfs_create_dir("registers", d);
if (IS_ERR(pm_dbg_dir))
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0ff5a6c53aa..378c2f61835 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -51,97 +51,112 @@ static void (*_omap_sram_idle)(u32 *addr, int save_state);
static struct powerdomain *mpu_pwrdm;
-/* PRCM Interrupt Handler for wakeups */
-static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+/*
+ * PRCM Interrupt Handler Helper Function
+ *
+ * The purpose of this function is to clear any wake-up events latched
+ * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
+ * may occur whilst attempting to clear a PM_WKST_x register and thus
+ * set another bit in this register. A while loop is used to ensure
+ * that any peripheral wake-up events occurring while attempting to
+ * clear the PM_WKST_x are detected and cleared.
+ */
+static int prcm_clear_mod_irqs(s16 module, u8 regs)
{
- u32 wkst, irqstatus_mpu;
- u32 fclk, iclk;
-
- /* WKUP */
- wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
+ u32 wkst, fclk, iclk, clken;
+ u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
+ u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
+ u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
+ u16 grpsel_off = (regs == 3) ?
+ OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
+ int c = 0;
+
+ wkst = prm_read_mod_reg(module, wkst_off);
+ wkst &= prm_read_mod_reg(module, grpsel_off);
if (wkst) {
- iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
- fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
- cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_ICLKEN);
- cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_FCLKEN);
- prm_write_mod_reg(wkst, WKUP_MOD, PM_WKST);
- while (prm_read_mod_reg(WKUP_MOD, PM_WKST))
- cpu_relax();
- cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN);
- cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN);
+ iclk = cm_read_mod_reg(module, iclk_off);
+ fclk = cm_read_mod_reg(module, fclk_off);
+ while (wkst) {
+ clken = wkst;
+ cm_set_mod_reg_bits(clken, module, iclk_off);
+ /*
+ * For USBHOST, we don't know whether HOST1 or
+ * HOST2 woke us up, so enable both f-clocks
+ */
+ if (module == OMAP3430ES2_USBHOST_MOD)
+ clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
+ cm_set_mod_reg_bits(clken, module, fclk_off);
+ prm_write_mod_reg(wkst, module, wkst_off);
+ wkst = prm_read_mod_reg(module, wkst_off);
+ c++;
+ }
+ cm_write_mod_reg(iclk, module, iclk_off);
+ cm_write_mod_reg(fclk, module, fclk_off);
}
- /* CORE */
- wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1);
- if (wkst) {
- iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
- fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
- cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN1);
- cm_set_mod_reg_bits(wkst, CORE_MOD, CM_FCLKEN1);
- prm_write_mod_reg(wkst, CORE_MOD, PM_WKST1);
- while (prm_read_mod_reg(CORE_MOD, PM_WKST1))
- cpu_relax();
- cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1);
- cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1);
- }
- wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3);
- if (wkst) {
- iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
- fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
- cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3);
- cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
- prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3);
- while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3))
- cpu_relax();
- cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3);
- cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
- }
+ return c;
+}
- /* PER */
- wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST);
- if (wkst) {
- iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
- fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
- cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_ICLKEN);
- cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_FCLKEN);
- prm_write_mod_reg(wkst, OMAP3430_PER_MOD, PM_WKST);
- while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST))
- cpu_relax();
- cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN);
- cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN);
- }
+static int _prcm_int_handle_wakeup(void)
+{
+ int c;
+ c = prcm_clear_mod_irqs(WKUP_MOD, 1);
+ c += prcm_clear_mod_irqs(CORE_MOD, 1);
+ c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
if (omap_rev() > OMAP3430_REV_ES1_0) {
- /* USBHOST */
- wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST);
- if (wkst) {
- iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
- CM_ICLKEN);
- fclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
- CM_FCLKEN);
- cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
- CM_ICLKEN);
- cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
- CM_FCLKEN);
- prm_write_mod_reg(wkst, OMAP3430ES2_USBHOST_MOD,
- PM_WKST);
- while (prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
- PM_WKST))
- cpu_relax();
- cm_write_mod_reg(iclk, OMAP3430ES2_USBHOST_MOD,
- CM_ICLKEN);
- cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD,
- CM_FCLKEN);
- }
+ c += prcm_clear_mod_irqs(CORE_MOD, 3);
+ c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
}
- irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
- OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
- prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
- OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ return c;
+}
+
+/*
+ * PRCM Interrupt Handler
+ *
+ * The PRM_IRQSTATUS_MPU register indicates if there are any pending
+ * interrupts from the PRCM for the MPU. These bits must be cleared in
+ * order to clear the PRCM interrupt. The PRCM interrupt handler is
+ * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
+ * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
+ * register indicates that a wake-up event is pending for the MPU and
+ * this bit can only be cleared if the all the wake-up events latched
+ * in the various PM_WKST_x registers have been cleared. The interrupt
+ * handler is implemented using a do-while loop so that if a wake-up
+ * event occurred during the processing of the prcm interrupt handler
+ * (setting a bit in the corresponding PM_WKST_x register and thus
+ * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
+ * this would be handled.
+ */
+static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+{
+ u32 irqstatus_mpu;
+ int c = 0;
+
+ do {
+ irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
+ if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) {
+ c = _prcm_int_handle_wakeup();
+
+ /*
+ * Is the MPU PRCM interrupt handler racing with the
+ * IVA2 PRCM interrupt handler ?
+ */
+ WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
+ "but no wakeup sources are marked\n");
+ } else {
+ /* XXX we need to expand our PRCM interrupt handler */
+ WARN(1, "prcm: WARNING: PRCM interrupt received, but "
+ "no code to handle it (%08x)\n", irqstatus_mpu);
+ }
+
+ prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
- while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET))
- cpu_relax();
+ } while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET));
return IRQ_HANDLED;
}
@@ -624,6 +639,16 @@ static void __init prcm_setup_regs(void)
prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+ /* Enable GPIO wakeups in PER */
+ prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
+ OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
+ OMAP3430_EN_GPIO6, OMAP3430_PER_MOD, PM_WKEN);
+ /* and allow them to wake up MPU */
+ prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
+ OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
+ OMAP3430_GRPSEL_GPIO6,
+ OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
+
/* Don't attach IVA interrupts */
prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 2594cbff394..f00289abd30 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -273,35 +273,50 @@ struct powerdomain *pwrdm_lookup(const char *name)
}
/**
- * pwrdm_for_each - call function on each registered clockdomain
+ * pwrdm_for_each_nolock - call function on each registered clockdomain
* @fn: callback function *
*
* Call the supplied function for each registered powerdomain. The
* callback function can return anything but 0 to bail out early from
- * the iterator. The callback function is called with the pwrdm_rwlock
- * held for reading, so no powerdomain structure manipulation
- * functions should be called from the callback, although hardware
- * powerdomain control functions are fine. Returns the last return
- * value of the callback function, which should be 0 for success or
- * anything else to indicate failure; or -EINVAL if the function
- * pointer is null.
+ * the iterator. Returns the last return value of the callback function, which
+ * should be 0 for success or anything else to indicate failure; or -EINVAL if
+ * the function pointer is null.
*/
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
- void *user)
+int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
+ void *user)
{
struct powerdomain *temp_pwrdm;
- unsigned long flags;
int ret = 0;
if (!fn)
return -EINVAL;
- read_lock_irqsave(&pwrdm_rwlock, flags);
list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
ret = (*fn)(temp_pwrdm, user);
if (ret)
break;
}
+
+ return ret;
+}
+
+/**
+ * pwrdm_for_each - call function on each registered clockdomain
+ * @fn: callback function *
+ *
+ * This function is the same as 'pwrdm_for_each_nolock()', but keeps the
+ * &pwrdm_rwlock locked for reading, so no powerdomain structure manipulation
+ * functions should be called from the callback, although hardware powerdomain
+ * control functions are fine.
+ */
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+ void *user)
+{
+ unsigned long flags;
+ int ret;
+
+ read_lock_irqsave(&pwrdm_rwlock, flags);
+ ret = pwrdm_for_each_nolock(fn, user);
read_unlock_irqrestore(&pwrdm_rwlock, flags);
return ret;
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 81ffff7ed49..4e5c07f4e45 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -71,11 +71,6 @@ config SA1100_H3600
<http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
<http://www.compaq.com/products/handhelds/pocketpc/>
-config SA1100_H3XXX
- bool
- depends on SA1100_H3100 || SA1100_H3600
- default y
-
config SA1100_BADGE4
bool "HP Labs BadgePAD 4"
select SA1111
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 95d92e8e56a..b9cbb56d6e9 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -77,7 +77,7 @@ static struct clock_event_device ckevt_sa1100_osmr0 = {
.set_mode = sa1100_osmr0_set_mode,
};
-static cycle_t sa1100_read_oscr(void)
+static cycle_t sa1100_read_oscr(struct clocksource *s)
{
return OSCR;
}
diff --git a/arch/arm/mach-u300/gpio.c b/arch/arm/mach-u300/gpio.c
index 63c8f27fb15..0b35826b7d1 100644
--- a/arch/arm/mach-u300/gpio.c
+++ b/arch/arm/mach-u300/gpio.c
@@ -281,6 +281,16 @@ int gpio_unregister_callback(unsigned gpio)
}
EXPORT_SYMBOL(gpio_unregister_callback);
+/* Non-zero means valid */
+int gpio_is_valid(int number)
+{
+ if (number >= 0 &&
+ number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT))
+ return 1;
+ return 0;
+}
+EXPORT_SYMBOL(gpio_is_valid);
+
int gpio_request(unsigned gpio, const char *label)
{
if (gpio_pin[gpio].users)
diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h
index c8174128d7e..7b1fc984abb 100644
--- a/arch/arm/mach-u300/include/mach/gpio.h
+++ b/arch/arm/mach-u300/include/mach/gpio.h
@@ -258,6 +258,7 @@
#define PIN_TO_PORT(val) (val >> 3)
/* These can be found in arch/arm/mach-u300/gpio.c */
+extern int gpio_is_valid(int number);
extern int gpio_request(unsigned gpio, const char *label);
extern void gpio_free(unsigned gpio);
extern int gpio_direction_input(unsigned gpio);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 8d43e58f924..e993140edd8 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -17,7 +17,7 @@ config CPU_ARM610
select CPU_CP15_MMU
select CPU_COPY_V3 if MMU
select CPU_TLB_V3 if MMU
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
help
The ARM610 is the successor to the ARM3 processor
and was produced by VLSI Technology Inc.
@@ -31,7 +31,7 @@ config CPU_ARM7TDMI
depends on !MMU
select CPU_32v4T
select CPU_ABRT_LV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4
help
A 32-bit RISC microprocessor based on the ARM7 processor core
@@ -49,7 +49,7 @@ config CPU_ARM710
select CPU_CP15_MMU
select CPU_COPY_V3 if MMU
select CPU_TLB_V3 if MMU
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
help
A 32-bit RISC microprocessor based on the ARM7 processor core
designed by Advanced RISC Machines Ltd. The ARM710 is the
@@ -64,7 +64,7 @@ config CPU_ARM720T
bool "Support ARM720T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_LV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@@ -83,7 +83,7 @@ config CPU_ARM740T
depends on !MMU
select CPU_32v4T
select CPU_ABRT_LV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V3 # although the core is v4t
select CPU_CP15_MPU
help
@@ -100,7 +100,7 @@ config CPU_ARM9TDMI
depends on !MMU
select CPU_32v4T
select CPU_ABRT_NOMMU
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4
help
A 32-bit RISC microprocessor based on the ARM9 processor core
@@ -114,7 +114,7 @@ config CPU_ARM920T
bool "Support ARM920T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_EV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@@ -135,7 +135,7 @@ config CPU_ARM922T
bool "Support ARM922T processor" if ARCH_INTEGRATOR
select CPU_32v4T
select CPU_ABRT_EV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@@ -154,7 +154,7 @@ config CPU_ARM925T
bool "Support ARM925T processor" if ARCH_OMAP1
select CPU_32v4T
select CPU_ABRT_EV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@@ -173,7 +173,7 @@ config CPU_ARM926T
bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB
select CPU_32v5
select CPU_ABRT_EV5TJ
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU
@@ -191,7 +191,7 @@ config CPU_FA526
bool
select CPU_32v4
select CPU_ABRT_EV4
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_CACHE_FA
@@ -210,7 +210,7 @@ config CPU_ARM940T
depends on !MMU
select CPU_32v4T
select CPU_ABRT_NOMMU
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MPU
help
@@ -228,7 +228,7 @@ config CPU_ARM946E
depends on !MMU
select CPU_32v5
select CPU_ABRT_NOMMU
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MPU
help
@@ -244,7 +244,7 @@ config CPU_ARM1020
bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@@ -262,7 +262,7 @@ config CPU_ARM1020E
bool "Support ARM1020E processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@@ -275,7 +275,7 @@ config CPU_ARM1022
bool "Support ARM1022E processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU # can probably do better
@@ -293,7 +293,7 @@ config CPU_ARM1026
bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_V4WB if MMU # can probably do better
@@ -311,7 +311,7 @@ config CPU_SA110
select CPU_32v3 if ARCH_RPC
select CPU_32v4 if !ARCH_RPC
select CPU_ABRT_EV4
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@@ -331,7 +331,7 @@ config CPU_SA1100
bool
select CPU_32v4
select CPU_ABRT_EV4
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_CP15_MMU
@@ -342,7 +342,7 @@ config CPU_XSCALE
bool
select CPU_32v5
select CPU_ABRT_EV5T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_TLB_V4WBI if MMU
@@ -352,7 +352,7 @@ config CPU_XSC3
bool
select CPU_32v5
select CPU_ABRT_EV5T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_TLB_V4WBI if MMU
@@ -363,7 +363,7 @@ config CPU_MOHAWK
bool
select CPU_32v5
select CPU_ABRT_EV5T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_TLB_V4WBI if MMU
@@ -374,7 +374,7 @@ config CPU_FEROCEON
bool
select CPU_32v5
select CPU_ABRT_EV5T
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_LEGACY
select CPU_CACHE_VIVT
select CPU_CP15_MMU
select CPU_COPY_FEROCEON if MMU
@@ -394,7 +394,7 @@ config CPU_V6
bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
select CPU_32v6
select CPU_ABRT_EV6
- select CPU_PABRT_NOIFAR
+ select CPU_PABRT_V6
select CPU_CACHE_V6
select CPU_CACHE_VIPT
select CPU_CP15_MMU
@@ -420,7 +420,7 @@ config CPU_V7
select CPU_32v6K
select CPU_32v7
select CPU_ABRT_EV7
- select CPU_PABRT_IFAR
+ select CPU_PABRT_V7
select CPU_CACHE_V7
select CPU_CACHE_VIPT
select CPU_CP15_MMU
@@ -482,10 +482,13 @@ config CPU_ABRT_EV6
config CPU_ABRT_EV7
bool
-config CPU_PABRT_IFAR
+config CPU_PABRT_LEGACY
bool
-config CPU_PABRT_NOIFAR
+config CPU_PABRT_V6
+ bool
+
+config CPU_PABRT_V7
bool
# The cache model
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 63e3f6dd0e2..055cb2aa813 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -27,6 +27,10 @@ obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o
obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o
obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o
+obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o
+obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o
+obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o
+
obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o
obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o
obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 379f7855605..ae0e25f5a70 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -519,9 +519,58 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
arm_notify_die("", regs, &info, fsr, 0);
}
+
+static struct fsr_info ifsr_info[] = {
+ { do_bad, SIGBUS, 0, "unknown 0" },
+ { do_bad, SIGBUS, 0, "unknown 1" },
+ { do_bad, SIGBUS, 0, "debug event" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "section access flag fault" },
+ { do_bad, SIGBUS, 0, "unknown 4" },
+ { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "page access flag fault" },
+ { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" },
+ { do_bad, SIGBUS, 0, "external abort on non-linefetch" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" },
+ { do_bad, SIGBUS, 0, "unknown 10" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" },
+ { do_bad, SIGBUS, 0, "external abort on translation" },
+ { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" },
+ { do_bad, SIGBUS, 0, "external abort on translation" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" },
+ { do_bad, SIGBUS, 0, "unknown 16" },
+ { do_bad, SIGBUS, 0, "unknown 17" },
+ { do_bad, SIGBUS, 0, "unknown 18" },
+ { do_bad, SIGBUS, 0, "unknown 19" },
+ { do_bad, SIGBUS, 0, "unknown 20" },
+ { do_bad, SIGBUS, 0, "unknown 21" },
+ { do_bad, SIGBUS, 0, "unknown 22" },
+ { do_bad, SIGBUS, 0, "unknown 23" },
+ { do_bad, SIGBUS, 0, "unknown 24" },
+ { do_bad, SIGBUS, 0, "unknown 25" },
+ { do_bad, SIGBUS, 0, "unknown 26" },
+ { do_bad, SIGBUS, 0, "unknown 27" },
+ { do_bad, SIGBUS, 0, "unknown 28" },
+ { do_bad, SIGBUS, 0, "unknown 29" },
+ { do_bad, SIGBUS, 0, "unknown 30" },
+ { do_bad, SIGBUS, 0, "unknown 31" },
+};
+
asmlinkage void __exception
-do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
+do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
{
- do_translation_fault(addr, FSR_LNX_PF, regs);
+ const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
+ struct siginfo info;
+
+ if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
+ return;
+
+ printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
+ inf->name, ifsr, addr);
+
+ info.si_signo = inf->sig;
+ info.si_errno = 0;
+ info.si_code = inf->code;
+ info.si_addr = (void __user *)addr;
+ arm_notify_die("", regs, &info, ifsr, 0);
}
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index f7457fea6de..2b7996401b0 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -124,7 +124,7 @@ int valid_phys_addr_range(unsigned long addr, size_t size)
{
if (addr < PHYS_OFFSET)
return 0;
- if (addr + size >= __pa(high_memory - 1))
+ if (addr + size > __pa(high_memory - 1) + 1)
return 0;
return 1;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4426ee67cec..02243eeccf5 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -21,6 +21,7 @@
#include <asm/cachetype.h>
#include <asm/setup.h>
#include <asm/sizes.h>
+#include <asm/smp_plat.h>
#include <asm/tlb.h>
#include <asm/highmem.h>
@@ -709,10 +710,6 @@ static void __init sanity_check_meminfo(void)
if (meminfo.nr_banks >= NR_BANKS) {
printk(KERN_CRIT "NR_BANKS too low, "
"ignoring high memory\n");
- } else if (cache_is_vipt_aliasing()) {
- printk(KERN_CRIT "HIGHMEM is not yet supported "
- "with VIPT aliasing cache, "
- "ignoring high memory\n");
} else {
memmove(bank + 1, bank,
(meminfo.nr_banks - i) * sizeof(*bank));
@@ -726,6 +723,8 @@ static void __init sanity_check_meminfo(void)
bank->size = VMALLOC_MIN - __va(bank->start);
}
#else
+ bank->highmem = highmem;
+
/*
* Check whether this memory bank would entirely overlap
* the vmalloc area.
@@ -754,6 +753,38 @@ static void __init sanity_check_meminfo(void)
#endif
j++;
}
+#ifdef CONFIG_HIGHMEM
+ if (highmem) {
+ const char *reason = NULL;
+
+ if (cache_is_vipt_aliasing()) {
+ /*
+ * Interactions between kmap and other mappings
+ * make highmem support with aliasing VIPT caches
+ * rather difficult.
+ */
+ reason = "with VIPT aliasing cache";
+#ifdef CONFIG_SMP
+ } else if (tlb_ops_need_broadcast()) {
+ /*
+ * kmap_high needs to occasionally flush TLB entries,
+ * however, if the TLB entries need to be broadcast
+ * we may deadlock:
+ * kmap_high(irqs off)->flush_all_zero_pkmaps->
+ * flush_tlb_kernel_range->smp_call_function_many
+ * (must not be called with irqs off)
+ */
+ reason = "without hardware TLB ops broadcasting";
+#endif
+ }
+ if (reason) {
+ printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n",
+ reason);
+ while (j > 0 && meminfo.bank[j - 1].highmem)
+ j--;
+ }
+ }
+#endif
meminfo.nr_banks = j;
}
diff --git a/arch/arm/mm/pabort-legacy.S b/arch/arm/mm/pabort-legacy.S
new file mode 100644
index 00000000000..87970eba88e
--- /dev/null
+++ b/arch/arm/mm/pabort-legacy.S
@@ -0,0 +1,19 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: legacy_pabort
+ *
+ * Params : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ * : r1 = Simulated IFSR with section translation fault status
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+ .align 5
+ENTRY(legacy_pabort)
+ mov r1, #5
+ mov pc, lr
+ENDPROC(legacy_pabort)
diff --git a/arch/arm/mm/pabort-v6.S b/arch/arm/mm/pabort-v6.S
new file mode 100644
index 00000000000..06e3d1ef211
--- /dev/null
+++ b/arch/arm/mm/pabort-v6.S
@@ -0,0 +1,19 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: v6_pabort
+ *
+ * Params : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ * : r1 = IFSR
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+ .align 5
+ENTRY(v6_pabort)
+ mrc p15, 0, r1, c5, c0, 1 @ get IFSR
+ mov pc, lr
+ENDPROC(v6_pabort)
diff --git a/arch/arm/mm/pabort-v7.S b/arch/arm/mm/pabort-v7.S
new file mode 100644
index 00000000000..a8b3b300a18
--- /dev/null
+++ b/arch/arm/mm/pabort-v7.S
@@ -0,0 +1,20 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: v6_pabort
+ *
+ * Params : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ * : r1 = IFSR
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+ .align 5
+ENTRY(v7_pabort)
+ mrc p15, 0, r0, c6, c0, 2 @ get IFAR
+ mrc p15, 0, r1, c5, c0, 1 @ get IFSR
+ mov pc, lr
+ENDPROC(v7_pabort)
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index b5551bf010a..d9fb4b98c49 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -449,7 +449,7 @@ arm1020_crval:
.type arm1020_processor_functions, #object
arm1020_processor_functions:
.word v4t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm1020_proc_init
.word cpu_arm1020_proc_fin
.word cpu_arm1020_reset
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 8bc6740c29e..7453b75dcea 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -430,7 +430,7 @@ arm1020e_crval:
.type arm1020e_processor_functions, #object
arm1020e_processor_functions:
.word v4t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm1020e_proc_init
.word cpu_arm1020e_proc_fin
.word cpu_arm1020e_reset
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 2cd03e66c0a..8eb72d75a8b 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -413,7 +413,7 @@ arm1022_crval:
.type arm1022_processor_functions, #object
arm1022_processor_functions:
.word v4t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm1022_proc_init
.word cpu_arm1022_proc_fin
.word cpu_arm1022_reset
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index ad961a897f6..3b59f0d6713 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -408,7 +408,7 @@ arm1026_crval:
.type arm1026_processor_functions, #object
arm1026_processor_functions:
.word v5t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm1026_proc_init
.word cpu_arm1026_proc_fin
.word cpu_arm1026_reset
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 80d6e1de069..3f9cd3d8f6d 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -278,7 +278,7 @@ __arm7_setup: mov r0, #0
.type arm6_processor_functions, #object
ENTRY(arm6_processor_functions)
.word cpu_arm6_data_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm6_proc_init
.word cpu_arm6_proc_fin
.word cpu_arm6_reset
@@ -295,7 +295,7 @@ ENTRY(arm6_processor_functions)
.type arm7_processor_functions, #object
ENTRY(arm7_processor_functions)
.word cpu_arm7_data_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm7_proc_init
.word cpu_arm7_proc_fin
.word cpu_arm7_reset
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 85ae18695f1..0b62de24466 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -181,7 +181,7 @@ arm720_crval:
.type arm720_processor_functions, #object
ENTRY(arm720_processor_functions)
.word v4t_late_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm720_proc_init
.word cpu_arm720_proc_fin
.word cpu_arm720_reset
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 4f95bee63e9..01860cdeb2e 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -126,7 +126,7 @@ __arm740_setup:
.type arm740_processor_functions, #object
ENTRY(arm740_processor_functions)
.word v4t_late_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm740_proc_init
.word cpu_arm740_proc_fin
.word cpu_arm740_reset
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 93e05fa7bed..1201b986382 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -64,7 +64,7 @@ __arm7tdmi_setup:
.type arm7tdmi_processor_functions, #object
ENTRY(arm7tdmi_processor_functions)
.word v4t_late_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm7tdmi_proc_init
.word cpu_arm7tdmi_proc_fin
.word cpu_arm7tdmi_reset
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 914d688394f..2b7c197cc58 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -395,7 +395,7 @@ arm920_crval:
.type arm920_processor_functions, #object
arm920_processor_functions:
.word v4t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm920_proc_init
.word cpu_arm920_proc_fin
.word cpu_arm920_reset
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 51c9c9859e5..06a1aa4e339 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -399,7 +399,7 @@ arm922_crval:
.type arm922_processor_functions, #object
arm922_processor_functions:
.word v4t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm922_proc_init
.word cpu_arm922_proc_fin
.word cpu_arm922_reset
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 2724526d89c..cb53435a85a 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -462,7 +462,7 @@ arm925_crval:
.type arm925_processor_functions, #object
arm925_processor_functions:
.word v4t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm925_proc_init
.word cpu_arm925_proc_fin
.word cpu_arm925_reset
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 54466937bff..1c4848704bb 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -415,7 +415,7 @@ arm926_crval:
.type arm926_processor_functions, #object
arm926_processor_functions:
.word v5tj_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm926_proc_init
.word cpu_arm926_proc_fin
.word cpu_arm926_reset
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index f595117caf5..5b0f8464c8f 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -322,7 +322,7 @@ __arm940_setup:
.type arm940_processor_functions, #object
ENTRY(arm940_processor_functions)
.word nommu_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm940_proc_init
.word cpu_arm940_proc_fin
.word cpu_arm940_reset
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index e03f6ff1fb2..40c0449a139 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -377,7 +377,7 @@ __arm946_setup:
.type arm946_processor_functions, #object
ENTRY(arm946_processor_functions)
.word nommu_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm946_proc_init
.word cpu_arm946_proc_fin
.word cpu_arm946_reset
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index be6c11d2b3f..28545c29dbc 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -64,7 +64,7 @@ __arm9tdmi_setup:
.type arm9tdmi_processor_functions, #object
ENTRY(arm9tdmi_processor_functions)
.word nommu_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_arm9tdmi_proc_init
.word cpu_arm9tdmi_proc_fin
.word cpu_arm9tdmi_reset
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 08b8a955d5d..08f5ac237ad 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -191,7 +191,7 @@ fa526_cr1_set:
.type fa526_processor_functions, #object
fa526_processor_functions:
.word v4_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_fa526_proc_init
.word cpu_fa526_proc_fin
.word cpu_fa526_reset
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 0fe1f8fc348..d0d7795200f 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -499,7 +499,7 @@ feroceon_crval:
.type feroceon_processor_functions, #object
feroceon_processor_functions:
.word v5t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_feroceon_proc_init
.word cpu_feroceon_proc_fin
.word cpu_feroceon_reset
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 540f5078496..52b5fd74fbb 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -359,7 +359,7 @@ mohawk_crval:
.type mohawk_processor_functions, #object
mohawk_processor_functions:
.word v5t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_mohawk_proc_init
.word cpu_mohawk_proc_fin
.word cpu_mohawk_reset
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 90a7e5279f2..7b706b38990 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -199,7 +199,7 @@ sa110_crval:
.type sa110_processor_functions, #object
ENTRY(sa110_processor_functions)
.word v4_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_sa110_proc_init
.word cpu_sa110_proc_fin
.word cpu_sa110_reset
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 451e2d953e2..ee7700242c1 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -214,7 +214,7 @@ sa1100_crval:
.type sa1100_processor_functions, #object
ENTRY(sa1100_processor_functions)
.word v4_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_sa1100_proc_init
.word cpu_sa1100_proc_fin
.word cpu_sa1100_reset
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 524ddae9259..194737d60a2 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -191,7 +191,7 @@ v6_crval:
.type v6_processor_functions, #object
ENTRY(v6_processor_functions)
.word v6_early_abort
- .word pabort_noifar
+ .word v6_pabort
.word cpu_v6_proc_init
.word cpu_v6_proc_fin
.word cpu_v6_reset
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index f3fa1c32fe9..23ebcf6eab9 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -295,7 +295,7 @@ __v7_setup_stack:
.type v7_processor_functions, #object
ENTRY(v7_processor_functions)
.word v7_early_abort
- .word pabort_ifar
+ .word v7_pabort
.word cpu_v7_proc_init
.word cpu_v7_proc_fin
.word cpu_v7_reset
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 33515c214b9..2028f370288 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -428,7 +428,7 @@ xsc3_crval:
.type xsc3_processor_functions, #object
ENTRY(xsc3_processor_functions)
.word v5t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_xsc3_proc_init
.word cpu_xsc3_proc_fin
.word cpu_xsc3_reset
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 423394260bc..f056c283682 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -511,7 +511,7 @@ xscale_crval:
.type xscale_processor_functions, #object
ENTRY(xscale_processor_functions)
.word v5t_early_abort
- .word pabort_noifar
+ .word legacy_pabort
.word cpu_xscale_proc_init
.word cpu_xscale_proc_fin
.word cpu_xscale_reset
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index 77fa7cc7d16..ce31f316ac7 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -257,7 +257,8 @@ void __init iop3xx_atu_setup(void)
*IOP3XX_OUMWTVR0 = 0;
/* Outbound window 1 */
- *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_BA + IOP3XX_PCI_MEM_WINDOW_SIZE;
+ *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_BA +
+ IOP3XX_PCI_MEM_WINDOW_SIZE / 2;
*IOP3XX_OUMWTVR1 = 0;
/* BAR 3 ( Disabled ) */
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index 3695bbe3ee2..8da95d57c21 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -85,7 +85,7 @@ void __init iop_init_time(unsigned long tick_rate)
{
u32 timer_ctl;
- ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
+ ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
ticks_per_usec = tick_rate / 1000000;
next_jiffy_time = 0xffffffff;
iop_tick_rate = tick_rate;
diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h
index 11e73d9e892..f129efb3075 100644
--- a/arch/arm/plat-omap/include/mach/cpu.h
+++ b/arch/arm/plat-omap/include/mach/cpu.h
@@ -303,32 +303,21 @@ IS_OMAP_TYPE(3430, 0x3430)
#define cpu_is_omap2430() 0
#define cpu_is_omap3430() 0
-#if defined(MULTI_OMAP1)
-# if defined(CONFIG_ARCH_OMAP730)
-# undef cpu_is_omap730
-# define cpu_is_omap730() is_omap730()
-# endif
-# if defined(CONFIG_ARCH_OMAP850)
-# undef cpu_is_omap850
-# define cpu_is_omap850() is_omap850()
-# endif
-#else
-# if defined(CONFIG_ARCH_OMAP730)
-# undef cpu_is_omap730
-# define cpu_is_omap730() 1
-# endif
-#endif
-#else
-# if defined(CONFIG_ARCH_OMAP850)
-# undef cpu_is_omap850
-# define cpu_is_omap850() 1
-# endif
-#endif
-
/*
* Whether we have MULTI_OMAP1 or not, we still need to distinguish
- * between 330 vs. 1510 and 1611B/5912 vs. 1710.
+ * between 730 vs 850, 330 vs. 1510 and 1611B/5912 vs. 1710.
*/
+
+#if defined(CONFIG_ARCH_OMAP730)
+# undef cpu_is_omap730
+# define cpu_is_omap730() is_omap730()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP850)
+# undef cpu_is_omap850
+# define cpu_is_omap850() is_omap850()
+#endif
+
#if defined(CONFIG_ARCH_OMAP15XX)
# undef cpu_is_omap310
# undef cpu_is_omap1510
@@ -433,3 +422,5 @@ IS_OMAP_TYPE(3430, 0x3430)
int omap_chip_is(struct omap_chip_id oci);
void omap2_check_revision(void);
+
+#endif
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h
index 6271d8556a4..fa6461423bd 100644
--- a/arch/arm/plat-omap/include/mach/powerdomain.h
+++ b/arch/arm/plat-omap/include/mach/powerdomain.h
@@ -135,6 +135,8 @@ struct powerdomain *pwrdm_lookup(const char *name);
int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
void *user);
+int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
+ void *user);
int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 57f7122a091..dc3fac3dd0e 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -47,7 +47,7 @@
* 'va': mpu virtual address
*
* 'c': contiguous memory area
- * 'd': dicontiguous memory area
+ * 'd': discontiguous memory area
* 'a': anonymous memory allocation
* '()': optional feature
*
@@ -363,8 +363,9 @@ void *da_to_va(struct iommu *obj, u32 da)
goto out;
}
va = area->va;
- mutex_unlock(&obj->mmap_lock);
out:
+ mutex_unlock(&obj->mmap_lock);
+
return va;
}
EXPORT_SYMBOL_GPL(da_to_va);
@@ -398,7 +399,7 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
{
/*
* Actually this is not necessary at all, just exists for
- * consistency of the code readibility.
+ * consistency of the code readability.
*/
BUG_ON(!sgt);
}
@@ -434,7 +435,7 @@ static inline void sgtable_drain_kmalloc(struct sg_table *sgt)
{
/*
* Actually this is not necessary at all, just exists for
- * consistency of the code readibility
+ * consistency of the code readability
*/
BUG_ON(!sgt);
}
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 925f64711c3..75d1f26e5b1 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -270,7 +270,8 @@ void * omap_sram_push(void * start, unsigned long size)
omap_sram_ceil -= size;
omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
memcpy((void *)omap_sram_ceil, start, size);
- flush_icache_range((unsigned long)start, (unsigned long)(start + size));
+ flush_icache_range((unsigned long)omap_sram_ceil,
+ (unsigned long)(omap_sram_ceil + size));
return (void *)omap_sram_ceil;
}
diff --git a/arch/arm/plat-s3c24xx/include/plat/mci.h b/arch/arm/plat-s3c24xx/include/plat/mci.h
index 2d0852ac3b2..c2cef613968 100644
--- a/arch/arm/plat-s3c24xx/include/plat/mci.h
+++ b/arch/arm/plat-s3c24xx/include/plat/mci.h
@@ -2,8 +2,11 @@
#define _ARCH_MCI_H
struct s3c24xx_mci_pdata {
+ unsigned int no_wprotect : 1;
+ unsigned int no_detect : 1;
unsigned int wprotect_invert : 1;
unsigned int detect_invert : 1; /* set => detect active high. */
+ unsigned int use_dma : 1;
unsigned int gpio_detect;
unsigned int gpio_wprotect;
diff --git a/arch/blackfin/ADI_BSD.txt b/arch/blackfin/ADI_BSD.txt
new file mode 100644
index 00000000000..501d0b64594
--- /dev/null
+++ b/arch/blackfin/ADI_BSD.txt
@@ -0,0 +1,41 @@
+This BSD-Style License applies to a few files in ./arch/blackfin directory,
+and is included here, so people understand which code they can use outside
+the Linux kernel, in non-GPL based projects.
+
+Using the files released under the "ADI BSD" license, must comply with
+these license terms.
+
+--------------------------------------------------------------------------
+
+Copyright Analog Devices, Inc.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ - Neither the name of Analog Devices, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ - The use of this software may or may not infringe the patent rights
+ of one or more patent holders. This license does not release you
+ from the requirement that you obtain separate licenses from these
+ patent holders to use this software.
+
+THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 9a01d445eca..ae6a60f1012 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -47,6 +47,9 @@ config GENERIC_HARDIRQS
config GENERIC_IRQ_PROBE
def_bool y
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ def_bool y
+
config GENERIC_GPIO
def_bool y
@@ -229,7 +232,7 @@ endchoice
config SMP
depends on BF561
- select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
bool "Symmetric multi-processing support"
---help---
This enables support for systems with more than one CPU,
@@ -613,12 +616,10 @@ comment "Kernel Timer/Scheduler"
source kernel/Kconfig.hz
config GENERIC_TIME
- bool "Generic time"
- default y
+ def_bool y
config GENERIC_CLOCKEVENTS
bool "Generic clock events"
- depends on GENERIC_TIME
default y
choice
@@ -653,6 +654,10 @@ config GPTMR0_CLOCKSOURCE
depends on GENERIC_CLOCKEVENTS
depends on !TICKSOURCE_GPTMR0
+config ARCH_USES_GETTIMEOFFSET
+ depends on !GENERIC_CLOCKEVENTS
+ def_bool y
+
source kernel/time/Kconfig
comment "Misc"
diff --git a/arch/blackfin/include/asm/atomic.h b/arch/blackfin/include/asm/atomic.h
index 88f36d599fe..d27c6274247 100644
--- a/arch/blackfin/include/asm/atomic.h
+++ b/arch/blackfin/include/asm/atomic.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __ARCH_BLACKFIN_ATOMIC__
#define __ARCH_BLACKFIN_ATOMIC__
diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h
index aef0594e786..10064f902d2 100644
--- a/arch/blackfin/include/asm/bfin-global.h
+++ b/arch/blackfin/include/asm/bfin-global.h
@@ -1,29 +1,9 @@
/*
- * File: include/asm-blackfin/bfin-global.h
- * Based on:
- * Author: *
- * Created:
- * Description: Global extern defines for blackfin
+ * Global extern defines for blackfin
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
+ * Copyright 2006-2009 Analog Devices Inc.
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BFIN_GLOBAL_H_
diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h
index c281c632827..ed4f8c6db0c 100644
--- a/arch/blackfin/include/asm/bfin5xx_spi.h
+++ b/arch/blackfin/include/asm/bfin5xx_spi.h
@@ -3,8 +3,6 @@
*
* Copyright 2004-2008 Analog Devices Inc.
*
- * Enter bugs at http://blackfin.uclinux.org/
- *
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/include/asm/bfin_rotary.h b/arch/blackfin/include/asm/bfin_rotary.h
index 425ece64fd5..abdb2af5290 100644
--- a/arch/blackfin/include/asm/bfin_rotary.h
+++ b/arch/blackfin/include/asm/bfin_rotary.h
@@ -1,6 +1,10 @@
/*
* board initialization should put one of these structures into platform_data
* and place the bfin-rotary onto platform_bus named "bfin-rotary".
+ *
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BFIN_ROTARY_H
diff --git a/arch/blackfin/include/asm/bfin_simple_timer.h b/arch/blackfin/include/asm/bfin_simple_timer.h
index fccbb595464..5248c133bc6 100644
--- a/arch/blackfin/include/asm/bfin_simple_timer.h
+++ b/arch/blackfin/include/asm/bfin_simple_timer.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2006-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _bfin_simple_timer_h_
#define _bfin_simple_timer_h_
diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h
index daffa71576d..a2ff3fb3568 100644
--- a/arch/blackfin/include/asm/bitops.h
+++ b/arch/blackfin/include/asm/bitops.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_BITOPS_H
#define _BLACKFIN_BITOPS_H
diff --git a/arch/blackfin/include/asm/blackfin.h b/arch/blackfin/include/asm/blackfin.h
index 4d443958339..eb7c1441d8f 100644
--- a/arch/blackfin/include/asm/blackfin.h
+++ b/arch/blackfin/include/asm/blackfin.h
@@ -1,6 +1,9 @@
/*
- * Common header file for blackfin family of processors.
+ * Common header file for Blackfin family of processors.
*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BLACKFIN_H_
diff --git a/arch/blackfin/include/asm/bug.h b/arch/blackfin/include/asm/bug.h
index 655e49540e4..6f4548a1355 100644
--- a/arch/blackfin/include/asm/bug.h
+++ b/arch/blackfin/include/asm/bug.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_BUG_H
#define _BLACKFIN_BUG_H
diff --git a/arch/blackfin/include/asm/byteorder.h b/arch/blackfin/include/asm/byteorder.h
index 3e69106a4d3..9558416d578 100644
--- a/arch/blackfin/include/asm/byteorder.h
+++ b/arch/blackfin/include/asm/byteorder.h
@@ -1,6 +1 @@
-#ifndef _BLACKFIN_BYTEORDER_H
-#define _BLACKFIN_BYTEORDER_H
-
#include <linux/byteorder/little_endian.h>
-
-#endif /* _BLACKFIN_BYTEORDER_H */
diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h
index 477050ad5c5..8542bc31f63 100644
--- a/arch/blackfin/include/asm/cache.h
+++ b/arch/blackfin/include/asm/cache.h
@@ -1,6 +1,9 @@
/*
- * include/asm-blackfin/cache.h
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
+
#ifndef __ARCH_BLACKFIN_CACHE_H
#define __ARCH_BLACKFIN_CACHE_H
@@ -35,10 +38,10 @@
#if defined(CONFIG_SMP) && \
!defined(CONFIG_BFIN_CACHE_COHERENT)
-# if defined(CONFIG_BFIN_ICACHEABLE) || defined(CONFIG_BFIN_L2_ICACHEABLE)
+# if defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) || defined(CONFIG_BFIN_L2_ICACHEABLE)
# define __ARCH_SYNC_CORE_ICACHE
# endif
-# if defined(CONFIG_BFIN_DCACHEABLE) || defined(CONFIG_BFIN_L2_DCACHEABLE)
+# if defined(CONFIG_BFIN_EXTMEM_DCACHEABLE) || defined(CONFIG_BFIN_L2_DCACHEABLE)
# define __ARCH_SYNC_CORE_DCACHE
# endif
#ifndef __ASSEMBLY__
diff --git a/arch/blackfin/include/asm/cacheflush.h b/arch/blackfin/include/asm/cacheflush.h
index 7e55549e180..af03a36c7a4 100644
--- a/arch/blackfin/include/asm/cacheflush.h
+++ b/arch/blackfin/include/asm/cacheflush.h
@@ -1,30 +1,9 @@
/*
- * File: include/asm-blackfin/cacheflush.h
- * Based on: include/asm-m68knommu/cacheflush.h
- * Author: LG Soft India
- * Copyright (C) 2004 Analog Devices Inc.
- * Created: Tue Sep 21 2004
- * Description: Blackfin low-level cache routines adapted from the i386
- * and PPC versions by Greg Ungerer (gerg@snapgear.com)
+ * Blackfin low-level cache routines
*
- * Modified:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BLACKFIN_CACHEFLUSH_H
diff --git a/arch/blackfin/include/asm/cdef_LPBlackfin.h b/arch/blackfin/include/asm/cdef_LPBlackfin.h
index 35f841bce57..8778e0f0373 100644
--- a/arch/blackfin/include/asm/cdef_LPBlackfin.h
+++ b/arch/blackfin/include/asm/cdef_LPBlackfin.h
@@ -1,30 +1,8 @@
- /*
- * File: include/asm-blackfin/mach-common/cdef_LPBlackfin.h
- * Based on:
- * Author: unknown
- * COPYRIGHT 2005 Analog Devices
- * Created: ?
- * Description:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
+/*
+ * Copyright 2005-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
#ifndef _CDEF_LPBLACKFIN_H
#define _CDEF_LPBLACKFIN_H
diff --git a/arch/blackfin/include/asm/checksum.h b/arch/blackfin/include/asm/checksum.h
index 793581fc955..a23415be0de 100644
--- a/arch/blackfin/include/asm/checksum.h
+++ b/arch/blackfin/include/asm/checksum.h
@@ -1,9 +1,14 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ * akbar.hussain@lineo.com
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BFIN_CHECKSUM_H
#define _BFIN_CHECKSUM_H
/*
- * MODIFIED FOR BFIN April 30, 2001 akbar.hussain@lineo.com
- *
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
diff --git a/arch/blackfin/include/asm/clocks.h b/arch/blackfin/include/asm/clocks.h
index 033bba92d61..f80dad5ff25 100644
--- a/arch/blackfin/include/asm/clocks.h
+++ b/arch/blackfin/include/asm/clocks.h
@@ -1,30 +1,9 @@
/*
- * File: include/asm-blackfin/mach-common/clocks.h
- * Based on: include/asm-blackfin/mach-bf537/bf537.h
- * Author: Robin Getz <rgetz@blackfin.uclinux.org>
+ * Common Clock definitions for various kernel files
*
- * Created: 25Jul07
- * Description: Common Clock definitions for various kernel files
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BFIN_CLOCKS_H
diff --git a/arch/blackfin/include/asm/context.S b/arch/blackfin/include/asm/context.S
index f8a664f022b..5dffaf582a2 100644
--- a/arch/blackfin/include/asm/context.S
+++ b/arch/blackfin/include/asm/context.S
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/context.S
- * Based on:
- * Author:
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
/*
diff --git a/arch/blackfin/include/asm/cplb.h b/arch/blackfin/include/asm/cplb.h
index d18d16837a6..fda96261ed6 100644
--- a/arch/blackfin/include/asm/cplb.h
+++ b/arch/blackfin/include/asm/cplb.h
@@ -1,30 +1,7 @@
/*
- * File: include/asm-blackfin/cplb.h
- * Based on: include/asm-blackfin/mach-bf537/bf537.h
- * Author: Robin Getz <rgetz@blackfin.uclinux.org>
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created: 2000
- * Description: Common CPLB definitions for CPLB init
- *
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CPLB_H
diff --git a/arch/blackfin/include/asm/cplbinit.h b/arch/blackfin/include/asm/cplbinit.h
index 05b14a631d0..f315c83a015 100644
--- a/arch/blackfin/include/asm/cplbinit.h
+++ b/arch/blackfin/include/asm/cplbinit.h
@@ -1,30 +1,9 @@
/*
- * File: include/asm-blackfin/cplbinit.h
- * Based on:
- * Author:
+ * Common CPLB definitions for CPLB init
*
- * Created:
- * Description:
+ * Copyright 2006-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __ASM_CPLBINIT_H__
diff --git a/arch/blackfin/include/asm/cpu.h b/arch/blackfin/include/asm/cpu.h
index fadfa82f93b..b191dc662bd 100644
--- a/arch/blackfin/include/asm/cpu.h
+++ b/arch/blackfin/include/asm/cpu.h
@@ -1,23 +1,8 @@
/*
- * File: arch/blackfin/include/asm/cpu.h.
- * Author: Philippe Gerum <rpm@xenomai.org>
+ * Copyright 2007-2009 Analog Devices Inc.
+ * Philippe Gerum <rpm@xenomai.org>
*
- * Copyright 2007 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __ASM_BLACKFIN_CPU_H
diff --git a/arch/blackfin/include/asm/def_LPBlackfin.h b/arch/blackfin/include/asm/def_LPBlackfin.h
index 6341eebff3d..25906468622 100644
--- a/arch/blackfin/include/asm/def_LPBlackfin.h
+++ b/arch/blackfin/include/asm/def_LPBlackfin.h
@@ -1,32 +1,10 @@
- /*
- * File: include/asm-blackfin/mach-common/def_LPBlackfin.h
- * Based on:
- * Author: unknown
- * COPYRIGHT 2005 Analog Devices
- * Created: ?
- * Description:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/* LP Blackfin CORE REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532/33 */
+/*
+ * Blackfin core register bit & address definitions
+ *
+ * Copyright 2005-2008 Analog Devices Inc.
+ *
+ * Licensed under the ADI BSD license or GPL-2 (or later).
+ */
#ifndef _DEF_LPBLACKFIN_H
#define _DEF_LPBLACKFIN_H
diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h
index ed6b1f3cccc..7a23d824ac9 100644
--- a/arch/blackfin/include/asm/dma-mapping.h
+++ b/arch/blackfin/include/asm/dma-mapping.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_DMA_MAPPING_H
#define _BLACKFIN_DMA_MAPPING_H
diff --git a/arch/blackfin/include/asm/dpmc.h b/arch/blackfin/include/asm/dpmc.h
index 96e8208f929..925e66cb2d4 100644
--- a/arch/blackfin/include/asm/dpmc.h
+++ b/arch/blackfin/include/asm/dpmc.h
@@ -1,9 +1,11 @@
/*
- * include/asm-blackfin/dpmc.h - Miscellaneous IOCTL commands for Dynamic Power
- * Management Controller Driver.
+ * Miscellaneous IOCTL commands for Dynamic Power Management Controller Driver
+ *
* Copyright (C) 2004-2008 Analog Device Inc.
*
+ * Licensed under the GPL-2
*/
+
#ifndef _BLACKFIN_DPMC_H_
#define _BLACKFIN_DPMC_H_
diff --git a/arch/blackfin/include/asm/early_printk.h b/arch/blackfin/include/asm/early_printk.h
index 53a762b6fcd..68a910db886 100644
--- a/arch/blackfin/include/asm/early_printk.h
+++ b/arch/blackfin/include/asm/early_printk.h
@@ -1,27 +1,11 @@
/*
- * File: include/asm-blackfin/early_printk.h
- * Author: Robin Getz <rgetz@blackfin.uclinux.org
+ * function prototpyes for early printk
*
- * Created: 14Aug2007
- * Description: function prototpyes for early printk
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Licensed under the GPL-2 or later.
*/
-
#ifndef __ASM_EARLY_PRINTK_H__
#define __ASM_EARLY_PRINTK_H__
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index c823e8ebbfa..8e0764c81ea 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -1,4 +1,8 @@
-/* Changes made by LG Soft Oct 2004*/
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
#ifndef __ASMBFIN_ELF_H
#define __ASMBFIN_ELF_H
diff --git a/arch/blackfin/include/asm/entry.h b/arch/blackfin/include/asm/entry.h
index 55b808fced7..a6886f6e481 100644
--- a/arch/blackfin/include/asm/entry.h
+++ b/arch/blackfin/include/asm/entry.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __BFIN_ENTRY_H
#define __BFIN_ENTRY_H
diff --git a/arch/blackfin/include/asm/fcntl.h b/arch/blackfin/include/asm/fcntl.h
index 9c403712785..8727b2b382f 100644
--- a/arch/blackfin/include/asm/fcntl.h
+++ b/arch/blackfin/include/asm/fcntl.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BFIN_FCNTL_H
#define _BFIN_FCNTL_H
diff --git a/arch/blackfin/include/asm/fixed_code.h b/arch/blackfin/include/asm/fixed_code.h
index 32c4d495d84..73fe53e7fd2 100644
--- a/arch/blackfin/include/asm/fixed_code.h
+++ b/arch/blackfin/include/asm/fixed_code.h
@@ -1,5 +1,11 @@
-/* This file defines the fixed addresses where userspace programs can find
- atomic code sequences. */
+/*
+ * This file defines the fixed addresses where userspace programs
+ * can find atomic code sequences.
+ *
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
#ifndef __BFIN_ASM_FIXED_CODE_H__
#define __BFIN_ASM_FIXED_CODE_H__
diff --git a/arch/blackfin/include/asm/flat.h b/arch/blackfin/include/asm/flat.h
index 733a178d782..c1314c56dd1 100644
--- a/arch/blackfin/include/asm/flat.h
+++ b/arch/blackfin/include/asm/flat.h
@@ -1,8 +1,9 @@
/*
- * include/asm-blackfin/flat.h -- uClinux flat-format executables
+ * uClinux flat-format executables
*
- * Copyright (C) 2003,
+ * Copyright 2003-2009 Analog Devices Inc.
*
+ * Licensed under the GPL-2
*/
#ifndef __BLACKFIN_FLAT_H__
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h
index fe139619351..5b44d05ca53 100644
--- a/arch/blackfin/include/asm/gpio.h
+++ b/arch/blackfin/include/asm/gpio.h
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/bfin_gpio.h
- * Based on:
- * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
+ * Copyright 2006-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __ARCH_BLACKFIN_GPIO_H__
diff --git a/arch/blackfin/include/asm/hardirq.h b/arch/blackfin/include/asm/hardirq.h
index 0b78b873df5..c078dd78d99 100644
--- a/arch/blackfin/include/asm/hardirq.h
+++ b/arch/blackfin/include/asm/hardirq.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __BFIN_HARDIRQ_H
#define __BFIN_HARDIRQ_H
diff --git a/arch/blackfin/include/asm/io.h b/arch/blackfin/include/asm/io.h
index 37053eca200..d1f5029189a 100644
--- a/arch/blackfin/include/asm/io.h
+++ b/arch/blackfin/include/asm/io.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BFIN_IO_H
#define _BFIN_IO_H
diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h
index 42a15f5ce0d..e7c0623f909 100644
--- a/arch/blackfin/include/asm/irq.h
+++ b/arch/blackfin/include/asm/irq.h
@@ -1,17 +1,10 @@
/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2003 HuTao
+ * 2002 Arcturus Networks Inc. (www.arcturusnetworks.com
+ * Ted Ma <mated@sympatico.ca>
*
- * Changed by HuTao Apr18, 2003
- *
- * Copyright was missing when I got the code so took from MIPS arch ...MaTed---
- * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
- * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle
- *
- * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
- * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
- * Copyright (c) 2002 Lineo, Inc. <mattw@lineo.com>
+ * Licensed under the GPL-2
*/
#ifndef _BFIN_IRQ_H_
@@ -19,6 +12,8 @@
#include <linux/irqflags.h>
+#include <mach/anomaly.h>
+
/* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */
#include <mach/irq.h>
diff --git a/arch/blackfin/include/asm/irq_handler.h b/arch/blackfin/include/asm/irq_handler.h
index 7d9e2d3bbed..7fbe42307b9 100644
--- a/arch/blackfin/include/asm/irq_handler.h
+++ b/arch/blackfin/include/asm/irq_handler.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _IRQ_HANDLER_H
#define _IRQ_HANDLER_H
diff --git a/arch/blackfin/include/asm/l1layout.h b/arch/blackfin/include/asm/l1layout.h
index 79dbefaa5be..c87e68647a2 100644
--- a/arch/blackfin/include/asm/l1layout.h
+++ b/arch/blackfin/include/asm/l1layout.h
@@ -1,6 +1,9 @@
/*
- * l1layout.h
* Defines a layout of L1 scratchpad memory that userspace can rely on.
+ *
+ * Copyright 2006-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
#ifndef _L1LAYOUT_H_
diff --git a/arch/blackfin/include/asm/linkage.h b/arch/blackfin/include/asm/linkage.h
index 5a822bb790f..f7d6d47a048 100644
--- a/arch/blackfin/include/asm/linkage.h
+++ b/arch/blackfin/include/asm/linkage.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __ASM_LINKAGE_H
#define __ASM_LINKAGE_H
diff --git a/arch/blackfin/include/asm/mmu.h b/arch/blackfin/include/asm/mmu.h
index dbfd686360e..26f6b70b11e 100644
--- a/arch/blackfin/include/asm/mmu.h
+++ b/arch/blackfin/include/asm/mmu.h
@@ -1,8 +1,13 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2002 David McCullough <davidm@snapgear.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
#ifndef __MMU_H
#define __MMU_H
-/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
-
struct sram_list_struct {
struct sram_list_struct *next;
void *addr;
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index 040410bb07e..4a3be376ad5 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -1,30 +1,7 @@
/*
- * File: include/asm-blackfin/mmu_context.h
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __BLACKFIN_MMU_CONTEXT_H__
diff --git a/arch/blackfin/include/asm/module.h b/arch/blackfin/include/asm/module.h
index e3128df139d..9c1cfffddd9 100644
--- a/arch/blackfin/include/asm/module.h
+++ b/arch/blackfin/include/asm/module.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _ASM_BFIN_MODULE_H
#define _ASM_BFIN_MODULE_H
diff --git a/arch/blackfin/include/asm/mutex.h b/arch/blackfin/include/asm/mutex.h
index 5cc641c5083..f726e3a80ad 100644
--- a/arch/blackfin/include/asm/mutex.h
+++ b/arch/blackfin/include/asm/mutex.h
@@ -4,6 +4,10 @@
* TODO: implement optimized primitives instead, or leave the generic
* implementation in place, or pick the atomic_xchg() based generic
* implementation. (see asm-generic/mutex-xchg.h for details)
+ *
+ * Copyright 2006-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
#ifndef _ASM_MUTEX_H
diff --git a/arch/blackfin/include/asm/nand.h b/arch/blackfin/include/asm/nand.h
index afbaafa793f..3ae8b569edf 100644
--- a/arch/blackfin/include/asm/nand.h
+++ b/arch/blackfin/include/asm/nand.h
@@ -1,13 +1,9 @@
-/* linux/include/asm-blackfin/nand.h
- *
- * Copyright (c) 2007 Analog Devices, Inc.
- * Bryan Wu <bryan.wu@analog.com>
- *
+/*
* BF5XX - NAND flash controller platfrom_device info
*
- * 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.
+ * Copyright 2007-2008 Analog Devices, Inc.
+ *
+ * Licensed under the GPL-2
*/
/* struct bf5xx_nand_platform
diff --git a/arch/blackfin/include/asm/page.h b/arch/blackfin/include/asm/page.h
index 29dcf75c611..944a07c6cfd 100644
--- a/arch/blackfin/include/asm/page.h
+++ b/arch/blackfin/include/asm/page.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_PAGE_H
#define _BLACKFIN_PAGE_H
diff --git a/arch/blackfin/include/asm/page_offset.h b/arch/blackfin/include/asm/page_offset.h
index cbaff24b4b2..d06a89b89d2 100644
--- a/arch/blackfin/include/asm/page_offset.h
+++ b/arch/blackfin/include/asm/page_offset.h
@@ -1,5 +1,10 @@
-
-/* This handles the memory map.. */
+/*
+ * This handles the memory map
+ *
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
#ifdef CONFIG_BLACKFIN
#define PAGE_OFFSET_RAW 0x00000000
diff --git a/arch/blackfin/include/asm/pda.h b/arch/blackfin/include/asm/pda.h
index a6f95695731..d49bb261d9b 100644
--- a/arch/blackfin/include/asm/pda.h
+++ b/arch/blackfin/include/asm/pda.h
@@ -1,23 +1,8 @@
/*
- * File: arch/blackfin/include/asm/pda.h
- * Author: Philippe Gerum <rpm@xenomai.org>
+ * Copyright 2007-2009 Analog Devices Inc.
+ * Philippe Gerum <rpm@xenomai.org>
*
- * Copyright 2007 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef _ASM_BLACKFIN_PDA_H
diff --git a/arch/blackfin/include/asm/pgtable.h b/arch/blackfin/include/asm/pgtable.h
index 783c8f7f8f8..821c699c223 100644
--- a/arch/blackfin/include/asm/pgtable.h
+++ b/arch/blackfin/include/asm/pgtable.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_PGTABLE_H
#define _BLACKFIN_PGTABLE_H
@@ -92,6 +98,12 @@ extern unsigned int kobjsize(const void *objp);
#define VMALLOC_START 0
#define VMALLOC_END 0xffffffff
+/* provide a special get_unmapped_area for framebuffer mmaps of nommu */
+extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long);
+#define HAVE_ARCH_FB_UNMAPPED_AREA
+
#include <asm-generic/pgtable.h>
#endif /* _BLACKFIN_PGTABLE_H */
diff --git a/arch/blackfin/include/asm/poll.h b/arch/blackfin/include/asm/poll.h
index a0556671357..072d8966c5c 100644
--- a/arch/blackfin/include/asm/poll.h
+++ b/arch/blackfin/include/asm/poll.h
@@ -1,3 +1,10 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ */
+
#ifndef __BFIN_POLL_H
#define __BFIN_POLL_H
diff --git a/arch/blackfin/include/asm/portmux.h b/arch/blackfin/include/asm/portmux.h
index 88eb5c07cc2..edd8ef3a378 100644
--- a/arch/blackfin/include/asm/portmux.h
+++ b/arch/blackfin/include/asm/portmux.h
@@ -1,6 +1,9 @@
/*
- * Common header file for blackfin family of processors.
+ * Common header file for Blackfin family of processors
*
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
#ifndef _PORTMUX_H_
diff --git a/arch/blackfin/include/asm/posix_types.h b/arch/blackfin/include/asm/posix_types.h
index 80c9d64eb26..41bc1875c4d 100644
--- a/arch/blackfin/include/asm/posix_types.h
+++ b/arch/blackfin/include/asm/posix_types.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __ARCH_BFIN_POSIX_TYPES_H
#define __ARCH_BFIN_POSIX_TYPES_H
diff --git a/arch/blackfin/include/asm/processor.h b/arch/blackfin/include/asm/processor.h
index a36ad8dac06..aea880274de 100644
--- a/arch/blackfin/include/asm/processor.h
+++ b/arch/blackfin/include/asm/processor.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __ASM_BFIN_PROCESSOR_H
#define __ASM_BFIN_PROCESSOR_H
diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h
index e3f086dc726..27290c955a7 100644
--- a/arch/blackfin/include/asm/ptrace.h
+++ b/arch/blackfin/include/asm/ptrace.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BFIN_PTRACE_H
#define _BFIN_PTRACE_H
diff --git a/arch/blackfin/include/asm/sections.h b/arch/blackfin/include/asm/sections.h
index ae4dae1e370..1f5381fbb4a 100644
--- a/arch/blackfin/include/asm/sections.h
+++ b/arch/blackfin/include/asm/sections.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_SECTIONS_H
#define _BLACKFIN_SECTIONS_H
diff --git a/arch/blackfin/include/asm/segment.h b/arch/blackfin/include/asm/segment.h
index 02cfd09b5a9..f8e1984ffc7 100644
--- a/arch/blackfin/include/asm/segment.h
+++ b/arch/blackfin/include/asm/segment.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BFIN_SEGMENT_H
#define _BFIN_SEGMENT_H
diff --git a/arch/blackfin/include/asm/sigcontext.h b/arch/blackfin/include/asm/sigcontext.h
index ce00b03c277..ce4081a4d81 100644
--- a/arch/blackfin/include/asm/sigcontext.h
+++ b/arch/blackfin/include/asm/sigcontext.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _ASM_BLACKFIN_SIGCONTEXT_H
#define _ASM_BLACKFIN_SIGCONTEXT_H
diff --git a/arch/blackfin/include/asm/siginfo.h b/arch/blackfin/include/asm/siginfo.h
index eca4565cea3..3e81306394e 100644
--- a/arch/blackfin/include/asm/siginfo.h
+++ b/arch/blackfin/include/asm/siginfo.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BFIN_SIGINFO_H
#define _BFIN_SIGINFO_H
diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h
index 118deeeae7c..6a0fe94b84a 100644
--- a/arch/blackfin/include/asm/smp.h
+++ b/arch/blackfin/include/asm/smp.h
@@ -1,23 +1,8 @@
/*
- * File: arch/blackfin/include/asm/smp.h
- * Author: Philippe Gerum <rpm@xenomai.org>
+ * Copyright 2007-2009 Analog Devices Inc.
+ * Philippe Gerum <rpm@xenomai.org>
*
- * Copyright 2007 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __ASM_BLACKFIN_SMP_H
diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h
index d6ff4b59fcb..b0c7f0ee4b0 100644
--- a/arch/blackfin/include/asm/spinlock.h
+++ b/arch/blackfin/include/asm/spinlock.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __BFIN_SPINLOCK_H
#define __BFIN_SPINLOCK_H
diff --git a/arch/blackfin/include/asm/spinlock_types.h b/arch/blackfin/include/asm/spinlock_types.h
index b1e3c4c7b38..be75762c061 100644
--- a/arch/blackfin/include/asm/spinlock_types.h
+++ b/arch/blackfin/include/asm/spinlock_types.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __ASM_SPINLOCK_TYPES_H
#define __ASM_SPINLOCK_TYPES_H
diff --git a/arch/blackfin/include/asm/stat.h b/arch/blackfin/include/asm/stat.h
index d2b6f11ec23..2e27665c4e9 100644
--- a/arch/blackfin/include/asm/stat.h
+++ b/arch/blackfin/include/asm/stat.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
#ifndef _BFIN_STAT_H
#define _BFIN_STAT_H
diff --git a/arch/blackfin/include/asm/string.h b/arch/blackfin/include/asm/string.h
index 321f4d96e4a..d7f0ccb418c 100644
--- a/arch/blackfin/include/asm/string.h
+++ b/arch/blackfin/include/asm/string.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_STRING_H_
#define _BLACKFIN_STRING_H_
diff --git a/arch/blackfin/include/asm/swab.h b/arch/blackfin/include/asm/swab.h
index d442113de51..89de6507ca2 100644
--- a/arch/blackfin/include/asm/swab.h
+++ b/arch/blackfin/include/asm/swab.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_SWAB_H
#define _BLACKFIN_SWAB_H
diff --git a/arch/blackfin/include/asm/system.h b/arch/blackfin/include/asm/system.h
index 85e8f16cf8c..dde19b1d25f 100644
--- a/arch/blackfin/include/asm/system.h
+++ b/arch/blackfin/include/asm/system.h
@@ -1,34 +1,8 @@
/*
- * File: include/asm/system.h
- * Based on:
- * Author: Tony Kou (tonyko@lineo.ca)
- * Copyright (c) 2002 Arcturus Networks Inc.
- * (www.arcturusnetworks.com)
- * Copyright (c) 2003 Metrowerks (www.metrowerks.com)
- * Copyright (c) 2004 Analog Device Inc.
- * Created: 25Jan2001 - Tony Kou
- * Description: system.h include file
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Tony Kou (tonyko@lineo.ca)
*
- * Modified: 22Sep2006 - Robin Getz
- * - move include blackfin.h down, so I can get access to
- * irq functions in other include files.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _BLACKFIN_SYSTEM_H
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 2bbfdd950af..afb3a862638 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -1,27 +1,7 @@
/*
- * File: include/asm-blackfin/thread_info.h
- * Based on: include/asm-m68knommu/thread_info.h
- * Author: LG Soft India
- * Copyright (C) 2004-2005 Analog Devices Inc.
- * Created: Tue Sep 21 2004
- * Description: Blackfin low-level thread information
- * Modified:
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _ASM_THREAD_INFO_H
diff --git a/arch/blackfin/include/asm/tlb.h b/arch/blackfin/include/asm/tlb.h
index 89a12ee916d..a74ae08af1a 100644
--- a/arch/blackfin/include/asm/tlb.h
+++ b/arch/blackfin/include/asm/tlb.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BLACKFIN_TLB_H
#define _BLACKFIN_TLB_H
diff --git a/arch/blackfin/include/asm/trace.h b/arch/blackfin/include/asm/trace.h
index 312b596b973..609ad3c8418 100644
--- a/arch/blackfin/include/asm/trace.h
+++ b/arch/blackfin/include/asm/trace.h
@@ -1,6 +1,9 @@
/*
- * Common header file for blackfin family of processors.
+ * header file for hardware trace functions
*
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BLACKFIN_TRACE_
diff --git a/arch/blackfin/include/asm/traps.h b/arch/blackfin/include/asm/traps.h
index 3cdc454cde2..9fe0da612c0 100644
--- a/arch/blackfin/include/asm/traps.h
+++ b/arch/blackfin/include/asm/traps.h
@@ -1,13 +1,10 @@
/*
- * linux/include/asm/traps.h
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2001 Lineo, Inc
+ * Tony Kou
+ * 1993 Hamish Macdonald
*
- * Copyright (C) 1993 Hamish Macdonald
- *
- * Lineo, Inc Jul 2001 Tony Kou
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
+ * Licensed under the GPL-2
*/
#ifndef _BFIN_TRAPS_H
diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h
index 2f469a1f80f..c03b8532aad 100644
--- a/arch/blackfin/include/asm/uaccess.h
+++ b/arch/blackfin/include/asm/uaccess.h
@@ -1,4 +1,7 @@
-/* Changes made by Lineo Inc. May 2001
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*
* Based on: include/asm-m68knommu/uaccess.h
*/
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index 02b1529dad5..779be02a910 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef __ASM_BFIN_UNISTD_H
#define __ASM_BFIN_UNISTD_H
/*
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index f05d1b99b0e..bd32c09b934 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/kernel/asm-offsets.c
- * Based on:
- * Author:
+ * generate definitions needed by assembly language modules
*
- * Created:
- * Description: generate definitions needed by assembly language modules.
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/stddef.h>
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 384868dedac..1f170216d2f 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -2,6 +2,7 @@
* bfin_dma_5xx.c - Blackfin DMA implementation
*
* Copyright 2004-2008 Analog Devices Inc.
+ *
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index fc4681c0170..22705eeff34 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/kernel/bfin_gpio.c
- * Based on:
- * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
+ * GPIO Abstraction Layer
*
- * Created:
- * Description: GPIO Abstraction Layer
+ * Copyright 2006-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/delay.h>
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
index 36193eed9a1..f7b9cdce823 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
@@ -1,25 +1,11 @@
/*
* Blackfin CPLB initialization
*
- * Copyright 2004-2007 Analog Devices Inc.
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
+
#include <linux/module.h>
#include <asm/blackfin.h>
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index 8e1e9e9e963..69e0e530d70 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -1,22 +1,11 @@
/*
- * Blackfin CPLB exception handling.
- * Copyright 2004-2007 Analog Devices Inc.
+ * Blackfin CPLB exception handling for when MPU in on
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
+
#include <linux/module.h>
#include <linux/mm.h>
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 5d8ad503f82..fd9a2f31e68 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -1,24 +1,9 @@
/*
* Blackfin CPLB initialization
*
- * Copyright 2004-2007 Analog Devices Inc.
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
index d9ea46c6e41..5b88861d618 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -1,26 +1,14 @@
/*
- * File: arch/blackfin/kernel/cplb-nompu-c/cplbmgr.c
* Based on: arch/blackfin/kernel/cplb-mpu/cplbmgr.c
* Author: Michael McTernan <mmcternan@airvana.com>
*
- * Created: 01Nov2008
* Description: CPLB miss handler.
*
* Modified:
* Copyright 2008 Airvana Inc.
- * Copyright 2004-2007 Analog Devices Inc.
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Licensed under the GPL-2 or later
*/
#include <linux/kernel.h>
diff --git a/arch/blackfin/kernel/cplbinfo.c b/arch/blackfin/kernel/cplbinfo.c
index 64d78300dd0..0bdaa517a50 100644
--- a/arch/blackfin/kernel/cplbinfo.c
+++ b/arch/blackfin/kernel/cplbinfo.c
@@ -2,6 +2,7 @@
* arch/blackfin/kernel/cplbinfo.c - display CPLB status
*
* Copyright 2004-2008 Analog Devices Inc.
+ *
* Licensed under the GPL-2 or later.
*/
@@ -111,24 +112,21 @@ static const struct seq_operations cplbinfo_sops = {
.show = cplbinfo_show,
};
+#define CPLBINFO_DCPLB_FLAG 0x80000000
+
static int cplbinfo_open(struct inode *inode, struct file *file)
{
- char buf[256], *path, *p;
+ struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
+ char cplb_type;
unsigned int cpu;
- char *s_cpu, *s_cplb;
int ret;
struct seq_file *m;
struct cplbinfo_data *cdata;
- path = d_path(&file->f_path, buf, sizeof(buf));
- if (IS_ERR(path))
- return PTR_ERR(path);
- s_cpu = strstr(path, "/cpu");
- s_cplb = strrchr(path, '/');
- if (!s_cpu || !s_cplb)
- return -EINVAL;
+ cpu = (unsigned int)pde->data;
+ cplb_type = cpu & CPLBINFO_DCPLB_FLAG ? 'D' : 'I';
+ cpu &= ~CPLBINFO_DCPLB_FLAG;
- cpu = simple_strtoul(s_cpu + 4, &p, 10);
if (!cpu_online(cpu))
return -ENODEV;
@@ -139,7 +137,7 @@ static int cplbinfo_open(struct inode *inode, struct file *file)
cdata = m->private;
cdata->pos = 0;
- cdata->cplb_type = toupper(s_cplb[1]);
+ cdata->cplb_type = cplb_type;
cplbinfo_seq_init(cdata, cpu);
return 0;
@@ -168,8 +166,10 @@ static int __init cplbinfo_init(void)
if (!cpu_dir)
return -ENOMEM;
- proc_create("icplb", S_IRUGO, cpu_dir, &cplbinfo_fops);
- proc_create("dcplb", S_IRUGO, cpu_dir, &cplbinfo_fops);
+ proc_create_data("icplb", S_IRUGO, cpu_dir, &cplbinfo_fops,
+ (void *)cpu);
+ proc_create_data("dcplb", S_IRUGO, cpu_dir, &cplbinfo_fops,
+ (void *)(cpu | CPLBINFO_DCPLB_FLAG));
}
return 0;
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 2f62a9f4058..e74e74d7733 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/kernel/dma-mapping.c
- * Based on:
- * Author:
+ * Dynamic DMA mapping support
*
- * Created:
- * Description: Dynamic DMA mapping support.
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/types.h>
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c
index 931c78b5ea1..84ed8375113 100644
--- a/arch/blackfin/kernel/early_printk.c
+++ b/arch/blackfin/kernel/early_printk.c
@@ -1,25 +1,10 @@
/*
- * File: arch/blackfin/kernel/early_printk.c
- * Based on: arch/x86_64/kernel/early_printk.c
- * Author: Robin Getz <rgetz@blackfin.uclinux.org
+ * allow a console to be used for early printk
+ * derived from arch/x86/kernel/early_printk.c
*
- * Created: 14Aug2007
- * Description: allow a console to be used for early printk
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Licensed under the GPL-2
*/
#include <linux/kernel.h>
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S
index 3f8769b7db5..f27dc2292e1 100644
--- a/arch/blackfin/kernel/entry.S
+++ b/arch/blackfin/kernel/entry.S
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/entry.S
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S
index 0d2d9e0968c..0565917f23b 100644
--- a/arch/blackfin/kernel/fixed_code.S
+++ b/arch/blackfin/kernel/fixed_code.S
@@ -6,7 +6,12 @@
* These are aligned to 16 bytes, so that we have some space to replace
* these sequences with something else (e.g. kernel traps if we ever do
* BF561 SMP).
+ *
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
*/
+
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/unistd.h>
diff --git a/arch/blackfin/kernel/flat.c b/arch/blackfin/kernel/flat.c
index d188b243053..a88daddbf07 100644
--- a/arch/blackfin/kernel/flat.c
+++ b/arch/blackfin/kernel/flat.c
@@ -1,21 +1,7 @@
/*
- * arch/blackfin/kernel/flat.c
+ * Copyright 2007 Analog Devices Inc.
*
- * Copyright (C) 2007 Analog Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Licensed under the GPL-2.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c
index c26c34de9f3..118c5b9deda 100644
--- a/arch/blackfin/kernel/init_task.c
+++ b/arch/blackfin/kernel/init_task.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/init_task.c
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/mm.h>
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 4b5fd36187d..db9f9c91f11 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/irqchip.c
- * Based on:
- * Author:
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/kernel_stat.h>
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index 67fc7a56c86..a6dfa6b71e6 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/module.c
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#define pr_fmt(fmt) "module %s: " fmt
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index f5b28618964..430ae39456e 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/kernel/process.c
- * Based on:
- * Author:
+ * Blackfin architecture-dependent process handling
*
- * Created:
- * Description: Blackfin architecture-dependent process handling.
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/module.h>
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 30f4828277a..0982b5d5af1 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -1,30 +1,8 @@
/*
- * File: arch/blackfin/kernel/ptrace.c
- * Based on: Taken from linux/kernel/ptrace.c
- * Author: linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ * these modifications are Copyright 2004-2009 Analog Devices Inc.
*
- * Created: 1/23/92
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2
*/
#include <linux/kernel.h>
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 369535b61ed..c202a44d141 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -1,9 +1,5 @@
/*
- * arch/blackfin/kernel/setup.c
- *
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Enter bugs at http://blackfin.uclinux.org/
+ * Copyright 2004-2009 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c
index 8b8c7107a16..557e9fef406 100644
--- a/arch/blackfin/kernel/shadow_console.c
+++ b/arch/blackfin/kernel/shadow_console.c
@@ -4,8 +4,6 @@
*
* Copyright 2009 Analog Devices Inc.
*
- * Enter bugs at http://blackfin.uclinux.org/
- *
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index dbc3bbf846b..9d90c18fab2 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/signal.c
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/signal.h>
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index 3da60fb13ce..afcef129d4e 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -1,32 +1,10 @@
/*
- * File: arch/blackfin/kernel/sys_bfin.c
- * Based on:
- * Author:
+ * contains various random system calls that have a non-standard
+ * calling sequence on the Linux/Blackfin platform.
*
- * Created:
- * Description: This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/bfin
- * platform.
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/spinlock.h>
@@ -91,3 +69,14 @@ asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len)
{
return safe_dma_memcpy(dest, src, len);
}
+
+#if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)
+#include <linux/fb.h>
+unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ struct fb_info *info = filp->private_data;
+ return (unsigned long)info->screen_base;
+}
+EXPORT_SYMBOL(get_fb_unmapped_area);
+#endif
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index f9715764383..359cfb1815c 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -1,13 +1,13 @@
/*
- * linux/arch/kernel/time-ts.c
- *
* Based on arm clockevents implementation and old bfin time tick.
*
- * Copyright(C) 2008, GeoTechnologies, Vitja Makarov
+ * Copyright 2008-2009 Analog Devics Inc.
+ * 2008 GeoTechnologies
+ * Vitja Makarov
*
- * This code is licenced under the GPL version 2. For details see
- * kernel-base/COPYING.
+ * Licensed under the GPL-2
*/
+
#include <linux/module.h>
#include <linux/profile.h>
#include <linux/interrupt.h>
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
index adb54aa7d7c..e5069fe6861 100644
--- a/arch/blackfin/kernel/time.c
+++ b/arch/blackfin/kernel/time.c
@@ -81,11 +81,11 @@ time_sched_init(irqreturn_t(*timer_routine) (int, void *))
#endif
}
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
/*
* Should return useconds since last timer tick
*/
-#ifndef CONFIG_GENERIC_TIME
-static unsigned long gettimeoffset(void)
+u32 arch_gettimeoffset(void)
{
unsigned long offset;
unsigned long clocks_per_jiffy;
@@ -184,65 +184,6 @@ void __init time_init(void)
time_sched_init(timer_interrupt);
}
-#ifndef CONFIG_GENERIC_TIME
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long seq;
- unsigned long usec, sec;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
- usec = gettimeoffset();
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / NSEC_PER_USEC);
- }
- while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= USEC_PER_SEC) {
- usec -= USEC_PER_SEC;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set the xtime.tv_usec
- * correctly. However, the value in this location is
- * is value at the last tick.
- * Discover what correction gettimeofday
- * would have done, and then undo it!
- */
- nsec -= (gettimeoffset() * NSEC_PER_USEC);
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
-
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
-
- return 0;
-}
-EXPORT_SYMBOL(do_settimeofday);
-#endif /* !CONFIG_GENERIC_TIME */
-
/*
* Scheduler clock - returns current time in nanosec units.
*/
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 56464cb8edf..6b7325d634a 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/traps.c
- * Based on:
- * Author: Hamish Macdonald
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description: uses S/W interrupt 15 for the system calls
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#include <linux/bug.h>
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index ffd90fbbc8f..10e12539000 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/kernel/vmlinux.lds.S
- * Based on: none - original work
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created: Tue Sep 21 2004
- * Description: Master linker script for blackfin architecture
- *
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#define VMLINUX_SYMBOL(_sym_) _##_sym_
diff --git a/arch/blackfin/lib/ashldi3.c b/arch/blackfin/lib/ashldi3.c
index a8c279e9b19..ab69d8768af 100644
--- a/arch/blackfin/lib/ashldi3.c
+++ b/arch/blackfin/lib/ashldi3.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/ashldi3.c
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include "gcclib.h"
diff --git a/arch/blackfin/lib/ashrdi3.c b/arch/blackfin/lib/ashrdi3.c
index a0d3419329c..b5b351e82e1 100644
--- a/arch/blackfin/lib/ashrdi3.c
+++ b/arch/blackfin/lib/ashrdi3.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/ashrdi3.c
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include "gcclib.h"
diff --git a/arch/blackfin/lib/checksum.c b/arch/blackfin/lib/checksum.c
index cd605e7d851..c62969dc1bb 100644
--- a/arch/blackfin/lib/checksum.c
+++ b/arch/blackfin/lib/checksum.c
@@ -1,32 +1,12 @@
/*
- * File: arch/blackfin/lib/checksum.c
- * Based on: none - original work
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description: An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
+ * Licensed under the GPL-2 or later.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
+ * An implementation of the TCP/IP protocol suite for the LINUX operating
+ * system. INET is implemented using the BSD Socket interface as the
+ * means of communication with the user level.
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/module.h>
diff --git a/arch/blackfin/lib/divsi3.S b/arch/blackfin/lib/divsi3.S
index 2ac59c70dd9..f89c5a49c47 100644
--- a/arch/blackfin/lib/divsi3.S
+++ b/arch/blackfin/lib/divsi3.S
@@ -1,10 +1,9 @@
/*
- * File: arch/blackfin/lib/divsi3.S
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description: 16 / 32 bit signed division.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
+ *
+ * 16 / 32 bit signed division.
* Special cases :
* 1) If(numerator == 0)
* return 0
@@ -22,25 +21,6 @@
* R0 - Quotient (o)
* Registers Used : R2-R7,P0-P2
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
.global ___divsi3;
diff --git a/arch/blackfin/lib/gcclib.h b/arch/blackfin/lib/gcclib.h
index 9ccd39a135e..724f07f14f8 100644
--- a/arch/blackfin/lib/gcclib.h
+++ b/arch/blackfin/lib/gcclib.h
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/gcclib.h
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#define BITS_PER_UNIT 8
diff --git a/arch/blackfin/lib/lshrdi3.c b/arch/blackfin/lib/lshrdi3.c
index e57bf6fbdf3..53f1741047e 100644
--- a/arch/blackfin/lib/lshrdi3.c
+++ b/arch/blackfin/lib/lshrdi3.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/lshrdi3.c
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include "gcclib.h"
diff --git a/arch/blackfin/lib/memchr.S b/arch/blackfin/lib/memchr.S
index 5da428134d3..542e40f8775 100644
--- a/arch/blackfin/lib/memchr.S
+++ b/arch/blackfin/lib/memchr.S
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/memchr.S
- * Based on:
- * Author:
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memcmp.S b/arch/blackfin/lib/memcmp.S
index 219fa2877c6..ce5b9f1a826 100644
--- a/arch/blackfin/lib/memcmp.S
+++ b/arch/blackfin/lib/memcmp.S
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/memcmp.S
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S
index e654a18a075..c31bf22aab1 100644
--- a/arch/blackfin/lib/memcpy.S
+++ b/arch/blackfin/lib/memcpy.S
@@ -1,36 +1,13 @@
/*
- * File: arch/blackfin/lib/memcpy.S
- * Based on:
- * Author:
+ * internal version of memcpy(), issued by the compiler to copy blocks of
+ * data around. This is really memmove() - it has to be able to deal with
+ * possible overlaps, because that ambiguity is when the compiler gives up
+ * and calls a function. We have our own, internal version so that we get
+ * something we trust, even if the user has redefined the normal symbol.
*
- * Created:
- * Description: internal version of memcpy(), issued by the compiler
- * to copy blocks of data around.
- * This is really memmove() - it has to be able to deal with
- * possible overlaps, because that ambiguity is when the compiler
- * gives up and calls a function. We have our own, internal version
- * so that we get something we trust, even if the user has redefined
- * the normal symbol.
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memmove.S b/arch/blackfin/lib/memmove.S
index 33f8653145b..80c240acac6 100644
--- a/arch/blackfin/lib/memmove.S
+++ b/arch/blackfin/lib/memmove.S
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/memmove.S
- * Based on:
- * Author:
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memset.S b/arch/blackfin/lib/memset.S
index 8159136a29e..c30d99b1096 100644
--- a/arch/blackfin/lib/memset.S
+++ b/arch/blackfin/lib/memset.S
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/memset.S
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/modsi3.S b/arch/blackfin/lib/modsi3.S
index ca1dd3973b3..8b0c7d4052a 100644
--- a/arch/blackfin/lib/modsi3.S
+++ b/arch/blackfin/lib/modsi3.S
@@ -1,36 +1,12 @@
/*
- * File: arch/blackfin/lib/modsi3.S
- * Based on:
- * Author:
+ * This program computes 32 bit signed remainder. It calls div32 function
+ * for quotient estimation.
+ * Registers in: R0, R1 = Numerator/ Denominator
+ * Registers out: R0 = Remainder
*
- * Created:
- * Description: This program computes 32 bit signed remainder. It calls div32 function
- * for quotient estimation.
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Registers used :
- * Numerator/ Denominator in R0, R1
- * R0 - returns remainder.
- * R2-R7
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
.global ___modsi3;
diff --git a/arch/blackfin/lib/muldi3.S b/arch/blackfin/lib/muldi3.S
index abde120ee23..953a38a1d1d 100644
--- a/arch/blackfin/lib/muldi3.S
+++ b/arch/blackfin/lib/muldi3.S
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
+ */
+
.align 2
.global ___muldi3;
.type ___muldi3, STT_FUNC;
diff --git a/arch/blackfin/lib/outs.S b/arch/blackfin/lib/outs.S
index 4685b7aa008..250f4d4b943 100644
--- a/arch/blackfin/lib/outs.S
+++ b/arch/blackfin/lib/outs.S
@@ -1,30 +1,11 @@
/*
- * File: arch/blackfin/lib/outs.S
- * Based on:
- * Author: Bas Vermeulen <bas@buyways.nl>
+ * Implementation of outs{bwl} for BlackFin processors using zero overhead loops.
*
- * Created: Tue Mar 22 15:27:24 CEST 2005
- * Description: Implementation of outs{bwl} for BlackFin processors using zero overhead loops.
+ * Copyright 2005-2009 Analog Devices Inc.
+ * 2005 BuyWays BV
+ * Bas Vermeulen <bas@buyways.nl>
*
- * Modified: Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2.
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/smulsi3_highpart.S b/arch/blackfin/lib/smulsi3_highpart.S
index e383cd3eca5..99ee8c5de38 100644
--- a/arch/blackfin/lib/smulsi3_highpart.S
+++ b/arch/blackfin/lib/smulsi3_highpart.S
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007 Analog Devices Inc.
+ *
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
+ */
+
.align 2
.global ___smulsi3_highpart;
.type ___smulsi3_highpart, STT_FUNC;
diff --git a/arch/blackfin/lib/udivsi3.S b/arch/blackfin/lib/udivsi3.S
index 58fd96d7476..97e904315ec 100644
--- a/arch/blackfin/lib/udivsi3.S
+++ b/arch/blackfin/lib/udivsi3.S
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/lib/udivsi3.S
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/umodsi3.S b/arch/blackfin/lib/umodsi3.S
index 4f2b76ee762..168eba7c64c 100644
--- a/arch/blackfin/lib/umodsi3.S
+++ b/arch/blackfin/lib/umodsi3.S
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/lib/umodsi3.S
- * Based on:
- * Author:
+ * libgcc1 routines for Blackfin 5xx
*
- * Created:
- * Description: libgcc1 routines for Blackfin 5xx
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifdef CONFIG_ARITHMETIC_OPS_L1
diff --git a/arch/blackfin/lib/umulsi3_highpart.S b/arch/blackfin/lib/umulsi3_highpart.S
index 67b799351e3..051824a6ed0 100644
--- a/arch/blackfin/lib/umulsi3_highpart.S
+++ b/arch/blackfin/lib/umulsi3_highpart.S
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007 Analog Devices Inc.
+ *
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
+ */
+
.align 2
.global ___umulsi3_highpart;
.type ___umulsi3_highpart, STT_FUNC;
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c
index 03e4a9941f0..01975c01711 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf518/boards/ezbrd.c
- * Based on: arch/blackfin/mach-bf527/boards/ezbrd.c
- * Author: Bryan Wu <cooloney@kernel.org>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -571,19 +549,6 @@ static struct platform_device bf51x_sdh_device = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
static const unsigned int cclk_vlev_datasheet[] =
{
VRPAIR(VLEV_100, 400000000),
@@ -660,8 +625,6 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezbrd_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init ezbrd_init(void)
diff --git a/arch/blackfin/mach-bf518/dma.c b/arch/blackfin/mach-bf518/dma.c
index 698e88ca510..78b43605a0b 100644
--- a/arch/blackfin/mach-bf518/dma.c
+++ b/arch/blackfin/mach-bf518/dma.c
@@ -1,31 +1,11 @@
/*
- * File: arch/blackfin/mach-bf518/dma.c
- * Based on:
- * Author: Bryan Wu <cooloney@kernel.org>
+ * the simple DMA Implementation for Blackfin
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
+ * Copyright 2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
+
#include <linux/module.h>
#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf518/include/mach/bf518.h b/arch/blackfin/mach-bf518/include/mach/bf518.h
index 78da1a07ee7..856b330ecf0 100644
--- a/arch/blackfin/mach-bf518/include/mach/bf518.h
+++ b/arch/blackfin/mach-bf518/include/mach/bf518.h
@@ -1,30 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/bf518.h
- * Based on: include/asm-blackfin/mach-bf527/bf527.h
- * Author: Michael Hennerich (michael.hennerich@analog.com)
+ * Copyright 2008 Analog Devices Inc.
*
- * Created:
- * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF518
- *
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __MACH_BF518_H__
diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
index dbade93395e..970d310021e 100644
--- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf518/bfin_serial_5xx.h
- * based on:
- * author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * created:
- * description:
- * blackfin serial driver head file
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later
*/
#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf518/include/mach/blackfin.h b/arch/blackfin/mach-bf518/include/mach/blackfin.h
index 83421d39314..6cfb246aebe 100644
--- a/arch/blackfin/mach-bf518/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf518/include/mach/blackfin.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/blackfin.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF512.h b/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
index 820c13c4daa..493020d0a65 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/cdefbf512.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description: system mmr register map
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _CDEF_BF512_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
index dfe492dfe54..e1d99911025 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/cdefbf514.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description: system mmr register map
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF514_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
index 14df43d4677..6b364eda494 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/cdefbf516.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description: system mmr register map
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF516_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
index bafb370cfb3..929b90650bd 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/cdefbf518.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description: system mmr register map
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF518_H
@@ -211,6 +186,47 @@
#define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT)
#define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT, val)
+#define bfin_read_EMAC_PTP_CTL() bfin_read16(EMAC_PTP_CTL)
+#define bfin_write_EMAC_PTP_CTL(val) bfin_write16(EMAC_PTP_CTL, val)
+#define bfin_read_EMAC_PTP_IE() bfin_read16(EMAC_PTP_IE)
+#define bfin_write_EMAC_PTP_IE(val) bfin_write16(EMAC_PTP_IE, val)
+#define bfin_read_EMAC_PTP_ISTAT() bfin_read16(EMAC_PTP_ISTAT)
+#define bfin_write_EMAC_PTP_ISTAT(val) bfin_write16(EMAC_PTP_ISTAT, val)
+#define bfin_read_EMAC_PTP_FOFF() bfin_read32(EMAC_PTP_FOFF)
+#define bfin_write_EMAC_PTP_FOFF(val) bfin_write32(EMAC_PTP_FOFF, val)
+#define bfin_read_EMAC_PTP_FV1() bfin_read32(EMAC_PTP_FV1)
+#define bfin_write_EMAC_PTP_FV1(val) bfin_write32(EMAC_PTP_FV1, val)
+#define bfin_read_EMAC_PTP_FV2() bfin_read32(EMAC_PTP_FV2)
+#define bfin_write_EMAC_PTP_FV2(val) bfin_write32(EMAC_PTP_FV2, val)
+#define bfin_read_EMAC_PTP_FV3() bfin_read32(EMAC_PTP_FV3)
+#define bfin_write_EMAC_PTP_FV3(val) bfin_write32(EMAC_PTP_FV3, val)
+#define bfin_read_EMAC_PTP_ADDEND() bfin_read32(EMAC_PTP_ADDEND)
+#define bfin_write_EMAC_PTP_ADDEND(val) bfin_write32(EMAC_PTP_ADDEND, val)
+#define bfin_read_EMAC_PTP_ACCR() bfin_read32(EMAC_PTP_ACCR)
+#define bfin_write_EMAC_PTP_ACCR(val) bfin_write32(EMAC_PTP_ACCR, val)
+#define bfin_read_EMAC_PTP_OFFSET() bfin_read32(EMAC_PTP_OFFSET)
+#define bfin_write_EMAC_PTP_OFFSET(val) bfin_write32(EMAC_PTP_OFFSET, val)
+#define bfin_read_EMAC_PTP_TIMELO() bfin_read32(EMAC_PTP_TIMELO)
+#define bfin_write_EMAC_PTP_TIMELO(val) bfin_write32(EMAC_PTP_TIMELO, val)
+#define bfin_read_EMAC_PTP_TIMEHI() bfin_read32(EMAC_PTP_TIMEHI)
+#define bfin_write_EMAC_PTP_TIMEHI(val) bfin_write32(EMAC_PTP_TIMEHI, val)
+#define bfin_read_EMAC_PTP_RXSNAPLO() bfin_read32(EMAC_PTP_RXSNAPLO)
+#define bfin_read_EMAC_PTP_RXSNAPHI() bfin_read32(EMAC_PTP_RXSNAPHI)
+#define bfin_read_EMAC_PTP_TXSNAPLO() bfin_read32(EMAC_PTP_TXSNAPLO)
+#define bfin_read_EMAC_PTP_TXSNAPHI() bfin_read32(EMAC_PTP_TXSNAPHI)
+#define bfin_read_EMAC_PTP_ALARMLO() bfin_read32(EMAC_PTP_ALARMLO)
+#define bfin_write_EMAC_PTP_ALARMLO(val) bfin_write32(EMAC_PTP_ALARMLO, val)
+#define bfin_read_EMAC_PTP_ALARMHI() bfin_read32(EMAC_PTP_ALARMHI)
+#define bfin_write_EMAC_PTP_ALARMHI(val) bfin_write32(EMAC_PTP_ALARMHI, val)
+#define bfin_read_EMAC_PTP_ID_OFF() bfin_read16(EMAC_PTP_ID_OFF)
+#define bfin_write_EMAC_PTP_ID_OFF(val) bfin_write16(EMAC_PTP_ID_OFF, val)
+#define bfin_read_EMAC_PTP_ID_SNAP() bfin_read32(EMAC_PTP_ID_SNAP)
+#define bfin_write_EMAC_PTP_ID_SNAP(val) bfin_write32(EMAC_PTP_ID_SNAP, val)
+#define bfin_read_EMAC_PTP_PPS_STARTHI() bfin_read32(EMAC_PTP_PPS_STARTHI)
+#define bfin_write_EMAC_PTP_PPS_STARTHI(val) bfin_write32(EMAC_PTP_PPS_STARTHI, val)
+#define bfin_read_EMAC_PTP_PPS_PERIOD() bfin_read32(EMAC_PTP_PPS_PERIOD)
+#define bfin_write_EMAC_PTP_PPS_PERIOD(val) bfin_write32(EMAC_PTP_PPS_PERIOD, val)
+
/* Removable Storage Interface Registers */
#define bfin_read_RSI_PWR_CTL() bfin_read16(RSI_PWR_CONTROL)
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
index ee3d4733369..1d970df7aee 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/cdefBF51x_base.h
- * Based on:
- * Author:
+ * Copyright 2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF52X_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF512.h b/arch/blackfin/mach-bf518/include/mach/defBF512.h
index a96ca90154d..9b505bb0cb2 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF512.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF512.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/defBF512.h
- * Based on:
- * Author:
+ * Copyright 2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF512_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF514.h b/arch/blackfin/mach-bf518/include/mach/defBF514.h
index 56ee5a7c200..b5adca23a78 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF514.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF514.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/defBF514.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF514_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF516.h b/arch/blackfin/mach-bf518/include/mach/defBF516.h
index dfc93843517..7eb18774d72 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF516.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF516.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/defBF516.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF516_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF518.h b/arch/blackfin/mach-bf518/include/mach/defBF518.h
index 6e982abf4ed..794cf06eb5b 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF518.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF518.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/defBF518.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF518_H
@@ -648,4 +624,32 @@
#define RWR 0x1 /* Read Wait Request */
+/* Bit masks for EMAC_PTP_CTL */
+
+#define PTP_EN 0x1 /* Enable the PTP_TSYNC module */
+#define TL 0x2 /* Timestamp lock control */
+#define ASEN 0x10 /* Auxiliary snapshot control */
+#define PPSEN 0x80 /* Pulse-per-second (PPS) control */
+#define CKOEN 0x2000 /* Clock output control */
+
+/* Bit masks for EMAC_PTP_IE */
+
+#define ALIE 0x1 /* Alarm interrupt enable */
+#define RXEIE 0x2 /* Receive event interrupt enable */
+#define RXGIE 0x4 /* Receive general interrupt enable */
+#define TXIE 0x8 /* Transmit interrupt enable */
+#define RXOVE 0x10 /* Receive overrun error interrupt enable */
+#define TXOVE 0x20 /* Transmit overrun error interrupt enable */
+#define ASIE 0x40 /* Auxiliary snapshot interrupt enable */
+
+/* Bit masks for EMAC_PTP_ISTAT */
+
+#define ALS 0x1 /* Alarm status */
+#define RXEL 0x2 /* Receive event interrupt status */
+#define RXGL 0x4 /* Receive general interrupt status */
+#define TXTL 0x8 /* Transmit snapshot status */
+#define RXOV 0x10 /* Receive snapshot overrun status */
+#define TXOV 0x20 /* Transmit snapshot overrun status */
+#define ASL 0x40 /* Auxiliary snapshot interrupt status */
+
#endif /* _DEF_BF518_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
index 1bec8d1c2a7..e06f4112c69 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf518/defBF51x_base.h
- * Based on:
- * Author:
+ * Copyright 2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF51X_H
diff --git a/arch/blackfin/mach-bf518/include/mach/gpio.h b/arch/blackfin/mach-bf518/include/mach/gpio.h
index 9757683c394..bbab2d76499 100644
--- a/arch/blackfin/mach-bf518/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf518/include/mach/gpio.h
@@ -1,7 +1,4 @@
/*
- * File: arch/blackfin/mach-bf518/include/mach/gpio.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
* Copyright (C) 2008 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-bf518/include/mach/irq.h b/arch/blackfin/mach-bf518/include/mach/irq.h
index 3ff0f093313..14e52ec7afa 100644
--- a/arch/blackfin/mach-bf518/include/mach/irq.h
+++ b/arch/blackfin/mach-bf518/include/mach/irq.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf518/irq.h
- * based on: include/asm-blackfin/mach-bf527/irq.h
- * author: Michael Hennerich (michael.hennerich@analog.com)
+ * Copyright 2008 Analog Devices Inc.
*
- * created:
- * description:
- * system mmr register map
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later
*/
#ifndef _BF518_IRQ_H_
diff --git a/arch/blackfin/mach-bf518/include/mach/portmux.h b/arch/blackfin/mach-bf518/include/mach/portmux.h
index a0fc77fd331..e352910f7f9 100644
--- a/arch/blackfin/mach-bf518/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf518/include/mach/portmux.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2008-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
#ifndef _MACH_PORTMUX_H_
#define _MACH_PORTMUX_H_
diff --git a/arch/blackfin/mach-bf518/ints-priority.c b/arch/blackfin/mach-bf518/ints-priority.c
index 3151fd5501c..bb05bef34ec 100644
--- a/arch/blackfin/mach-bf518/ints-priority.c
+++ b/arch/blackfin/mach-bf518/ints-priority.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf518/ints-priority.c
- * Based on: arch/blackfin/mach-bf527/ints-priority.c
- * Author: Bryan Wu <cooloney@kernel.org>
+ * Set up the interrupt priorities
*
- * Created:
- * Description: Set up the interrupt priorities
+ * Copyright 2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index 08a3f01c988..f1996b13a3d 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -1,31 +1,10 @@
/*
- * File: arch/blackfin/mach-bf527/boards/cm-bf527.c
- * Based on: arch/blackfin/mach-bf537/boards/stamp.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2008-2009 Bluetechnix
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -616,12 +595,6 @@ static struct platform_device bfin_spi0_device = {
};
#endif /* spi master and devices */
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
-static struct platform_device bfin_fb_adv7393_device = {
- .name = "bfin-adv7393",
-};
-#endif
-
#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
static struct mtd_partition cm_partitions[] = {
{
@@ -786,6 +759,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
.irq = IRQ_PF8,
},
#endif
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+ {
+ I2C_BOARD_INFO("bfin-adv7393", 0x2B),
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -821,19 +799,6 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
static const unsigned int cclk_vlev_datasheet[] =
{
VRPAIR(VLEV_100, 400000000),
@@ -909,10 +874,6 @@ static struct platform_device *cmbf527_devices[] __initdata = {
&bfin_spi0_device,
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
- &bfin_fb_adv7393_device,
-#endif
-
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
&bfin_uart_device,
#endif
@@ -942,8 +903,6 @@ static struct platform_device *cmbf527_devices[] __initdata = {
#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
&cm_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init cm_init(void)
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index 68b4c804364..cad23b15d83 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf527/boards/ezbrd.c
- * Based on: arch/blackfin/mach-bf537/boards/stamp.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -611,19 +589,6 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
static const unsigned int cclk_vlev_datasheet[] =
{
VRPAIR(VLEV_100, 400000000),
@@ -732,8 +697,6 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezbrd_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init ezbrd_init(void)
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 2849b09abe9..f09665f74ba 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf527/boards/ezkit.c
- * Based on: arch/blackfin/mach-bf537/boards/stamp.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -716,12 +694,6 @@ static struct platform_device bfin_fb_device = {
};
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
-static struct platform_device bfin_fb_adv7393_device = {
- .name = "bfin-adv7393",
-};
-#endif
-
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
static struct resource bfin_uart_resources[] = {
#ifdef CONFIG_SERIAL_BFIN_UART0
@@ -837,6 +809,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
.irq = IRQ_PF8,
},
#endif
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+ {
+ I2C_BOARD_INFO("bfin-adv7393", 0x2B),
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -905,19 +882,6 @@ static struct platform_device bfin_rotary_device = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
static const unsigned int cclk_vlev_datasheet[] =
{
VRPAIR(VLEV_100, 400000000),
@@ -1001,10 +965,6 @@ static struct platform_device *stamp_devices[] __initdata = {
&bf52x_t350mcqb_device,
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
- &bfin_fb_adv7393_device,
-#endif
-
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
&bfin_uart_device,
#endif
@@ -1038,8 +998,6 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezkit_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init ezkit_init(void)
diff --git a/arch/blackfin/mach-bf527/dma.c b/arch/blackfin/mach-bf527/dma.c
index 23187757824..7bc7577d6c4 100644
--- a/arch/blackfin/mach-bf527/dma.c
+++ b/arch/blackfin/mach-bf527/dma.c
@@ -1,31 +1,11 @@
/*
- * File: arch/blackfin/mach-bf527/dma.c
- * Based on:
- * Author:
+ * This file contains the simple DMA Implementation for Blackfin
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
+
#include <linux/module.h>
#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf527/include/mach/bf527.h b/arch/blackfin/mach-bf527/include/mach/bf527.h
index 3832aab11e9..ff68c889708 100644
--- a/arch/blackfin/mach-bf527/include/mach/bf527.h
+++ b/arch/blackfin/mach-bf527/include/mach/bf527.h
@@ -1,30 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/bf527.h
- * Based on: include/asm-blackfin/mach-bf537/bf537.h
- * Author: Michael Hennerich (michael.hennerich@analog.com)
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Created:
- * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF527
- *
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __MACH_BF527_H__
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
index ebd6cebc1fb..c1d55b878b4 100644
--- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
- * based on:
- * author:
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * created:
- * description:
- * blackfin serial driver head file
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later
*/
#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf527/include/mach/blackfin.h b/arch/blackfin/mach-bf527/include/mach/blackfin.h
index ea9cb0fef8b..e7d6034f268 100644
--- a/arch/blackfin/mach-bf527/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf527/include/mach/blackfin.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/blackfin.h
- * Based on:
- * Author:
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF522.h b/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
index 663c2bbdfd9..1079af8c7ae 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/cdefbf522.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description: system mmr register map
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF522_H
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF525.h b/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
index 00377eb59b7..dc3119e9f66 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/cdefbf525.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description: system mmr register map
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF525_H
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF527.h b/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
index fca8db70811..d6579449ee4 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/cdefbf527.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description: system mmr register map
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF527_H
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
index 1fe76d8e040..7014dde10dd 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/cdefBF52x_base.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF52X_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF522.h b/arch/blackfin/mach-bf527/include/mach/defBF522.h
index 0a8cdcdf0b4..cb139a25481 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF522.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF522.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/defBF522.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF522_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF525.h b/arch/blackfin/mach-bf527/include/mach/defBF525.h
index 5cd7576fef7..82abefc1ef6 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF525.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF525.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/defBF525.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF525_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF527.h b/arch/blackfin/mach-bf527/include/mach/defBF527.h
index f040f364afa..570a125df02 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF527.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF527.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/defBF527.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF527_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
index 68b55d03fed..f821700716e 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf527/defBF52x_base.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF52X_H
diff --git a/arch/blackfin/mach-bf527/include/mach/gpio.h b/arch/blackfin/mach-bf527/include/mach/gpio.h
index 06b6eebf0d4..104bff85290 100644
--- a/arch/blackfin/mach-bf527/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf527/include/mach/gpio.h
@@ -1,7 +1,4 @@
/*
- * File: arch/blackfin/mach-bf527/include/mach/gpio.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
* Copyright (C) 2008 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-bf527/include/mach/irq.h b/arch/blackfin/mach-bf527/include/mach/irq.h
index 8ea660d8151..aa6579a64a2 100644
--- a/arch/blackfin/mach-bf527/include/mach/irq.h
+++ b/arch/blackfin/mach-bf527/include/mach/irq.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf527/irq.h
- * based on: include/asm-blackfin/mach-bf537/irq.h
- * author: Michael Hennerich (michael.hennerich@analog.com)
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * created:
- * description:
- * system mmr register map
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later
*/
#ifndef _BF527_IRQ_H_
diff --git a/arch/blackfin/mach-bf527/include/mach/portmux.h b/arch/blackfin/mach-bf527/include/mach/portmux.h
index 72b1652be4d..d4518b6f4ad 100644
--- a/arch/blackfin/mach-bf527/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf527/include/mach/portmux.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
#ifndef _MACH_PORTMUX_H_
#define _MACH_PORTMUX_H_
diff --git a/arch/blackfin/mach-bf527/ints-priority.c b/arch/blackfin/mach-bf527/ints-priority.c
index f8c8acd73e3..44ca215bf16 100644
--- a/arch/blackfin/mach-bf527/ints-priority.c
+++ b/arch/blackfin/mach-bf527/ints-priority.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf537/ints-priority.c
- * Based on: arch/blackfin/mach-bf533/ints-priority.c
- * Author: Michael Hennerich (michael.hennerich@analog.com)
+ * Set up the interrupt priorities
*
- * Created:
- * Description: Set up the interrupt priorities
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
index 6c2b47fe4fe..43f43a095a9 100644
--- a/arch/blackfin/mach-bf533/boards/H8606.c
+++ b/arch/blackfin/mach-bf533/boards/H8606.c
@@ -1,32 +1,11 @@
/*
- * File: arch/blackfin/mach-bf533/H8606.c
- * Based on: arch/blackfin/mach-bf533/stamp.c
- * Author: Javier Herrero <jherrero@hvsistemas.es>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2007-2008 HV Sistemas S.L.
+ * Javier Herrero <jherrero@hvsistemas.es>
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2007
- * Description: Board Info File for the HV Sistemas H8606 board
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2006 Analog Devices Inc
- * Copyright 2007,2008 HV Sistemas S.L.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c
index 8208d67e2c9..b580884848d 100644
--- a/arch/blackfin/mach-bf533/boards/blackstamp.c
+++ b/arch/blackfin/mach-bf533/boards/blackstamp.c
@@ -1,16 +1,10 @@
/*
- * File: arch/blackfin/mach-bf533/blackstamp.c
- * Based on: arch/blackfin/mach-bf533/stamp.c
- * Author: Benjamin Matthews <bmat@lle.rochester.edu>
- * Aidan Williams <aidan@nicta.com.au>
+ * Board Info File for the BlackStamp
*
- * Created: 2008
- * Description: Board Info File for the BlackStamp
- *
- * Copyright 2005 National ICT Australia (NICTA)
* Copyright 2004-2008 Analog Devices Inc.
- *
- * Enter bugs at http://blackfin.uclinux.org/
+ * 2008 Benjamin Matthews <bmat@lle.rochester.edu>
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
* More info about the BlackStamp at:
* http://blackfin.uclinux.org/gf/project/blackstamp/
@@ -281,19 +275,6 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include <linux/i2c-gpio.h>
@@ -384,8 +365,6 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
&i2c_gpio_device,
#endif
-
- &bfin_gpios_device,
};
static int __init blackstamp_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index 7443b26c80c..7fc3b860d4a 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -1,30 +1,10 @@
/*
- * File: arch/blackfin/mach-bf533/boards/cm_bf533.c
- * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au> Copyright 2005
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2008-2009 Bluetechnix
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2005
- * Description: Board description file
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -261,19 +241,6 @@ static struct platform_device smsc911x_device = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
static struct resource bfin_uart_resources[] = {
{
@@ -506,8 +473,6 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&para_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init cm_bf533_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index fd518e383b7..d4689dcc198 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf533/ezkit.c
- * Based on: Original Work
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2005
- * Description:
- *
- * Modified: Robin Getz <rgetz@blackfin.uclinux.org> - Named the boards
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -33,12 +11,14 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
#include <linux/usb/isp1362.h>
#endif
#include <linux/irq.h>
+#include <linux/i2c.h>
#include <asm/dma.h>
#include <asm/bfin5xx_spi.h>
#include <asm/portmux.h>
@@ -56,12 +36,6 @@ static struct platform_device rtc_device = {
};
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
-static struct platform_device bfin_fb_adv7393_device = {
- .name = "bfin-adv7393",
-};
-#endif
-
/*
* USB-LAN EzExtender board
* Driver needs to know address, irq and flag pin.
@@ -98,54 +72,69 @@ static struct platform_device smc91x_device = {
};
#endif
-#if defined(CONFIG_MTD_PSD4256G) || defined(CONFIG_MTD_PSD4256G_MODULE)
-static const char *map_probes[] = {
- "stm_flash",
- NULL,
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition ezkit_partitions_a[] = {
+ {
+ .name = "bootloader(nor a)",
+ .size = 0x40000,
+ .offset = 0,
+ }, {
+ .name = "linux kernel(nor a)",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
};
-static struct platdata_mtd_ram stm_pri_data_a = {
- .mapname = "Flash A Primary",
- .map_probes = map_probes,
- .bankwidth = 2,
+static struct physmap_flash_data ezkit_flash_data_a = {
+ .width = 2,
+ .parts = ezkit_partitions_a,
+ .nr_parts = ARRAY_SIZE(ezkit_partitions_a),
};
-static struct resource stm_pri_resource_a = {
+static struct resource ezkit_flash_resource_a = {
.start = 0x20000000,
.end = 0x200fffff,
.flags = IORESOURCE_MEM,
};
-static struct platform_device stm_pri_device_a = {
- .name = "mtd-ram",
+static struct platform_device ezkit_flash_device_a = {
+ .name = "physmap-flash",
.id = 0,
.dev = {
- .platform_data = &stm_pri_data_a,
+ .platform_data = &ezkit_flash_data_a,
},
.num_resources = 1,
- .resource = &stm_pri_resource_a,
+ .resource = &ezkit_flash_resource_a,
+};
+
+static struct mtd_partition ezkit_partitions_b[] = {
+ {
+ .name = "file system(nor b)",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
};
-static struct platdata_mtd_ram stm_pri_data_b = {
- .mapname = "Flash B Primary",
- .map_probes = map_probes,
- .bankwidth = 2,
+static struct physmap_flash_data ezkit_flash_data_b = {
+ .width = 2,
+ .parts = ezkit_partitions_b,
+ .nr_parts = ARRAY_SIZE(ezkit_partitions_b),
};
-static struct resource stm_pri_resource_b = {
+static struct resource ezkit_flash_resource_b = {
.start = 0x20100000,
.end = 0x201fffff,
.flags = IORESOURCE_MEM,
};
-static struct platform_device stm_pri_device_b = {
- .name = "mtd-ram",
+static struct platform_device ezkit_flash_device_b = {
+ .name = "physmap-flash",
.id = 4,
.dev = {
- .platform_data = &stm_pri_data_b,
+ .platform_data = &ezkit_flash_data_b,
},
.num_resources = 1,
- .resource = &stm_pri_resource_b,
+ .resource = &ezkit_flash_resource_b,
};
#endif
@@ -400,19 +389,6 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include <linux/i2c-gpio.h>
@@ -460,13 +436,21 @@ static struct platform_device bfin_dpmc = {
},
};
+static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+ {
+ I2C_BOARD_INFO("bfin-adv7393", 0x2B),
+ },
+#endif
+};
+
static struct platform_device *ezkit_devices[] __initdata = {
&bfin_dpmc,
-#if defined(CONFIG_MTD_PSD4256G) || defined(CONFIG_MTD_PSD4256G_MODULE)
- &stm_pri_device_a,
- &stm_pri_device_b,
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+ &ezkit_flash_device_a,
+ &ezkit_flash_device_b,
#endif
#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
@@ -482,10 +466,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
&bfin_spi0_device,
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
- &bfin_fb_adv7393_device,
-#endif
-
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
&rtc_device,
#endif
@@ -507,8 +487,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
&i2c_gpio_device,
#endif
-
- &bfin_gpios_device,
};
static int __init ezkit_init(void)
@@ -516,6 +494,8 @@ static int __init ezkit_init(void)
printk(KERN_INFO "%s(): registering device resources\n", __func__);
platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+ i2c_register_board_info(0, bfin_i2c_board_info,
+ ARRAY_SIZE(bfin_i2c_board_info));
return 0;
}
diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c
index f19b63378b1..644be5e5ab6 100644
--- a/arch/blackfin/mach-bf533/boards/ip0x.c
+++ b/arch/blackfin/mach-bf533/boards/ip0x.c
@@ -1,34 +1,12 @@
/*
- * File: arch/blackfin/mach-bf533/ip0x.c
- * Based on: arch/blackfin/mach-bf533/bf1.c
- * Based on: arch/blackfin/mach-bf533/stamp.c
- * Author: Ivan Danov <idanov@gmail.com>
- * Modified for IP0X David Rowe
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2007 David Rowe
+ * 2006 Intratrade Ltd.
+ * Ivan Danov <idanov@gmail.com>
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2007
- * Description: Board info file for the IP04/IP08 boards, which
- * are derived from the BlackfinOne V2.0 boards.
- *
- * Modified:
- * COpyright 2007 David Rowe
- * Copyright 2006 Intratrade Ltd.
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -145,7 +123,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = {
.ctl_reg = 0x1000, /* CPOL=0,CPHA=0,Sandisk 1G work */
.enable_dma = 0, /* if 1 - block!!! */
.bits_per_word = 8,
- .cs_change_per_word = 0,
};
#endif
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 729fd7c2633..82f70efd66e 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf533/stamp.c
- * Based on: arch/blackfin/mach-bf533/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2005
- * Description: Board Info File for the BF533-STAMP
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -95,12 +73,6 @@ static struct platform_device smc91x_device = {
};
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
-static struct platform_device bfin_fb_adv7393_device = {
- .name = "bfin-adv7393",
-};
-#endif
-
#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
static struct resource net2272_bfin_resources[] = {
{
@@ -436,19 +408,6 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include <linux/i2c-gpio.h>
@@ -487,6 +446,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
.irq = 39,
},
#endif
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+ {
+ I2C_BOARD_INFO("bfin-adv7393", 0x2B),
+ },
+#endif
};
static const unsigned int cclk_vlev_datasheet[] =
@@ -528,10 +492,6 @@ static struct platform_device *stamp_devices[] __initdata = {
&smc91x_device,
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
- &bfin_fb_adv7393_device,
-#endif
-
#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
&net2272_bfin_device,
#endif
@@ -563,8 +523,6 @@ static struct platform_device *stamp_devices[] __initdata = {
&i2c_gpio_device,
#endif
- &bfin_gpios_device,
-
#if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE)
&stamp_flash_device,
#endif
diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c
index 7a443c37fb9..4a14a46a9a6 100644
--- a/arch/blackfin/mach-bf533/dma.c
+++ b/arch/blackfin/mach-bf533/dma.c
@@ -1,31 +1,11 @@
/*
- * File: arch/blackfin/mach-bf533/dma.c
- * Based on:
- * Author:
+ * simple DMA Implementation for Blackfin
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
+
#include <linux/module.h>
#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf533/include/mach/bf533.h b/arch/blackfin/mach-bf533/include/mach/bf533.h
index cf4427cd3f7..e3e05f8f7af 100644
--- a/arch/blackfin/mach-bf533/include/mach/bf533.h
+++ b/arch/blackfin/mach-bf533/include/mach/bf533.h
@@ -1,30 +1,9 @@
/*
- * File: include/asm-blackfin/mach-bf533/bf533.h
- * Based on:
- * Author:
+ * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
*
- * Created:
- * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __MACH_BF533_H__
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index 6965b4088c4..9e1f3defb6b 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
- * based on:
- * author:
+ * Copyright 2006-2009 Analog Devices Inc.
*
- * created:
- * description:
- * blackfin serial driver head file
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later
*/
#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf533/include/mach/blackfin.h b/arch/blackfin/mach-bf533/include/mach/blackfin.h
index 499e897a4f4..f4bd6df5d96 100644
--- a/arch/blackfin/mach-bf533/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf533/include/mach/blackfin.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf533/blackfin.h
- * Based on:
- * Author:
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf533/include/mach/cdefBF532.h b/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
index bbc3c8386d4..feb2392c43e 100644
--- a/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
+++ b/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf533/cdefBF532.h
- * Based on:
- * Author:
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF532_H
diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h
index 7f4633223e6..02b328eb0e0 100644
--- a/arch/blackfin/mach-bf533/include/mach/defBF532.h
+++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h
@@ -1,48 +1,10 @@
-/************************************************************************
- *
- * This file is subject to the terms and conditions of the GNU Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Non-GPL License also available as part of VisualDSP++
- * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
- *
- * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved
- *
- * This file under source code control, please send bugs or changes to:
- * dsptools.support@analog.com
- *
- ************************************************************************/
/*
- * File: include/asm-blackfin/mach-bf533/defBF532.h
- * Based on:
- * Author:
- *
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * System & MMR bit and Address definitions for ADSP-BF532
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
-/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532 */
#ifndef _DEF_BF532_H
#define _DEF_BF532_H
diff --git a/arch/blackfin/mach-bf533/include/mach/gpio.h b/arch/blackfin/mach-bf533/include/mach/gpio.h
index e45c17077af..2af19d69a7a 100644
--- a/arch/blackfin/mach-bf533/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf533/include/mach/gpio.h
@@ -1,7 +1,4 @@
/*
- * File: arch/blackfin/mach-bf533/include/mach/gpio.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
* Copyright (C) 2008 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-bf533/include/mach/irq.h b/arch/blackfin/mach-bf533/include/mach/irq.h
index db1e346cd1a..c31498be0bb 100644
--- a/arch/blackfin/mach-bf533/include/mach/irq.h
+++ b/arch/blackfin/mach-bf533/include/mach/irq.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf533/defBF532.h
- * Based on:
- * Author:
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _BF533_IRQ_H_
diff --git a/arch/blackfin/mach-bf533/include/mach/portmux.h b/arch/blackfin/mach-bf533/include/mach/portmux.h
index 2f59ce0b0cb..075dae1af16 100644
--- a/arch/blackfin/mach-bf533/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf533/include/mach/portmux.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
#ifndef _MACH_PORTMUX_H_
#define _MACH_PORTMUX_H_
diff --git a/arch/blackfin/mach-bf533/ints-priority.c b/arch/blackfin/mach-bf533/ints-priority.c
index f51994b7a2b..8f714cf8135 100644
--- a/arch/blackfin/mach-bf533/ints-priority.c
+++ b/arch/blackfin/mach-bf533/ints-priority.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf533/ints-priority.c
- * Based on:
- * Author: Michael Hennerich
+ * Set up the interrupt priorities
*
- * Created: ?
- * Description: Set up the interrupt priorities
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
index 87acb7dd2df..c85f4d77053 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -1,31 +1,10 @@
/*
- * File: arch/blackfin/mach-bf537/boards/cm_bf537.c
- * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2008-2009 Bluetechnix
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2005
- * Description: Board description file
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -297,19 +276,6 @@ static struct platform_device net2272_bfin_device = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
static struct mtd_partition cm_partitions[] = {
{
@@ -699,8 +665,6 @@ static struct platform_device *cm_bf537e_devices[] __initdata = {
#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
&cm_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init cm_bf537e_init(void)
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
index 8219dc3d65b..ea11aa81340 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
@@ -1,31 +1,10 @@
/*
- * File: arch/blackfin/mach-bf537/boards/cm_bf537u.c
- * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2008-2009 Bluetechnix
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2005
- * Description: Board description file
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -298,19 +277,6 @@ static struct platform_device net2272_bfin_device = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
static struct mtd_partition cm_partitions[] = {
{
@@ -605,8 +571,6 @@ static struct platform_device *cm_bf537u_devices[] __initdata = {
#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
&cm_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init cm_bf537u_init(void)
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c
index 399f81da7b9..0da92725270 100644
--- a/arch/blackfin/mach-bf537/boards/minotaur.c
+++ b/arch/blackfin/mach-bf537/boards/minotaur.c
@@ -1,4 +1,10 @@
/*
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2008-2009 Cambridge Signal Processing
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
+ *
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 10b35b838ba..9ba290466b5 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf537/boards/stamp.c
- * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -302,7 +280,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = {
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
- .cs_change_per_word = 0,
.enable_dma = 0,
.bits_per_word = 16,
};
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 9db6b40743e..c46baa5e6d9 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf537/boards/stamp.c
- * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -121,19 +99,6 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
static struct resource bfin_pcmcia_cf_resources[] = {
{
@@ -1078,12 +1043,6 @@ static struct platform_device bfin_fb_device = {
};
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
-static struct platform_device bfin_fb_adv7393_device = {
- .name = "bfin-adv7393",
-};
-#endif
-
#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
#include <asm/bfin-lq035q1.h>
@@ -1498,6 +1457,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
.platform_data = (void *)&adp5588_gpio_data,
},
#endif
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+ {
+ I2C_BOARD_INFO("bfin-adv7393", 0x2B),
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -1668,10 +1632,6 @@ static struct platform_device *stamp_devices[] __initdata = {
&bfin_lq035q1_device,
#endif
-#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
- &bfin_fb_adv7393_device,
-#endif
-
#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
&bfin_uart_device,
#endif
@@ -1702,8 +1662,6 @@ static struct platform_device *stamp_devices[] __initdata = {
&bfin_device_gpiokeys,
#endif
- &bfin_gpios_device,
-
#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
&bfin_async_nand_device,
#endif
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
index 61353f7bcb9..57163b65a4f 100644
--- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -1,31 +1,10 @@
/*
- * File: arch/blackfin/mach-bf537/boards/tcm_bf537.c
- * Based on: arch/blackfin/mach-bf533/boards/cm_bf537.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2008-2009 Bluetechnix
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2005
- * Description: Board description file
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -298,19 +277,6 @@ static struct platform_device net2272_bfin_device = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
static struct mtd_partition cm_partitions[] = {
{
@@ -607,8 +573,6 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
&cm_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init tcm_bf537_init(void)
diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c
index d23fc0edf2b..5c8c4ed517b 100644
--- a/arch/blackfin/mach-bf537/dma.c
+++ b/arch/blackfin/mach-bf537/dma.c
@@ -1,31 +1,11 @@
/*
- * File: arch/blackfin/mach-bf537/dma.c
- * Based on:
- * Author:
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
+ * Licensed under the GPL-2 or later.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * This file contains the simple DMA Implementation for Blackfin
*/
+
#include <linux/module.h>
#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf537/include/mach/bf537.h b/arch/blackfin/mach-bf537/include/mach/bf537.h
index f194a848ae8..17fab447466 100644
--- a/arch/blackfin/mach-bf537/include/mach/bf537.h
+++ b/arch/blackfin/mach-bf537/include/mach/bf537.h
@@ -1,30 +1,9 @@
/*
- * File: include/asm-blackfin/mach-bf537/bf537.h
- * Based on:
- * Author:
+ * System MMR Register and memory map for ADSP-BF537
*
- * Created:
- * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF537
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __MACH_BF537_H__
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
index e95d54f9af6..635c91c526a 100644
--- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
- * based on:
- * author:
+ * Copyright 2006-2009 Analog Devices Inc.
*
- * created:
- * description:
- * blackfin serial driver header files
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later
*/
#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf537/include/mach/blackfin.h b/arch/blackfin/mach-bf537/include/mach/blackfin.h
index 9ee8834c8f1..eab006d260c 100644
--- a/arch/blackfin/mach-bf537/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf537/include/mach/blackfin.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf537/blackfin.h
- * Based on:
- * Author:
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf537/include/mach/cdefBF534.h b/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
index 5f8b5f845be..91825c9bd22 100644
--- a/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf537/cdefbf534.h
- * Based on:
- * Author:
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * Created:
- * Description: system mmr register map
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF534_H
diff --git a/arch/blackfin/mach-bf537/include/mach/cdefBF537.h b/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
index b8fc949a991..9363c399042 100644
--- a/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
+++ b/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf537/cdefBF537.h
- * Based on:
- * Author:
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- * System MMR Register Map
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later
*/
#ifndef _CDEF_BF537_H
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h
index a3227f9003f..cebb14feb1b 100644
--- a/arch/blackfin/mach-bf537/include/mach/defBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf537/cdefBF537.h
- * Based on:
- * Author:
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF534_H
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF537.h b/arch/blackfin/mach-bf537/include/mach/defBF537.h
index 3d6c83e31b1..8cb5d5cf0c9 100644
--- a/arch/blackfin/mach-bf537/include/mach/defBF537.h
+++ b/arch/blackfin/mach-bf537/include/mach/defBF537.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf537/defbf537.h
- * based on:
- * author:
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * created:
- * description:
- * system mmr register map
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF537_H
diff --git a/arch/blackfin/mach-bf537/include/mach/gpio.h b/arch/blackfin/mach-bf537/include/mach/gpio.h
index d77a31e45a3..104bff85290 100644
--- a/arch/blackfin/mach-bf537/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf537/include/mach/gpio.h
@@ -1,7 +1,4 @@
/*
- * File: arch/blackfin/mach-bf537/include/mach/gpio.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
* Copyright (C) 2008 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-bf537/include/mach/irq.h b/arch/blackfin/mach-bf537/include/mach/irq.h
index b2a71d5d4e5..0defa9457e7 100644
--- a/arch/blackfin/mach-bf537/include/mach/irq.h
+++ b/arch/blackfin/mach-bf537/include/mach/irq.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf537/irq.h
- * based on:
- * author:
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * created:
- * description:
- * system mmr register map
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later
*/
#ifndef _BF537_IRQ_H_
diff --git a/arch/blackfin/mach-bf537/include/mach/portmux.h b/arch/blackfin/mach-bf537/include/mach/portmux.h
index 87285e75e90..da9760329e4 100644
--- a/arch/blackfin/mach-bf537/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf537/include/mach/portmux.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
#ifndef _MACH_PORTMUX_H_
#define _MACH_PORTMUX_H_
diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c
index 51c48087e03..f6500622b35 100644
--- a/arch/blackfin/mach-bf537/ints-priority.c
+++ b/arch/blackfin/mach-bf537/ints-priority.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf537/ints-priority.c
- * Based on: arch/blackfin/mach-bf533/ints-priority.c
- * Author: Michael Hennerich
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Created:
- * Description: Set up the interrupt priorities
+ * Licensed under the GPL-2 or later.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Set up the interrupt priorities
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c
index f2ac3b0ebf2..14af5c2088d 100644
--- a/arch/blackfin/mach-bf538/boards/ezkit.c
+++ b/arch/blackfin/mach-bf538/boards/ezkit.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf538/boards/ezkit.c
- * Based on: arch/blackfin/mach-bf537/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2
*/
#include <linux/device.h>
@@ -237,7 +215,6 @@ static struct flash_platform_data bfin_spi_flash_data = {
static struct bfin5xx_spi_chip spi_flash_chip_info = {
.enable_dma = 0, /* use dma transfer with this chip*/
.bits_per_word = 8,
- .cs_change_per_word = 0,
};
#endif
@@ -506,19 +483,6 @@ static struct platform_device i2c_bfin_twi1_device = {
#endif
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
#include <linux/gpio_keys.h>
@@ -658,8 +622,6 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
&bfin_device_gpiokeys,
#endif
- &bfin_gpios_device,
-
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezkit_flash_device,
#endif
diff --git a/arch/blackfin/mach-bf538/dma.c b/arch/blackfin/mach-bf538/dma.c
index d6837fbf94e..5dc02258921 100644
--- a/arch/blackfin/mach-bf538/dma.c
+++ b/arch/blackfin/mach-bf538/dma.c
@@ -1,31 +1,11 @@
/*
- * File: arch/blackfin/mach-bf538/dma.c
- * Based on:
- * Author:
+ * the simple DMA Implementation for Blackfin
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
+ * Copyright 2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
+
#include <linux/module.h>
#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf538/include/mach/bf538.h b/arch/blackfin/mach-bf538/include/mach/bf538.h
index 9c8abb30790..0cf5bf8dab8 100644
--- a/arch/blackfin/mach-bf538/include/mach/bf538.h
+++ b/arch/blackfin/mach-bf538/include/mach/bf538.h
@@ -1,30 +1,9 @@
/*
- * File: include/asm-blackfin/mach-bf538/bf538.h
- * Based on: include/asm-blackfin/mach-bf537/bf537.h
- * Author: Michael Hennerich (michael.hennerich@analog.com)
+ * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF538
*
- * Created:
- * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF527
+ * Copyright 2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __MACH_BF538_H__
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
index 999f239fe1a..5c148142f04 100644
--- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf538/bfin_serial_5xx.h
- * based on:
- * author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * created:
- * description:
- * blackfin serial driver header files
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later.
*/
#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf538/include/mach/blackfin.h b/arch/blackfin/mach-bf538/include/mach/blackfin.h
index 5ecee169095..278e8942eef 100644
--- a/arch/blackfin/mach-bf538/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf538/include/mach/blackfin.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf538/blackfin.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
index 1de67515dc9..401ebd79d0a 100644
--- a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
+++ b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf538/cdefBF538.h
- * Based on:
- * Author:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF538_H
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h
index 1c58914a874..5f6c34dfd08 100644
--- a/arch/blackfin/mach-bf538/include/mach/defBF539.h
+++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h
@@ -1,47 +1,9 @@
-/************************************************************************
- *
- * This file is subject to the terms and conditions of the GNU Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Non-GPL License also available as part of VisualDSP++
- * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
- *
- * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved
- *
- * This file under source code control, please send bugs or changes to:
- * dsptools.support@analog.com
- *
- ************************************************************************/
/*
- * File: include/asm-blackfin/mach-bf538/defBF539.h
- * Based on:
- * Author:
- *
- * Created:
- * Description:
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
+
/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF538/9 */
#ifndef _DEF_BF539_H
diff --git a/arch/blackfin/mach-bf538/include/mach/gpio.h b/arch/blackfin/mach-bf538/include/mach/gpio.h
index 30f4f723f7c..295c78a465c 100644
--- a/arch/blackfin/mach-bf538/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf538/include/mach/gpio.h
@@ -1,7 +1,4 @@
/*
- * File: arch/blackfin/mach-bf538/include/mach/gpio.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
* Copyright (C) 2008 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-bf538/include/mach/irq.h b/arch/blackfin/mach-bf538/include/mach/irq.h
index fdc87fe2c17..a4b7fcbc556 100644
--- a/arch/blackfin/mach-bf538/include/mach/irq.h
+++ b/arch/blackfin/mach-bf538/include/mach/irq.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf538/irq.h
- * based on: include/asm-blackfin/mach-bf537/irq.h
- * author: Michael Hennerich (michael.hennerich@analog.com)
+ * Copyright 2008 Analog Devices Inc.
*
- * created:
- * description:
- * system mmr register map
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BF538_IRQ_H_
diff --git a/arch/blackfin/mach-bf538/include/mach/portmux.h b/arch/blackfin/mach-bf538/include/mach/portmux.h
index c8db264e3e4..6121cf8b587 100644
--- a/arch/blackfin/mach-bf538/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf538/include/mach/portmux.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2008-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _MACH_PORTMUX_H_
#define _MACH_PORTMUX_H_
diff --git a/arch/blackfin/mach-bf538/ints-priority.c b/arch/blackfin/mach-bf538/ints-priority.c
index 70d17e550e0..1fa793ced34 100644
--- a/arch/blackfin/mach-bf538/ints-priority.c
+++ b/arch/blackfin/mach-bf538/ints-priority.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf538/ints-priority.c
- * Based on: arch/blackfin/mach-bf533/ints-priority.c
- * Author: Michael Hennerich
+ * Set up the interrupt priorities
*
- * Created:
- * Description: Set up the interrupt priorities
+ * Copyright 2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index e565aae11d7..ccdcd6da2e9 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -1,31 +1,10 @@
/*
- * File: arch/blackfin/mach-bf548/boards/cm_bf548.c
- * Based on: arch/blackfin/mach-bf537/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2008-2009 Bluetechnix
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -380,19 +359,6 @@ static struct platform_device musb_device = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
static struct resource bfin_atapi_resources[] = {
{
@@ -546,13 +512,11 @@ static struct flash_platform_data bfin_spi_flash_data = {
static struct bfin5xx_spi_chip spi_flash_chip_info = {
.enable_dma = 0, /* use dma transfer with this chip*/
.bits_per_word = 8,
- .cs_change_per_word = 0,
};
#endif
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
- .cs_change_per_word = 0,
.enable_dma = 0,
.bits_per_word = 16,
};
@@ -853,8 +817,6 @@ static struct platform_device *cm_bf548_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&para_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init cm_bf548_init(void)
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index c66f3801274..1a5286bbb3f 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -1,31 +1,9 @@
/*
- * File: arch/blackfin/mach-bf548/boards/ezkit.c
- * Based on: arch/blackfin/mach-bf537/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au>
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2005 National ICT Australia (NICTA)
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -208,7 +186,6 @@ static struct platform_device bfin_rotary_device = {
#endif
#if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE)
-#include <linux/input.h>
#include <linux/spi/adxl34x.h>
static const struct adxl34x_platform_data adxl34x_info = {
.x_axis_offset = 0,
@@ -636,7 +613,6 @@ static struct flash_platform_data bfin_spi_flash_data = {
static struct bfin5xx_spi_chip spi_flash_chip_info = {
.enable_dma = 0, /* use dma transfer with this chip*/
.bits_per_word = 8,
- .cs_change_per_word = 0,
};
#endif
@@ -650,7 +626,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
- .cs_change_per_word = 0,
.enable_dma = 0,
.bits_per_word = 16,
};
@@ -681,7 +656,6 @@ static struct bfin5xx_spi_chip spidev_chip_info = {
static struct bfin5xx_spi_chip spi_adxl34x_chip_info = {
.enable_dma = 0, /* use dma transfer with this chip*/
.bits_per_word = 8,
- .cs_change_per_word = 0,
};
#endif
@@ -908,19 +882,6 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
static const unsigned int cclk_vlev_datasheet[] =
{
/*
@@ -1028,8 +989,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
&bfin_device_gpiokeys,
#endif
- &bfin_gpios_device,
-
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezkit_flash_device,
#endif
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
index d9239bc05dd..039a6d9d38f 100644
--- a/arch/blackfin/mach-bf548/dma.c
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf548/dma.c
- * Based on:
- * Author:
+ * the simple DMA Implementation for Blackfin
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf548/include/mach/bf548.h b/arch/blackfin/mach-bf548/include/mach/bf548.h
index cd31f72bdd8..7bead5ce0f3 100644
--- a/arch/blackfin/mach-bf548/include/mach/bf548.h
+++ b/arch/blackfin/mach-bf548/include/mach/bf548.h
@@ -1,30 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/bf548.h
- * Based on:
- * Author:
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Created:
- * Description: System MMR register and memory map for ADSP-BF548
- *
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __MACH_BF548_H__
diff --git a/arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h b/arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h
index 9c7ca62a45e..8821efe57fb 100644
--- a/arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h
+++ b/arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef BF54X_LQ043_H
#define BF54X_LQ043_H
diff --git a/arch/blackfin/mach-bf548/include/mach/bf54x_keys.h b/arch/blackfin/mach-bf548/include/mach/bf54x_keys.h
index 1fb4ec77cc2..49338ae299a 100644
--- a/arch/blackfin/mach-bf548/include/mach/bf54x_keys.h
+++ b/arch/blackfin/mach-bf548/include/mach/bf54x_keys.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _BFIN_KPAD_H
#define _BFIN_KPAD_H
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
index 2d1b5fa3cca..dd44aa75fe7 100644
--- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
- * based on:
- * author:
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * created:
- * description:
- * blackfin serial driver head file
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later.
*/
#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf548/include/mach/blackfin.h b/arch/blackfin/mach-bf548/include/mach/blackfin.h
index 318667b2f03..13302b67857 100644
--- a/arch/blackfin/mach-bf548/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf548/include/mach/blackfin.h
@@ -1,32 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/blackfin.h
- * Based on:
- * Author:
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF542.h b/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
index 07aefb9ed79..42f4a946954 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/cdefBF542.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF542_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF544.h b/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
index 431a6927899..2207799575f 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/cdefBF544.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF544_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF547.h b/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
index 93376e90dfc..42342151513 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/cdefBF547.h
- * Based on:
- * Author:
+ * Copyright 2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF548.h b/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
index 9cd74384136..df84180410c 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/cdefBF548.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF549.h b/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
index ead360b69de..34c84c7fb25 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf549/cdefBF549.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF549_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
index 6e636c418cb..a2e9d9849eb 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/cdefBF54x_base.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF54X_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF542.h b/arch/blackfin/mach-bf548/include/mach/defBF542.h
index b1316541b8d..d3bc6d1df54 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF542.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF542.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/defBF542.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF542_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF544.h b/arch/blackfin/mach-bf548/include/mach/defBF544.h
index c2c785bdc5f..dd414ae4ba4 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF544.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF544.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/defBF544.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF544_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h
index 661f0d877bd..5a9dbabe0a6 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF547.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/defBF547.h
- * Based on:
- * Author:
+ * Copyright 2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF548.h b/arch/blackfin/mach-bf548/include/mach/defBF548.h
index 85d4bade911..82cd593f739 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF548.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF548.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/defBF548.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF549.h b/arch/blackfin/mach-bf548/include/mach/defBF549.h
index 09673454164..6fc6e39ab61 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF549.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF549.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/defBF549.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF549_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
index e022e896cb1..8590c8c7833 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf548/defBF54x_base.h
- * Based on:
- * Author:
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF54X_H
diff --git a/arch/blackfin/mach-bf548/include/mach/gpio.h b/arch/blackfin/mach-bf548/include/mach/gpio.h
index 3a205170978..850e39d193e 100644
--- a/arch/blackfin/mach-bf548/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf548/include/mach/gpio.h
@@ -1,34 +1,8 @@
/*
- * File: include/asm-blackfin/mach-bf548/gpio.h
- * Based on:
- * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
- *
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright 2007-2009 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
*/
-
-
#define GPIO_PA0 0
#define GPIO_PA1 1
#define GPIO_PA2 2
diff --git a/arch/blackfin/mach-bf548/include/mach/irq.h b/arch/blackfin/mach-bf548/include/mach/irq.h
index f194625f682..106db05684a 100644
--- a/arch/blackfin/mach-bf548/include/mach/irq.h
+++ b/arch/blackfin/mach-bf548/include/mach/irq.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf548/irq.h
- * based on: include/asm-blackfin/mach-bf537/irq.h
- * author: Roy Huang (roy.huang@analog.com)
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * created:
- * description:
- * system mmr register map
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BF548_IRQ_H_
diff --git a/arch/blackfin/mach-bf548/include/mach/portmux.h b/arch/blackfin/mach-bf548/include/mach/portmux.h
index ce372ba0f04..89ad6a88636 100644
--- a/arch/blackfin/mach-bf548/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf548/include/mach/portmux.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _MACH_PORTMUX_H_
#define _MACH_PORTMUX_H_
diff --git a/arch/blackfin/mach-bf548/ints-priority.c b/arch/blackfin/mach-bf548/ints-priority.c
index 9dd0fa3ac4d..48dd3a4bc4a 100644
--- a/arch/blackfin/mach-bf548/ints-priority.c
+++ b/arch/blackfin/mach-bf548/ints-priority.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf537/ints-priority.c
- * Based on: arch/blackfin/mach-bf533/ints-priority.c
- * Author: Michael Hennerich
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Created:
- * Description: Set up the interrupt priorities
+ * Licensed under the GPL-2 or later.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Set up the interrupt priorities
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf561/atomic.S b/arch/blackfin/mach-bf561/atomic.S
index 9439bc6bd01..0261a5e751b 100644
--- a/arch/blackfin/mach-bf561/atomic.S
+++ b/arch/blackfin/mach-bf561/atomic.S
@@ -1,23 +1,8 @@
/*
- * File: arch/blackfin/mach-bf561/atomic.S
- * Author: Philippe Gerum <rpm@xenomai.org>
+ * Copyright 2007-2008 Analog Devices Inc.
+ * Philippe Gerum <rpm@xenomai.org>
*
- * Copyright 2007 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index 6577ecfcf11..dfc8d5b7798 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -1,30 +1,10 @@
/*
- * File: arch/blackfin/mach-bf533/boards/cm_bf561.c
- * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
- * Author: Aidan Williams <aidan@nicta.com.au> Copyright 2005
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2008-2009 Bluetechnix
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created: 2006
- * Description: Board description file
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -285,19 +265,6 @@ static struct platform_device net2272_bfin_device = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
static struct resource isp1362_hcd_resources[] = {
{
@@ -532,8 +499,6 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&para_flash_device,
#endif
-
- &bfin_gpios_device,
};
static int __init cm_bf561_init(void)
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index caed96bb957..9e2d8cfba54 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf561/ezkit.c
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/device.h>
@@ -387,19 +366,6 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
-static struct resource bfin_gpios_resources = {
- .start = 0,
- .end = MAX_BLACKFIN_GPIOS - 1,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
- .name = "simple-gpio",
- .id = -1,
- .num_resources = 1,
- .resource = &bfin_gpios_resources,
-};
-
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include <linux/i2c-gpio.h>
@@ -493,8 +459,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
&isp1362_hcd_device,
#endif
- &bfin_gpios_device,
-
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
&ezkit_flash_device,
#endif
diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c
index 6f77dbe952f..8ba7252455e 100644
--- a/arch/blackfin/mach-bf561/boards/tepla.c
+++ b/arch/blackfin/mach-bf561/boards/tepla.c
@@ -1,15 +1,13 @@
/*
- * File: arch/blackfin/mach-bf561/tepla.c
+ * Copyright 2004-2007 Analog Devices Inc.
+ * 2005 National ICT Australia (NICTA)
+ * Aidan Williams <aidan@nicta.com.au>
*
- * Copyright 2004-2007 Analog Devices Inc.
- * Only SMSC91C1111 was registered, may do more later.
+ * Thanks to Jamey Hicks.
*
- * Copyright 2005 National ICT Australia (NICTA), Aidan Williams <aidan@nicta.com.au>
- * Thanks to Jamey Hicks.
+ * Only SMSC91C1111 was registered, may do more later.
*
- * 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.
+ * Licensed under the GPL-2
*/
#include <linux/device.h>
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
index 93635a766f9..1e60a92dd60 100644
--- a/arch/blackfin/mach-bf561/coreb.c
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -48,7 +48,7 @@ coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned l
return ret;
}
-static struct file_operations coreb_fops = {
+static const struct file_operations coreb_fops = {
.owner = THIS_MODULE,
.ioctl = coreb_ioctl,
};
diff --git a/arch/blackfin/mach-bf561/dma.c b/arch/blackfin/mach-bf561/dma.c
index 42b0037afe6..c938c3c7355 100644
--- a/arch/blackfin/mach-bf561/dma.c
+++ b/arch/blackfin/mach-bf561/dma.c
@@ -1,31 +1,11 @@
/*
- * File: arch/blackfin/mach-bf561/dma.c
- * Based on:
- * Author:
+ * the simple DMA Implementation for Blackfin
*
- * Created:
- * Description: This file contains the simple DMA Implementation for Blackfin
+ * Copyright 2007-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
+
#include <linux/module.h>
#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf561/include/mach/bf561.h b/arch/blackfin/mach-bf561/include/mach/bf561.h
index 9968362a2ee..9f9a367e6a2 100644
--- a/arch/blackfin/mach-bf561/include/mach/bf561.h
+++ b/arch/blackfin/mach-bf561/include/mach/bf561.h
@@ -1,30 +1,9 @@
/*
- * File: include/asm-blackfin/mach-bf561/bf561.h
- * Based on:
- * Author:
+ * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
*
- * Created:
- * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __MACH_BF561_H__
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
index fd5e8878b8c..e33e158bc16 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
/*
- * file: include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
- * based on:
- * author:
+ * Copyright 2006-2009 Analog Devices Inc.
*
- * created:
- * description:
- * blackfin serial driver head file
- * rev:
- *
- * modified:
- *
- *
- * bugs: enter bugs at http://blackfin.uclinux.org/
- *
- * this program is free software; you can redistribute it and/or modify
- * it under the terms of the gnu general public license as published by
- * the free software foundation; either version 2, or (at your option)
- * any later version.
- *
- * this program is distributed in the hope that it will be useful,
- * but without any warranty; without even the implied warranty of
- * merchantability or fitness for a particular purpose. see the
- * gnu general public license for more details.
- *
- * you should have received a copy of the gnu general public license
- * along with this program; see the file copying.
- * if not, write to the free software foundation,
- * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ * Licensed under the GPL-2 or later.
*/
#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf561/include/mach/blackfin.h b/arch/blackfin/mach-bf561/include/mach/blackfin.h
index 8be31358ef8..67d6bdcd3fa 100644
--- a/arch/blackfin/mach-bf561/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf561/include/mach/blackfin.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf561/blackfin.h
- * Based on:
- * Author:
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf561/include/mach/cdefBF561.h b/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
index 9d9858c2be6..81ecdb71c6a 100644
--- a/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
@@ -1,31 +1,7 @@
/*
- * File: include/asm-blackfin/mach-bf561/cdefBF561.h
- * Based on:
- * Author:
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Created:
- * Description: C POINTERS TO SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _CDEF_BF561_H
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h
index 5fc0f05026e..a31e509553f 100644
--- a/arch/blackfin/mach-bf561/include/mach/defBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h
@@ -1,32 +1,7 @@
-
/*
- * File: include/asm-blackfin/mach-bf561/defBF561.h
- * Based on:
- * Author:
- *
- * Created:
- * Description:
- * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the ADI BSD license or the GPL-2 (or later)
*/
#ifndef _DEF_BF561_H
diff --git a/arch/blackfin/mach-bf561/include/mach/gpio.h b/arch/blackfin/mach-bf561/include/mach/gpio.h
index 7882f79e1ad..a651a8cf805 100644
--- a/arch/blackfin/mach-bf561/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf561/include/mach/gpio.h
@@ -1,7 +1,4 @@
/*
- * File: arch/blackfin/mach-bf561/include/mach/gpio.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
* Copyright (C) 2008 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-bf561/include/mach/irq.h b/arch/blackfin/mach-bf561/include/mach/irq.h
index 6698389c556..7b208db267b 100644
--- a/arch/blackfin/mach-bf561/include/mach/irq.h
+++ b/arch/blackfin/mach-bf561/include/mach/irq.h
@@ -1,32 +1,7 @@
-
/*
- * File: include/asm-blackfin/mach-bf561/irq.h
- * Based on:
- * Author:
- *
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Copyright 2005-2008 Analog Devices Inc.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Licensed under the GPL-2 or later.
*/
#ifndef _BF561_IRQ_H_
diff --git a/arch/blackfin/mach-bf561/include/mach/portmux.h b/arch/blackfin/mach-bf561/include/mach/portmux.h
index 2e5ad6347de..3a7b46bbe84 100644
--- a/arch/blackfin/mach-bf561/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf561/include/mach/portmux.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _MACH_PORTMUX_H_
#define _MACH_PORTMUX_H_
diff --git a/arch/blackfin/mach-bf561/include/mach/smp.h b/arch/blackfin/mach-bf561/include/mach/smp.h
index f9e65ebe81b..390c7f4ae7b 100644
--- a/arch/blackfin/mach-bf561/include/mach/smp.h
+++ b/arch/blackfin/mach-bf561/include/mach/smp.h
@@ -1,3 +1,9 @@
+/*
+ * Copyright 2007-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
#ifndef _MACH_BF561_SMP
#define _MACH_BF561_SMP
diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c
index 9d2f2334472..b4424172ad9 100644
--- a/arch/blackfin/mach-bf561/ints-priority.c
+++ b/arch/blackfin/mach-bf561/ints-priority.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-bf561/ints-priority.c
- * Based on: arch/blackfin/mach-bf537/ints-priority.c
- * Author: Michael Hennerich
+ * Set up the interrupt priorities
*
- * Created:
- * Description: Set up the interrupt priorities
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S
index f72a6af20c4..8e6050369c0 100644
--- a/arch/blackfin/mach-bf561/secondary.S
+++ b/arch/blackfin/mach-bf561/secondary.S
@@ -1,26 +1,10 @@
/*
- * File: arch/blackfin/mach-bf561/secondary.S
- * Based on: arch/blackfin/mach-bf561/head.S
- * Author: Philippe Gerum <rpm@xenomai.org>
+ * BF561 coreB bootstrap file
*
- * Copyright 2007 Analog Devices Inc.
+ * Copyright 2007-2009 Analog Devices Inc.
+ * Philippe Gerum <rpm@xenomai.org>
*
- * Description: BF561 coreB bootstrap file
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/linkage.h>
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index 8c10701c251..510f5764149 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -1,23 +1,8 @@
/*
- * File: arch/blackfin/mach-bf561/smp.c
- * Author: Philippe Gerum <rpm@xenomai.org>
+ * Copyright 2007-2009 Analog Devices Inc.
+ * Philippe Gerum <rpm@xenomai.org>
*
- * Copyright 2007 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/init.h>
diff --git a/arch/blackfin/mach-common/arch_checks.c b/arch/blackfin/mach-common/arch_checks.c
index 5998d8632a7..9dbafcdcf47 100644
--- a/arch/blackfin/mach-common/arch_checks.c
+++ b/arch/blackfin/mach-common/arch_checks.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-common/arch_checks.c
- * Based on:
- * Author: Robin Getz <rgetz@blackfin.uclinux.org>
+ * Do some checking to make sure things are OK
*
- * Created: 25Jul07
- * Description: Do some checking to make sure things are OK
+ * Copyright 2007-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <asm/fixed_code.h>
diff --git a/arch/blackfin/mach-common/cache-c.c b/arch/blackfin/mach-common/cache-c.c
index 4ebbd78db3a..a60a24f5035 100644
--- a/arch/blackfin/mach-common/cache-c.c
+++ b/arch/blackfin/mach-common/cache-c.c
@@ -3,8 +3,6 @@
*
* Copyright 2004-2009 Analog Devices Inc.
*
- * Enter bugs at http://blackfin.uclinux.org/
- *
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S
index d9666fe6c3d..ea540318a22 100644
--- a/arch/blackfin/mach-common/cache.S
+++ b/arch/blackfin/mach-common/cache.S
@@ -3,8 +3,6 @@
*
* Copyright 2004-2008 Analog Devices Inc.
*
- * Enter bugs at http://blackfin.uclinux.org/
- *
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index 85c65808327..01506504e6d 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-common/cpufreq.c
- * Based on:
- * Author:
+ * Blackfin core clock scaling
*
- * Created:
- * Description: Blackfin core clock scaling
+ * Copyright 2008-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/kernel.h>
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 1e7cac23e25..94a0375cbdc 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -1,32 +1,11 @@
/*
- * File: arch/blackfin/mach-common/entry.S
- * Based on:
- * Author: Linus Torvalds
+ * Contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all
+ * interrupts and faults that can result in a task-switch.
*
- * Created: ?
- * Description: contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all
- * interrupts and faults that can result in a task-switch.
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
/* NOTE: This code handles signal-recognition, which happens every time
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index 9c79dfea2a5..cab0a0031ee 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -3,8 +3,6 @@
*
* Copyright 2004-2008 Analog Devices Inc.
*
- * Enter bugs at http://blackfin.uclinux.org/
- *
* Licensed under the GPL-2 or later.
*/
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 82d417ef4b5..8085ff1cce0 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -1,31 +1,11 @@
/*
- * File: arch/blackfin/mach-common/interrupt.S
- * Based on:
- * Author: D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>
- * Kenneth Albanowski <kjahds@kjahds.com>
- *
- * Created: ?
- * Description: Interrupt Entries
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
+ * Interrupt Entries
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Copyright 2005-2009 Analog Devices Inc.
+ * D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>
+ * Kenneth Albanowski <kjahds@kjahds.com>
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 6ffda78aaf9..660ea1bec54 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -1,33 +1,14 @@
/*
- * File: arch/blackfin/mach-common/ints-priority.c
+ * Set up the interrupt priorities
*
- * Description: Set up the interrupt priorities
+ * Copyright 2004-2009 Analog Devices Inc.
+ * 2003 Bas Vermeulen <bas@buyways.nl>
+ * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * 1996 Roman Zippel
*
- * Modified:
- * 1996 Roman Zippel
- * 1999 D. Jeff Dionne <jeff@uclinux.org>
- * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
- * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
- * 2003 Metrowerks/Motorola
- * 2003 Bas Vermeulen <bas@buyways.nl>
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-common/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c
index 883e3241b17..c6496249e2b 100644
--- a/arch/blackfin/mach-common/irqpanic.c
+++ b/arch/blackfin/mach-common/irqpanic.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mach-common/irqpanic.c
- * Based on:
- * Author:
+ * panic kernel with dump information
*
- * Created: ?
- * Description: panic kernel with dump information
+ * Copyright 2005-2009 Analog Devices Inc.
*
- * Modified: rgetz - added cache checking code 14Feb06
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 0e3d4ff9d8b..8837be4edb4 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -1,35 +1,11 @@
/*
- * File: arch/blackfin/mach-common/pm.c
- * Based on: arm/mach-omap/pm.c
- * Author: Cliff Brake <cbrake@accelent.com> Copyright (c) 2001
+ * Blackfin power management
*
- * Created: 2001
- * Description: Blackfin power management
+ * Copyright 2006-2009 Analog Devices Inc.
*
- * Modified: Nicolas Pitre - PXA250 support
- * Copyright (c) 2002 Monta Vista Software, Inc.
- * David Singleton - OMAP1510
- * Copyright (c) 2002 Monta Vista Software, Inc.
- * Dirk Behme <dirk.behme@de.bosch.com> - OMAP1510/1610
- * Copyright 2004
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2
+ * based on arm/mach-omap/pm.c
+ * Copyright 2001, Cliff Brake <cbrake@accelent.com> and others
*/
#include <linux/suspend.h>
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 349ee3f5466..d98585f3237 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -1,24 +1,10 @@
/*
- * File: arch/blackfin/kernel/smp.c
- * Author: Philippe Gerum <rpm@xenomai.org>
- * IPI management based on arch/arm/kernel/smp.c.
+ * IPI management based on arch/arm/kernel/smp.c (Copyright 2002 ARM Limited)
*
- * Copyright 2007 Analog Devices Inc.
+ * Copyright 2007-2009 Analog Devices Inc.
+ * Philippe Gerum <rpm@xenomai.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2.
*/
#include <linux/module.h>
diff --git a/arch/blackfin/mm/blackfin_sram.h b/arch/blackfin/mm/blackfin_sram.h
index bc0062884fd..fb0b1599cfb 100644
--- a/arch/blackfin/mm/blackfin_sram.h
+++ b/arch/blackfin/mm/blackfin_sram.h
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mm/blackfin_sram.h
- * Based on: arch/blackfin/mm/blackfin_sram.c
- * Author: Mike Frysinger
+ * Local prototypes meant for internal use only
*
- * Created: Aug 2006
- * Description: Local prototypes meant for internal use only
+ * Copyright 2006-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __BLACKFIN_SRAM_H__
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index b88ce7fda54..bb9c98f9cb5 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -1,30 +1,7 @@
/*
- * File: arch/blackfin/mm/init.c
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/swap.h>
diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c
index beb1a608824..84cdc5a1c13 100644
--- a/arch/blackfin/mm/isram-driver.c
+++ b/arch/blackfin/mm/isram-driver.c
@@ -1,19 +1,9 @@
/*
- * Description: Instruction SRAM accessor functions for the Blackfin
+ * Instruction SRAM accessor functions for the Blackfin
*
* Copyright 2008 Analog Devices Inc.
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later
*/
#define pr_fmt(fmt) "isram: " fmt
diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c
index eb63ab353e5..f068c11ea98 100644
--- a/arch/blackfin/mm/sram-alloc.c
+++ b/arch/blackfin/mm/sram-alloc.c
@@ -1,30 +1,9 @@
/*
- * File: arch/blackfin/mm/sram-alloc.c
- * Based on:
- * Author:
+ * SRAM allocator for Blackfin on-chip memory
*
- * Created:
- * Description: SRAM allocator for Blackfin L1 and L2 memory
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2008 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c
index 6cc1a0319a5..562b9a7feae 100644
--- a/arch/cris/arch-v10/drivers/sync_serial.c
+++ b/arch/cris/arch-v10/drivers/sync_serial.c
@@ -244,7 +244,7 @@ static unsigned sync_serial_prescale_shadow;
#define NUMBER_OF_PORTS 2
-static struct file_operations sync_serial_fops = {
+static const struct file_operations sync_serial_fops = {
.owner = THIS_MODULE,
.write = sync_serial_write,
.read = sync_serial_read,
diff --git a/arch/cris/arch-v32/drivers/mach-fs/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
index fe1fde89388..d89ab80498e 100644
--- a/arch/cris/arch-v32/drivers/mach-fs/gpio.c
+++ b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
@@ -855,7 +855,7 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
return 0;
}
-struct file_operations gpio_fops = {
+static const struct file_operations gpio_fops = {
.owner = THIS_MODULE,
.poll = gpio_poll,
.ioctl = gpio_ioctl,
diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h
index d06933bd631..4010f1fc5b6 100644
--- a/arch/m32r/include/asm/io.h
+++ b/arch/m32r/include/asm/io.h
@@ -162,6 +162,13 @@ static inline void _writel(unsigned long l, unsigned long addr)
#define __raw_writew writew
#define __raw_writel writel
+#define ioread8 read
+#define ioread16 readw
+#define ioread32 readl
+#define iowrite8 writeb
+#define iowrite16 writew
+#define iowrite32 writel
+
#define mmiowb()
#define flush_write_buffers() do { } while (0) /* M32R_FIXME */
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c
index 22624b51d4d..700570747a9 100644
--- a/arch/m32r/kernel/m32r_ksyms.c
+++ b/arch/m32r/kernel/m32r_ksyms.c
@@ -23,12 +23,6 @@ EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(kernel_thread);
-/* Networking helper routines. */
-/* Delay loops */
-EXPORT_SYMBOL(__udelay);
-EXPORT_SYMBOL(__delay);
-EXPORT_SYMBOL(__const_udelay);
-
EXPORT_SYMBOL(strncpy_from_user);
EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(clear_user);
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index ba61c4c7320..e7fee0f198d 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -33,6 +33,15 @@
#include <asm/hw_irq.h>
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+/* this needs a better home */
+DEFINE_SPINLOCK(rtc_lock);
+
+#ifdef CONFIG_RTC_DRV_CMOS_MODULE
+EXPORT_SYMBOL(rtc_lock);
+#endif
+#endif /* pc-style 'CMOS' RTC support */
+
#ifdef CONFIG_SMP
extern void smp_local_timer_interrupt(void);
#endif
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
index 03b14e55cd8..fbd109031df 100644
--- a/arch/m32r/kernel/traps.c
+++ b/arch/m32r/kernel/traps.c
@@ -104,8 +104,8 @@ static void set_eit_vector_entries(void)
eit_vector[186] = (unsigned long)smp_call_function_interrupt;
eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt;
eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt;
- eit_vector[189] = (unsigned long)smp_call_function_single_interrupt;
- eit_vector[190] = 0;
+ eit_vector[189] = 0; /* CPU_BOOT_IPI */
+ eit_vector[190] = (unsigned long)smp_call_function_single_interrupt;
eit_vector[191] = 0;
#endif
_flush_cache_copyback_all();
diff --git a/arch/m32r/lib/delay.c b/arch/m32r/lib/delay.c
index ced549be80f..940f4837e42 100644
--- a/arch/m32r/lib/delay.c
+++ b/arch/m32r/lib/delay.c
@@ -122,4 +122,8 @@ void __ndelay(unsigned long nsecs)
{
__const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
}
+
+EXPORT_SYMBOL(__delay);
+EXPORT_SYMBOL(__const_udelay);
+EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(__ndelay);
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c
index b7a78ad429b..5d2858f6eed 100644
--- a/arch/m32r/mm/discontig.c
+++ b/arch/m32r/mm/discontig.c
@@ -32,6 +32,9 @@ typedef struct {
} mem_prof_t;
static mem_prof_t mem_prof[MAX_NUMNODES];
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
static void __init mem_prof_init(void)
{
unsigned long start_pfn, holes, free_pfn;
@@ -42,7 +45,7 @@ static void __init mem_prof_init(void)
/* Node#0 SDRAM */
mp = &mem_prof[0];
mp->start_pfn = PFN_UP(CONFIG_MEMORY_START);
- mp->pages = PFN_DOWN(CONFIG_MEMORY_SIZE);
+ mp->pages = PFN_DOWN(memory_end - memory_start);
mp->holes = 0;
mp->free_pfn = PFN_UP(__pa(_end));
diff --git a/arch/m32r/mm/mmu.S b/arch/m32r/mm/mmu.S
index 49a6d16a3d5..e9491a5ae82 100644
--- a/arch/m32r/mm/mmu.S
+++ b/arch/m32r/mm/mmu.S
@@ -150,9 +150,13 @@ ENTRY(tme_handler)
; pmd = pmd_offset(pgd, address);
ld r3, @r3 ; r3: pmd data
- ldi r2, #-4096
beqz r3, 3f ; pmd_none(*pmd) ?
+ and3 r2, r3, #0xfff
+ add3 r2, r2, #-355 ; _KERNPG_TABLE(=0x163)
+ bnez r2, 3f ; pmd_bad(*pmd) ?
+ ldi r2, #-4096
+
; pte = pte_offset(pmd, address);
and r2, r3 ; r2: pte base addr
srl3 r3, r0, #10
@@ -263,9 +267,9 @@ ENTRY(tme_handler)
ld r1, @r3 ; r1: pmd
beqz r1, 3f ; pmd_none(*pmd) ?
;
- and3 r1, r1, #0xeff
- ldi r4, #611 ; _KERNPG_TABLE(=611)
- bne r1, r4, 3f ; !pmd_bad(*pmd) ?
+ and3 r1, r1, #0x3ff
+ ldi r4, #0x163 ; _KERNPG_TABLE(=0x163)
+ bne r1, r4, 3f ; pmd_bad(*pmd) ?
.fillinsn
4:
diff --git a/arch/m68k/include/asm/hardirq_mm.h b/arch/m68k/include/asm/hardirq_mm.h
index 554f65b6cd3..394ee946015 100644
--- a/arch/m68k/include/asm/hardirq_mm.h
+++ b/arch/m68k/include/asm/hardirq_mm.h
@@ -1,8 +1,16 @@
#ifndef __M68K_HARDIRQ_H
#define __M68K_HARDIRQ_H
-#define HARDIRQ_BITS 8
+#include <linux/threads.h>
+#include <linux/cache.h>
+
+/* entry.S is sensitive to the offsets of these fields */
+typedef struct {
+ unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
-#include <asm-generic/hardirq.h>
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#define HARDIRQ_BITS 8
#endif
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
index 594ee0e657f..9a8876f715d 100644
--- a/arch/m68knommu/kernel/asm-offsets.c
+++ b/arch/m68knommu/kernel/asm-offsets.c
@@ -45,25 +45,25 @@ int main(void)
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
/* offsets into the pt_regs */
- DEFINE(PT_D0, offsetof(struct pt_regs, d0));
- DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
- DEFINE(PT_D1, offsetof(struct pt_regs, d1));
- DEFINE(PT_D2, offsetof(struct pt_regs, d2));
- DEFINE(PT_D3, offsetof(struct pt_regs, d3));
- DEFINE(PT_D4, offsetof(struct pt_regs, d4));
- DEFINE(PT_D5, offsetof(struct pt_regs, d5));
- DEFINE(PT_A0, offsetof(struct pt_regs, a0));
- DEFINE(PT_A1, offsetof(struct pt_regs, a1));
- DEFINE(PT_A2, offsetof(struct pt_regs, a2));
- DEFINE(PT_PC, offsetof(struct pt_regs, pc));
- DEFINE(PT_SR, offsetof(struct pt_regs, sr));
+ DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
+ DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
+ DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
+ DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
+ DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
+ DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
+ DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
+ DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
+ DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
+ DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
+ DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
+ DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
#ifdef CONFIG_COLDFIRE
/* bitfields are a bit difficult */
- DEFINE(PT_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
+ DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
#else
/* bitfields are a bit difficult */
- DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4);
+ DEFINE(PT_OFF_VECTOR, offsetof(struct pt_regs, pc) + 4);
#endif
/* signal defines */
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
index f56faa5c9cd..56043ade394 100644
--- a/arch/m68knommu/kernel/entry.S
+++ b/arch/m68knommu/kernel/entry.S
@@ -46,7 +46,7 @@
ENTRY(buserr)
SAVE_ALL
moveq #-1,%d0
- movel %d0,%sp@(PT_ORIG_D0)
+ movel %d0,%sp@(PT_OFF_ORIG_D0)
movel %sp,%sp@- /* stack frame pointer argument */
jsr buserr_c
addql #4,%sp
@@ -55,7 +55,7 @@ ENTRY(buserr)
ENTRY(trap)
SAVE_ALL
moveq #-1,%d0
- movel %d0,%sp@(PT_ORIG_D0)
+ movel %d0,%sp@(PT_OFF_ORIG_D0)
movel %sp,%sp@- /* stack frame pointer argument */
jsr trap_c
addql #4,%sp
@@ -67,7 +67,7 @@ ENTRY(trap)
ENTRY(dbginterrupt)
SAVE_ALL
moveq #-1,%d0
- movel %d0,%sp@(PT_ORIG_D0)
+ movel %d0,%sp@(PT_OFF_ORIG_D0)
movel %sp,%sp@- /* stack frame pointer argument */
jsr dbginterrupt_c
addql #4,%sp
diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
index b1703c67a4f..f3236d0b522 100644
--- a/arch/m68knommu/mm/init.c
+++ b/arch/m68knommu/mm/init.c
@@ -162,7 +162,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
totalram_pages++;
pages++;
}
- printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+ printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages * (PAGE_SIZE / 1024));
}
#endif
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c
index 0f41ba82a3b..942397984c6 100644
--- a/arch/m68knommu/platform/5206e/config.c
+++ b/arch/m68knommu/platform/5206e/config.c
@@ -17,7 +17,6 @@
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
#include <asm/mcfdma.h>
-#include <asm/mcfuart.h>
/***************************************************************************/
diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S
index b1aef72f3ba..9d80d2c4286 100644
--- a/arch/m68knommu/platform/68328/entry.S
+++ b/arch/m68knommu/platform/68328/entry.S
@@ -39,17 +39,17 @@
.globl inthandler7
badsys:
- movel #-ENOSYS,%sp@(PT_D0)
+ movel #-ENOSYS,%sp@(PT_OFF_D0)
jra ret_from_exception
do_trace:
- movel #-ENOSYS,%sp@(PT_D0) /* needed for strace*/
+ movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
subql #4,%sp
SAVE_SWITCH_STACK
jbsr syscall_trace
RESTORE_SWITCH_STACK
addql #4,%sp
- movel %sp@(PT_ORIG_D0),%d1
+ movel %sp@(PT_OFF_ORIG_D0),%d1
movel #-ENOSYS,%d0
cmpl #NR_syscalls,%d1
jcc 1f
@@ -57,7 +57,7 @@ do_trace:
lea sys_call_table, %a0
jbsr %a0@(%d1)
-1: movel %d0,%sp@(PT_D0) /* save the return value */
+1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
subql #4,%sp /* dummy return address */
SAVE_SWITCH_STACK
jbsr syscall_trace
@@ -75,7 +75,7 @@ ENTRY(system_call)
jbsr set_esp0
addql #4,%sp
- movel %sp@(PT_ORIG_D0),%d0
+ movel %sp@(PT_OFF_ORIG_D0),%d0
movel %sp,%d1 /* get thread_info pointer */
andl #-THREAD_SIZE,%d1
@@ -88,10 +88,10 @@ ENTRY(system_call)
lea sys_call_table,%a0
movel %a0@(%d0), %a0
jbsr %a0@
- movel %d0,%sp@(PT_D0) /* save the return value*/
+ movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
ret_from_exception:
- btst #5,%sp@(PT_SR) /* check if returning to kernel*/
+ btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
jeq Luser_return /* if so, skip resched, signals*/
Lkernel_return:
@@ -133,7 +133,7 @@ Lreturn:
*/
inthandler1:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -144,7 +144,7 @@ inthandler1:
inthandler2:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -155,7 +155,7 @@ inthandler2:
inthandler3:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -166,7 +166,7 @@ inthandler3:
inthandler4:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -177,7 +177,7 @@ inthandler4:
inthandler5:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -188,7 +188,7 @@ inthandler5:
inthandler6:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -199,7 +199,7 @@ inthandler6:
inthandler7:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -210,7 +210,7 @@ inthandler7:
inthandler:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and #0x3ff, %d0
movel %sp,%sp@-
@@ -224,7 +224,7 @@ ret_from_interrupt:
2:
RESTORE_ALL
1:
- moveb %sp@(PT_SR), %d0
+ moveb %sp@(PT_OFF_SR), %d0
and #7, %d0
jhi 2b
diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S
index 55dfefe3864..6d3460a39ca 100644
--- a/arch/m68knommu/platform/68360/entry.S
+++ b/arch/m68knommu/platform/68360/entry.S
@@ -35,17 +35,17 @@
.globl inthandler
badsys:
- movel #-ENOSYS,%sp@(PT_D0)
+ movel #-ENOSYS,%sp@(PT_OFF_D0)
jra ret_from_exception
do_trace:
- movel #-ENOSYS,%sp@(PT_D0) /* needed for strace*/
+ movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
subql #4,%sp
SAVE_SWITCH_STACK
jbsr syscall_trace
RESTORE_SWITCH_STACK
addql #4,%sp
- movel %sp@(PT_ORIG_D0),%d1
+ movel %sp@(PT_OFF_ORIG_D0),%d1
movel #-ENOSYS,%d0
cmpl #NR_syscalls,%d1
jcc 1f
@@ -53,7 +53,7 @@ do_trace:
lea sys_call_table, %a0
jbsr %a0@(%d1)
-1: movel %d0,%sp@(PT_D0) /* save the return value */
+1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
subql #4,%sp /* dummy return address */
SAVE_SWITCH_STACK
jbsr syscall_trace
@@ -79,10 +79,10 @@ ENTRY(system_call)
lea sys_call_table,%a0
movel %a0@(%d0), %a0
jbsr %a0@
- movel %d0,%sp@(PT_D0) /* save the return value*/
+ movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
ret_from_exception:
- btst #5,%sp@(PT_SR) /* check if returning to kernel*/
+ btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
jeq Luser_return /* if so, skip resched, signals*/
Lkernel_return:
@@ -124,7 +124,7 @@ Lreturn:
*/
inthandler:
SAVE_ALL
- movew %sp@(PT_VECTOR), %d0
+ movew %sp@(PT_OFF_VECTOR), %d0
and.l #0x3ff, %d0
lsr.l #0x02, %d0
@@ -139,7 +139,7 @@ ret_from_interrupt:
2:
RESTORE_ALL
1:
- moveb %sp@(PT_SR), %d0
+ moveb %sp@(PT_OFF_SR), %d0
and #7, %d0
jhi 2b
/* check if we need to do software interrupts */
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S
index 3b471c0da24..dd7d591f70e 100644
--- a/arch/m68knommu/platform/coldfire/entry.S
+++ b/arch/m68knommu/platform/coldfire/entry.S
@@ -81,11 +81,11 @@ ENTRY(system_call)
movel %d3,%a0
jbsr %a0@
- movel %d0,%sp@(PT_D0) /* save the return value */
+ movel %d0,%sp@(PT_OFF_D0) /* save the return value */
jra ret_from_exception
1:
- movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_D0 */
- movel %d2,PT_D0(%sp) /* on syscall entry */
+ movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_OFF_D0 */
+ movel %d2,PT_OFF_D0(%sp) /* on syscall entry */
subql #4,%sp
SAVE_SWITCH_STACK
jbsr syscall_trace
@@ -93,7 +93,7 @@ ENTRY(system_call)
addql #4,%sp
movel %d3,%a0
jbsr %a0@
- movel %d0,%sp@(PT_D0) /* save the return value */
+ movel %d0,%sp@(PT_OFF_D0) /* save the return value */
subql #4,%sp /* dummy return address */
SAVE_SWITCH_STACK
jbsr syscall_trace
@@ -104,7 +104,7 @@ ret_from_signal:
ret_from_exception:
move #0x2700,%sr /* disable intrs */
- btst #5,%sp@(PT_SR) /* check if returning to kernel */
+ btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */
jeq Luser_return /* if so, skip resched, signals */
#ifdef CONFIG_PREEMPT
@@ -142,8 +142,8 @@ Luser_return:
Lreturn:
move #0x2700,%sr /* disable intrs */
movel sw_usp,%a0 /* get usp */
- movel %sp@(PT_PC),%a0@- /* copy exception program counter */
- movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */
+ movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
+ movel %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception format/vector/sr */
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
movel %sp@+,%d0
@@ -181,9 +181,9 @@ Lsignal_return:
ENTRY(inthandler)
SAVE_ALL
moveq #-1,%d0
- movel %d0,%sp@(PT_ORIG_D0)
+ movel %d0,%sp@(PT_OFF_ORIG_D0)
- movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */
+ movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */
andl #0x03fc,%d0 /* mask out vector only */
movel %sp,%sp@- /* push regs arg */
@@ -203,7 +203,7 @@ ENTRY(inthandler)
ENTRY(fasthandler)
SAVE_LOCAL
- movew %sp@(PT_FORMATVEC),%d0
+ movew %sp@(PT_OFF_FORMATVEC),%d0
andl #0x03fc,%d0 /* mask out vector only */
movel %sp,%sp@- /* push regs arg */
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index acc1f05d1e2..e3ecb36dd55 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -592,6 +592,8 @@ C_ENTRY(full_exception_trap):
nop
mfs r7, rfsr; /* save FSR */
nop
+ mts rfsr, r0; /* Clear sticky fsr */
+ nop
la r12, r0, full_exception
set_vms;
rtbd r12, 0;
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 6b0288ebccd..2b86c03aa84 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -384,7 +384,7 @@ handle_other_ex: /* Handle Other exceptions here */
addk r8, r17, r0; /* Load exception address */
bralid r15, full_exception; /* Branch to the handler */
nop;
- mts r0, rfsr; /* Clear sticky fsr */
+ mts rfsr, r0; /* Clear sticky fsr */
nop
/*
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 4201c743cc9..c592d475b3d 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -235,7 +235,9 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
regs->pc = pc;
regs->r1 = usp;
regs->pt_mode = 0;
+#ifdef CONFIG_MMU
regs->msr |= MSR_UMS;
+#endif
}
#ifdef CONFIG_MMU
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h
index 8a3a4dd5576..167e10ff06d 100644
--- a/arch/mn10300/include/asm/uaccess.h
+++ b/arch/mn10300/include/asm/uaccess.h
@@ -129,42 +129,47 @@ extern int fixup_exception(struct pt_regs *regs);
struct __large_struct { unsigned long buf[100]; };
#define __m(x) (*(struct __large_struct *)(x))
-#define __get_user_nocheck(x, ptr, size) \
-({ \
- __typeof(*(ptr)) __gu_val; \
- unsigned long __gu_addr; \
- int __gu_err; \
- __gu_addr = (unsigned long) (ptr); \
- switch (size) { \
- case 1: __get_user_asm("bu"); break; \
- case 2: __get_user_asm("hu"); break; \
- case 4: __get_user_asm("" ); break; \
- default: __get_user_unknown(); break; \
- } \
- x = (__typeof__(*(ptr))) __gu_val; \
- __gu_err; \
+#define __get_user_nocheck(x, ptr, size) \
+({ \
+ unsigned long __gu_addr; \
+ int __gu_err; \
+ __gu_addr = (unsigned long) (ptr); \
+ switch (size) { \
+ case 1: { \
+ unsigned char __gu_val; \
+ __get_user_asm("bu"); \
+ (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \
+ break; \
+ } \
+ case 2: { \
+ unsigned short __gu_val; \
+ __get_user_asm("hu"); \
+ (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \
+ break; \
+ } \
+ case 4: { \
+ unsigned int __gu_val; \
+ __get_user_asm(""); \
+ (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \
+ break; \
+ } \
+ default: \
+ __get_user_unknown(); \
+ break; \
+ } \
+ __gu_err; \
})
-#define __get_user_check(x, ptr, size) \
-({ \
- __typeof__(*(ptr)) __gu_val; \
- unsigned long __gu_addr; \
- int __gu_err; \
- __gu_addr = (unsigned long) (ptr); \
- if (likely(__access_ok(__gu_addr,size))) { \
- switch (size) { \
- case 1: __get_user_asm("bu"); break; \
- case 2: __get_user_asm("hu"); break; \
- case 4: __get_user_asm("" ); break; \
- default: __get_user_unknown(); break; \
- } \
- } \
- else { \
- __gu_err = -EFAULT; \
- __gu_val = 0; \
- } \
- x = (__typeof__(*(ptr))) __gu_val; \
- __gu_err; \
+#define __get_user_check(x, ptr, size) \
+({ \
+ int _e; \
+ if (likely(__access_ok((unsigned long) (ptr), (size)))) \
+ _e = __get_user_nocheck((x), (ptr), (size)); \
+ else { \
+ _e = -EFAULT; \
+ (x) = (__typeof__(x))0; \
+ } \
+ _e; \
})
#define __get_user_asm(INSN) \
diff --git a/arch/mn10300/unit-asb2303/include/unit/clock.h b/arch/mn10300/unit-asb2303/include/unit/clock.h
index 8b450e920af..2a0bf79ab96 100644
--- a/arch/mn10300/unit-asb2303/include/unit/clock.h
+++ b/arch/mn10300/unit-asb2303/include/unit/clock.h
@@ -20,9 +20,9 @@ extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */
extern unsigned long mn10300_iobclk;
extern unsigned long mn10300_tsc_per_HZ;
-#define MN10300_IOCLK ((unsigned long)mn10300_ioclk)
+#define MN10300_IOCLK mn10300_ioclk
/* If this processors has a another clock, uncomment the below. */
-/* #define MN10300_IOBCLK ((unsigned long)mn10300_iobclk) */
+/* #define MN10300_IOBCLK mn10300_iobclk */
#else /* !CONFIG_MN10300_RTC */
@@ -35,7 +35,7 @@ extern unsigned long mn10300_tsc_per_HZ;
#define MN10300_TSCCLK MN10300_IOCLK
#ifdef CONFIG_MN10300_RTC
-#define MN10300_TSC_PER_HZ ((unsigned long)mn10300_tsc_per_HZ)
+#define MN10300_TSC_PER_HZ mn10300_tsc_per_HZ
#else /* !CONFIG_MN10300_RTC */
#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ)
#endif /* !CONFIG_MN10300_RTC */
diff --git a/arch/mn10300/unit-asb2305/include/unit/clock.h b/arch/mn10300/unit-asb2305/include/unit/clock.h
index 7d514841ffd..67be3f2eb18 100644
--- a/arch/mn10300/unit-asb2305/include/unit/clock.h
+++ b/arch/mn10300/unit-asb2305/include/unit/clock.h
@@ -20,9 +20,9 @@ extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */
extern unsigned long mn10300_iobclk;
extern unsigned long mn10300_tsc_per_HZ;
-#define MN10300_IOCLK ((unsigned long)mn10300_ioclk)
+#define MN10300_IOCLK mn10300_ioclk
/* If this processors has a another clock, uncomment the below. */
-/* #define MN10300_IOBCLK ((unsigned long)mn10300_iobclk) */
+/* #define MN10300_IOBCLK mn10300_iobclk */
#else /* !CONFIG_MN10300_RTC */
@@ -35,7 +35,7 @@ extern unsigned long mn10300_tsc_per_HZ;
#define MN10300_TSCCLK MN10300_IOCLK
#ifdef CONFIG_MN10300_RTC
-#define MN10300_TSC_PER_HZ ((unsigned long)mn10300_tsc_per_HZ)
+#define MN10300_TSC_PER_HZ mn10300_tsc_per_HZ
#else /* !CONFIG_MN10300_RTC */
#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ)
#endif /* !CONFIG_MN10300_RTC */
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index f388dc68f60..524d9352f17 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -18,6 +18,7 @@ config PARISC
select BUG
select HAVE_PERF_EVENTS
select GENERIC_ATOMIC64 if !64BIT
+ select HAVE_ARCH_TRACEHOOK
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
in many of their workstations & servers (HP9000 700 and 800 series,
diff --git a/arch/parisc/include/asm/fixmap.h b/arch/parisc/include/asm/fixmap.h
index de3fe3a1822..6fec4d4a1a1 100644
--- a/arch/parisc/include/asm/fixmap.h
+++ b/arch/parisc/include/asm/fixmap.h
@@ -21,9 +21,9 @@
#define KERNEL_MAP_END (TMPALIAS_MAP_START)
#ifndef __ASSEMBLY__
-extern void *vmalloc_start;
+extern void *parisc_vmalloc_start;
#define PCXL_DMA_MAP_SIZE (8*1024*1024)
-#define VMALLOC_START ((unsigned long)vmalloc_start)
+#define VMALLOC_START ((unsigned long)parisc_vmalloc_start)
#define VMALLOC_END (KERNEL_MAP_END)
#endif /*__ASSEMBLY__*/
diff --git a/arch/parisc/include/asm/hardirq.h b/arch/parisc/include/asm/hardirq.h
index ce93133d511..0d68184a76c 100644
--- a/arch/parisc/include/asm/hardirq.h
+++ b/arch/parisc/include/asm/hardirq.h
@@ -1,29 +1,11 @@
/* hardirq.h: PA-RISC hard IRQ support.
*
* Copyright (C) 2001 Matthew Wilcox <matthew@wil.cx>
- *
- * The locking is really quite interesting. There's a cpu-local
- * count of how many interrupts are being handled, and a global
- * lock. An interrupt can only be serviced if the global lock
- * is free. You can't be sure no more interrupts are being
- * serviced until you've acquired the lock and then checked
- * all the per-cpu interrupt counts are all zero. It's a specialised
- * br_lock, and that's exactly how Sparc does it. We don't because
- * it's more locking for us. This way is lock-free in the interrupt path.
*/
#ifndef _PARISC_HARDIRQ_H
#define _PARISC_HARDIRQ_H
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-typedef struct {
- unsigned long __softirq_pending; /* set_bit is used on this */
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
-void ack_bad_irq(unsigned int irq);
+#include <asm-generic/hardirq.h>
#endif /* _PARISC_HARDIRQ_H */
diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h
index 302f68dc889..aead40b16dd 100644
--- a/arch/parisc/include/asm/ptrace.h
+++ b/arch/parisc/include/asm/ptrace.h
@@ -59,8 +59,11 @@ void user_enable_block_step(struct task_struct *task);
#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0)
#define instruction_pointer(regs) ((regs)->iaoq[0] & ~3)
+#define user_stack_pointer(regs) ((regs)->gr[30])
unsigned long profile_pc(struct pt_regs *);
extern void show_regs(struct pt_regs *);
-#endif
+
+
+#endif /* __KERNEL__ */
#endif
diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h
new file mode 100644
index 00000000000..8bdfd2c8c39
--- /dev/null
+++ b/arch/parisc/include/asm/syscall.h
@@ -0,0 +1,40 @@
+/* syscall.h */
+
+#ifndef _ASM_PARISC_SYSCALL_H_
+#define _ASM_PARISC_SYSCALL_H_
+
+#include <linux/err.h>
+#include <asm/ptrace.h>
+
+static inline long syscall_get_nr(struct task_struct *tsk,
+ struct pt_regs *regs)
+{
+ return regs->gr[20];
+}
+
+static inline void syscall_get_arguments(struct task_struct *tsk,
+ struct pt_regs *regs, unsigned int i,
+ unsigned int n, unsigned long *args)
+{
+ BUG_ON(i);
+
+ switch (n) {
+ case 6:
+ args[5] = regs->gr[21];
+ case 5:
+ args[4] = regs->gr[22];
+ case 4:
+ args[3] = regs->gr[23];
+ case 3:
+ args[2] = regs->gr[24];
+ case 2:
+ args[1] = regs->gr[25];
+ case 1:
+ args[0] = regs->gr[26];
+ break;
+ default:
+ BUG();
+ }
+}
+
+#endif /*_ASM_PARISC_SYSCALL_H_*/
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index ac775a76bff..7ecc1039cfe 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -32,6 +32,11 @@ struct thread_info {
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
+/* how to get the thread information struct from C */
+#define current_thread_info() ((struct thread_info *)mfctl(30))
+
+#endif /* !__ASSEMBLY */
+
/* thread information allocation */
#define THREAD_SIZE_ORDER 2
@@ -40,11 +45,6 @@ struct thread_info {
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER)
-/* how to get the thread information struct from C */
-#define current_thread_info() ((struct thread_info *)mfctl(30))
-
-#endif /* !__ASSEMBLY */
-
#define PREEMPT_ACTIVE_BIT 28
#define PREEMPT_ACTIVE (1 << PREEMPT_ACTIVE_BIT)
@@ -60,6 +60,8 @@ struct thread_info {
#define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */
#define TIF_FREEZE 7 /* is freezing for suspend */
#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
+#define TIF_SINGLESTEP 9 /* single stepping? */
+#define TIF_BLOCKSTEP 10 /* branch stepping? */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -69,6 +71,8 @@ struct thread_info {
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
+#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
+#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
_TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 699cf8ef211..fcd3c707bf1 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -270,8 +270,8 @@ int main(void)
DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count));
DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop));
BLANK();
- DEFINE(PA_BLOCKSTEP_BIT, 31-PT_BLOCKSTEP_BIT);
- DEFINE(PA_SINGLESTEP_BIT, 31-PT_SINGLESTEP_BIT);
+ DEFINE(TIF_BLOCKSTEP_PA_BIT, 31-TIF_BLOCKSTEP);
+ DEFINE(TIF_SINGLESTEP_PA_BIT, 31-TIF_SINGLESTEP);
BLANK();
DEFINE(ASM_PMD_SHIFT, PMD_SHIFT);
DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT);
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 8c4712b74dc..3a44f7f704f 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -2047,12 +2047,13 @@ syscall_do_signal:
b,n syscall_check_sig
syscall_restore:
- /* Are we being ptraced? */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
- ldw TASK_PTRACE(%r1), %r19
- bb,< %r19,31,syscall_restore_rfi
- nop
+ /* Are we being ptraced? */
+ ldw TASK_FLAGS(%r1),%r19
+ ldi (_TIF_SINGLESTEP|_TIF_BLOCKSTEP),%r2
+ and,COND(=) %r19,%r2,%r0
+ b,n syscall_restore_rfi
ldo TASK_PT_FR31(%r1),%r19 /* reload fpregs */
rest_fp %r19
@@ -2113,16 +2114,16 @@ syscall_restore_rfi:
ldi 0x0b,%r20 /* Create new PSW */
depi -1,13,1,%r20 /* C, Q, D, and I bits */
- /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are
- * set in include/linux/ptrace.h and converted to PA bitmap
+ /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
+ * set in thread_info.h and converted to PA bitmap
* numbers in asm-offsets.c */
- /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */
- extru,= %r19,PA_SINGLESTEP_BIT,1,%r0
+ /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
+ extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
depi -1,27,1,%r20 /* R bit */
- /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */
- extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0
+ /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
+ extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
depi -1,7,1,%r20 /* T bit */
STREG %r20,TASK_PT_PSW(%r1)
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 330f536a932..2e7610cb33d 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -423,8 +423,3 @@ void __init init_IRQ(void)
set_eiem(cpu_eiem); /* EIEM : enable all external intr */
}
-
-void ack_bad_irq(unsigned int irq)
-{
- printk(KERN_WARNING "unexpected IRQ %d\n", irq);
-}
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 61ee0eec4e6..212074653df 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -893,7 +893,7 @@ int module_finalize(const Elf_Ehdr *hdr,
* ourselves */
for (i = 1; i < hdr->e_shnum; i++) {
if(sechdrs[i].sh_type == SHT_SYMTAB
- && (sechdrs[i].sh_type & SHF_ALLOC)) {
+ && (sechdrs[i].sh_flags & SHF_ALLOC)) {
int strindex = sechdrs[i].sh_link;
/* FIXME: AWFUL HACK
* The cast is to drop the const from
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 927db3668b6..c4f49e45129 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -13,6 +13,7 @@
#include <linux/smp.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
+#include <linux/tracehook.h>
#include <linux/user.h>
#include <linux/personality.h>
#include <linux/security.h>
@@ -35,7 +36,8 @@
*/
void ptrace_disable(struct task_struct *task)
{
- task->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
+ clear_tsk_thread_flag(task, TIF_SINGLESTEP);
+ clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
/* make sure the trap bits are not set */
pa_psw(task)->r = 0;
@@ -55,8 +57,8 @@ void user_disable_single_step(struct task_struct *task)
void user_enable_single_step(struct task_struct *task)
{
- task->ptrace &= ~PT_BLOCKSTEP;
- task->ptrace |= PT_SINGLESTEP;
+ clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
+ set_tsk_thread_flag(task, TIF_SINGLESTEP);
if (pa_psw(task)->n) {
struct siginfo si;
@@ -98,8 +100,8 @@ void user_enable_single_step(struct task_struct *task)
void user_enable_block_step(struct task_struct *task)
{
- task->ptrace &= ~PT_SINGLESTEP;
- task->ptrace |= PT_BLOCKSTEP;
+ clear_tsk_thread_flag(task, TIF_SINGLESTEP);
+ set_tsk_thread_flag(task, TIF_BLOCKSTEP);
/* Enable taken branch trap. */
pa_psw(task)->r = 0;
@@ -263,22 +265,20 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
}
#endif
+long do_syscall_trace_enter(struct pt_regs *regs)
+{
+ if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+ tracehook_report_syscall_entry(regs))
+ return -1L;
+
+ return regs->gr[20];
+}
-void syscall_trace(void)
+void do_syscall_trace_exit(struct pt_regs *regs)
{
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
- if (!(current->ptrace & PT_PTRACED))
- return;
- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
- ? 0x80 : 0));
- /*
- * this isn't the same as continuing with a signal, but it will do
- * for normal use. strace only continues with a signal if the
- * stopping signal is not SIGTRAP. -brl
- */
- if (current->exit_code) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
+ int stepping = test_thread_flag(TIF_SINGLESTEP) ||
+ test_thread_flag(TIF_BLOCKSTEP);
+
+ if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(regs, stepping);
}
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 8eb3c63c407..e8467e4aa8d 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/ptrace.h>
+#include <linux/tracehook.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/compat.h>
@@ -34,7 +35,6 @@
#include <asm/asm-offsets.h>
#ifdef CONFIG_COMPAT
-#include <linux/compat.h>
#include "signal32.h"
#endif
@@ -468,6 +468,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
sigaddset(&current->blocked,sig);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
+
+ tracehook_signal_handler(sig, info, ka, regs, 0);
+
return 1;
}
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 59fc1a43ec3..f5f96021caa 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -288,18 +288,23 @@ tracesys:
STREG %r18,PT_GR18(%r2)
/* Finished saving things for the debugger */
- ldil L%syscall_trace,%r1
+ copy %r2,%r26
+ ldil L%do_syscall_trace_enter,%r1
ldil L%tracesys_next,%r2
- be R%syscall_trace(%sr7,%r1)
+ be R%do_syscall_trace_enter(%sr7,%r1)
ldo R%tracesys_next(%r2),%r2
-tracesys_next:
+tracesys_next:
+ /* do_syscall_trace_enter either returned the syscallno, or -1L,
+ * so we skip restoring the PT_GR20 below, since we pulled it from
+ * task->thread.regs.gr[20] above.
+ */
+ copy %ret0,%r20
ldil L%sys_call_table,%r1
ldo R%sys_call_table(%r1), %r19
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
- LDREG TASK_PT_GR20(%r1), %r20
LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */
LDREG TASK_PT_GR25(%r1), %r25
LDREG TASK_PT_GR24(%r1), %r24
@@ -336,7 +341,8 @@ tracesys_exit:
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
- bl syscall_trace, %r2
+ ldo TASK_REGS(%r1),%r26
+ bl do_syscall_trace_exit,%r2
STREG %r28,TASK_PT_GR28(%r1) /* save return value now */
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
@@ -353,12 +359,12 @@ tracesys_exit:
tracesys_sigexit:
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
- LDREG 0(%r1), %r1
+ LDREG TI_TASK(%r1), %r1
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
- bl syscall_trace, %r2
- nop
+ bl do_syscall_trace_exit,%r2
+ ldo TASK_REGS(%r1),%r26
ldil L%syscall_exit_rfi,%r1
be,n R%syscall_exit_rfi(%sr7,%r1)
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 775be2791bc..fda4baa059b 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -28,6 +28,7 @@
#include <asm/cache.h>
#include <asm/page.h>
#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
/* ld script to make hppa Linux kernel */
#ifndef CONFIG_64BIT
@@ -134,6 +135,15 @@ SECTIONS
__init_begin = .;
INIT_TEXT_SECTION(16384)
INIT_DATA_SECTION(16)
+ /* we have to discard exit text and such at runtime, not link time */
+ .exit.text :
+ {
+ EXIT_TEXT
+ }
+ .exit.data :
+ {
+ EXIT_DATA
+ }
PERCPU(PAGE_SIZE)
. = ALIGN(PAGE_SIZE);
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index d5aca31fddb..13b6e3e59b9 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -434,8 +434,8 @@ void mark_rodata_ro(void)
#define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
& ~(VM_MAP_OFFSET-1)))
-void *vmalloc_start __read_mostly;
-EXPORT_SYMBOL(vmalloc_start);
+void *parisc_vmalloc_start __read_mostly;
+EXPORT_SYMBOL(parisc_vmalloc_start);
#ifdef CONFIG_PA11
unsigned long pcxl_dma_start __read_mostly;
@@ -496,13 +496,14 @@ void __init mem_init(void)
#ifdef CONFIG_PA11
if (hppa_dma_ops == &pcxl_dma_ops) {
pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START);
- vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start + PCXL_DMA_MAP_SIZE);
+ parisc_vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start
+ + PCXL_DMA_MAP_SIZE);
} else {
pcxl_dma_start = 0;
- vmalloc_start = SET_MAP_OFFSET(MAP_START);
+ parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
}
#else
- vmalloc_start = SET_MAP_OFFSET(MAP_START);
+ parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
#endif
printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c
index 47ee603f558..2aa371e3007 100644
--- a/arch/powerpc/kvm/timing.c
+++ b/arch/powerpc/kvm/timing.c
@@ -201,7 +201,7 @@ static int kvmppc_exit_timing_open(struct inode *inode, struct file *file)
return single_open(file, kvmppc_exit_timing_show, inode->i_private);
}
-static struct file_operations kvmppc_exit_timing_fops = {
+static const struct file_operations kvmppc_exit_timing_fops = {
.owner = THIS_MODULE,
.open = kvmppc_exit_timing_open,
.read = seq_read,
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 96130944617..884e8bcec49 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -147,7 +147,7 @@ static int __fops ## _open(struct inode *inode, struct file *file) \
__simple_attr_check_format(__fmt, 0ull); \
return spufs_attr_open(inode, file, __get, __set, __fmt); \
} \
-static struct file_operations __fops = { \
+static const struct file_operations __fops = { \
.owner = THIS_MODULE, \
.open = __fops ## _open, \
.release = spufs_attr_release, \
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index ab69925d579..937a544a236 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -209,7 +209,7 @@ static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len,
return n_read * sizeof(struct dtl_entry);
}
-static struct file_operations dtl_fops = {
+static const struct file_operations dtl_fops = {
.open = dtl_file_open,
.release = dtl_file_release,
.read = dtl_file_read,
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index ec5eee7c25d..06cce8285ba 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -58,7 +58,7 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
-static inline int kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu)
+static inline long kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu)
{
return vcpu->arch.sie_block->gmslm
- vcpu->arch.sie_block->gmsor
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c
index 0a37c8bfc95..99ffc5f1c0d 100644
--- a/arch/sh/boards/board-magicpanelr2.c
+++ b/arch/sh/boards/board-magicpanelr2.c
@@ -205,8 +205,6 @@ static void __init setup_port_multiplexing(void)
static void __init mpr2_setup(char **cmdline_p)
{
- __set_io_port_base(0xa0000000);
-
/* set Pin Select Register A:
* /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2,
* /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index ebe99227d4e..a4b7402d617 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -42,8 +42,6 @@ static void __init dreamcast_setup(char **cmdline_p)
/* Acknowledge any previous events */
/* XXX */
- __set_io_port_base(0xa0000000);
-
/* Assign all virtual IRQs to the System ASIC int. handler */
for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
set_irq_chip_and_handler(i, &systemasic_int,
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 5f9881e16e2..3b1ceb46fa5 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/usb/r8a66597.h>
#include <linux/i2c.h>
+#include <linux/i2c/tsc2007.h>
#include <linux/input.h>
#include <video/sh_mobile_lcdc.h>
#include <media/sh_mobile_ceu.h>
@@ -38,6 +39,20 @@
* 0x1800_0000 MFI 16bit
*/
+/* SWITCH
+ *------------------------------
+ * DS2[1] = FlashROM write protect ON : write protect
+ * OFF : No write protect
+ * DS2[2] = RMII / TS, SCIF ON : RMII
+ * OFF : TS, SCIF3
+ * DS2[3] = Camera / Video ON : Camera
+ * OFF : NTSC/PAL (IN)
+ * DS2[5] = NTSC_OUT Clock ON : On board OSC
+ * OFF : SH7724 DV_CLK
+ * DS2[6-7] = MMC / SD ON-OFF : SD
+ * OFF-ON : MMC
+ */
+
/* Heartbeat */
static unsigned char led_pos[] = { 0, 1, 2, 3 };
static struct heartbeat_data heartbeat_data = {
@@ -70,7 +85,7 @@ static struct mtd_partition nor_flash_partitions[] = {
.name = "boot loader",
.offset = 0,
.size = (5 * 1024 * 1024),
- .mask_flags = MTD_CAP_ROM,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "free-area",
.offset = MTDPART_OFS_APPEND,
@@ -376,6 +391,43 @@ static struct platform_device keysc_device = {
},
};
+/* TouchScreen */
+#define IRQ0 32
+static int ts_get_pendown_state(void)
+{
+ int val = 0;
+ gpio_free(GPIO_FN_INTC_IRQ0);
+ gpio_request(GPIO_PTZ0, NULL);
+ gpio_direction_input(GPIO_PTZ0);
+
+ val = gpio_get_value(GPIO_PTZ0);
+
+ gpio_free(GPIO_PTZ0);
+ gpio_request(GPIO_FN_INTC_IRQ0, NULL);
+
+ return val ? 0 : 1;
+}
+
+static int ts_init(void)
+{
+ gpio_request(GPIO_FN_INTC_IRQ0, NULL);
+ return 0;
+}
+
+struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+ .get_pendown_state = ts_get_pendown_state,
+ .init_platform_hw = ts_init,
+};
+
+static struct i2c_board_info ts_i2c_clients = {
+ I2C_BOARD_INFO("tsc2007", 0x48),
+ .type = "tsc2007",
+ .platform_data = &tsc2007_info,
+ .irq = IRQ0,
+};
+
static struct platform_device *ecovec_devices[] __initdata = {
&heartbeat_device,
&nor_flash_device,
@@ -460,6 +512,11 @@ static void __init sh_eth_init(void)
#define IODRIVEA 0xA405018A
static int __init arch_setup(void)
{
+ /* enable STATUS0, STATUS2 and PDSTATUS */
+ gpio_request(GPIO_FN_STATUS0, NULL);
+ gpio_request(GPIO_FN_STATUS2, NULL);
+ gpio_request(GPIO_FN_PDSTATUS, NULL);
+
/* enable SCIFA0 */
gpio_request(GPIO_FN_SCIF0_TXD, NULL);
gpio_request(GPIO_FN_SCIF0_RXD, NULL);
@@ -590,6 +647,10 @@ static int __init arch_setup(void)
*/
gpio_request(GPIO_PTF4, NULL);
gpio_direction_output(GPIO_PTF4, 1);
+
+ /* enable TouchScreen */
+ i2c_register_board_info(0, &ts_i2c_clients, 1);
+ set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW);
}
/* enable CEU0 */
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 0151933e525..bb407ef0b91 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -152,8 +152,6 @@ call_do_page_fault:
mov.l 1f, r0
mov.l @r0, r6
- sti
-
mov.l 3f, r0
mov.l 4f, r1
mov r15, r4
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 4ff50723928..b8fa6524760 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -147,6 +147,9 @@ void generic_outsl(unsigned long port, const void *src, unsigned long count)
void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
{
+ if (PXSEG(addr) >= P1SEG)
+ return (void __iomem *)addr;
+
return (void __iomem *)(addr + generic_io_base);
}
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 548f6607fd0..cbce639b108 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <asm/machvec.h>
#include <asm/sections.h>
+#include <asm/addrspace.h>
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -133,4 +134,6 @@ void __init sh_mv_setup(void)
if (!sh_mv.mv_nr_irqs)
sh_mv.mv_nr_irqs = NR_IRQS;
+
+ __set_io_port_base(P2SEG);
}
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 8dbe26b17c4..86c27042835 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -84,6 +84,7 @@ DECLARE_EXPORT(__movstrSI60);
DECLARE_EXPORT(__movstr_i4_even);
DECLARE_EXPORT(__movstr_i4_odd);
DECLARE_EXPORT(__movstrSI12_i4);
+DECLARE_EXPORT(__movmem);
DECLARE_EXPORT(__movmem_i4_even);
DECLARE_EXPORT(__movmem_i4_odd);
DECLARE_EXPORT(__movmemSI12_i4);
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 69bb1652ecc..e0b5e4b5acc 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -54,8 +54,8 @@ static unsigned long se_multi;
/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
valid! */
static int se_usermode = 3;
-/* 0: no warning 1: print a warning message */
-static int se_kernmode_warn = 1;
+/* 0: no warning 1: print a warning message, disabled by default */
+static int se_kernmode_warn;
#ifdef CONFIG_PROC_FS
static const char *se_usermode_action[] = {
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index b2453bbef4c..a98c7d8984f 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -43,7 +43,7 @@ static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
* Called from kernel/module.c:sys_init_module and routine for a.out format,
* signal handler code and kprobes code
*/
-static void sh4_flush_icache_range(void *args)
+static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
{
struct flusher_data *data = args;
unsigned long start, end;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 2cadee2037a..2601935eb58 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -78,7 +78,7 @@ static void sh7705_flush_icache_range(void *args)
/*
* Writeback&Invalidate the D-cache of the page
*/
-static void __flush_dcache_page(unsigned long phys)
+static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
{
unsigned long ways, waysize, addrstart;
unsigned long flags;
@@ -144,7 +144,7 @@ static void sh7705_flush_dcache_page(void *arg)
__flush_dcache_page(PHYSADDR(page_address(page)));
}
-static void sh7705_flush_cache_all(void *args)
+static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
{
unsigned long flags;
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index c3250614e3a..a86eaa9d75a 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -83,7 +83,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
*
* PMB entries are all pre-faulted.
*/
- if (unlikely(size >= 0x1000000)) {
+ if (unlikely(phys_addr >= P1SEG)) {
unsigned long mapped = pmb_remap(addr, phys_addr, size, flags);
if (likely(mapped)) {
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index b1a714a92b1..aade3110211 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -33,6 +33,8 @@
#define NR_PMB_ENTRIES 16
+static void __pmb_unmap(struct pmb_entry *);
+
static struct kmem_cache *pmb_cache;
static unsigned long pmb_map;
@@ -218,9 +220,10 @@ static struct {
long pmb_remap(unsigned long vaddr, unsigned long phys,
unsigned long size, unsigned long flags)
{
- struct pmb_entry *pmbp;
+ struct pmb_entry *pmbp, *pmbe;
unsigned long wanted;
int pmb_flags, i;
+ long err;
/* Convert typical pgprot value to the PMB equivalent */
if (flags & _PAGE_CACHABLE) {
@@ -236,20 +239,22 @@ long pmb_remap(unsigned long vaddr, unsigned long phys,
again:
for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
- struct pmb_entry *pmbe;
int ret;
if (size < pmb_sizes[i].size)
continue;
pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag);
- if (IS_ERR(pmbe))
- return PTR_ERR(pmbe);
+ if (IS_ERR(pmbe)) {
+ err = PTR_ERR(pmbe);
+ goto out;
+ }
ret = set_pmb_entry(pmbe);
if (ret != 0) {
pmb_free(pmbe);
- return -EBUSY;
+ err = -EBUSY;
+ goto out;
}
phys += pmb_sizes[i].size;
@@ -264,12 +269,25 @@ again:
pmbp->link = pmbe;
pmbp = pmbe;
+
+ /*
+ * Instead of trying smaller sizes on every iteration
+ * (even if we succeed in allocating space), try using
+ * pmb_sizes[i].size again.
+ */
+ i--;
}
if (size >= 0x1000000)
goto again;
return wanted - size;
+
+out:
+ if (pmbp)
+ __pmb_unmap(pmbp);
+
+ return err;
}
void pmb_unmap(unsigned long addr)
@@ -283,12 +301,19 @@ void pmb_unmap(unsigned long addr)
if (unlikely(!pmbe))
return;
+ __pmb_unmap(pmbe);
+}
+
+static void __pmb_unmap(struct pmb_entry *pmbe)
+{
WARN_ON(!test_bit(pmbe->entry, &pmb_map));
do {
struct pmb_entry *pmblink = pmbe;
- clear_pmb_entry(pmbe);
+ if (pmbe->entry != PMB_NO_ENTRY)
+ clear_pmb_entry(pmbe);
+
pmbe = pmblink->link;
pmb_free(pmblink);
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index ac45aab741a..05ef5380a68 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -26,6 +26,7 @@ config SPARC
select RTC_CLASS
select RTC_DRV_M48T59
select HAVE_PERF_EVENTS
+ select PERF_USE_VMALLOC
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
@@ -48,6 +49,7 @@ config SPARC64
select RTC_DRV_SUN4V
select RTC_DRV_STARFIRE
select HAVE_PERF_EVENTS
+ select PERF_USE_VMALLOC
config ARCH_DEFCONFIG
string
diff --git a/arch/sparc/include/asm/hardirq_32.h b/arch/sparc/include/asm/hardirq_32.h
index 4f63ed8df55..162007643cd 100644
--- a/arch/sparc/include/asm/hardirq_32.h
+++ b/arch/sparc/include/asm/hardirq_32.h
@@ -7,17 +7,7 @@
#ifndef __SPARC_HARDIRQ_H
#define __SPARC_HARDIRQ_H
-#include <linux/threads.h>
-#include <linux/spinlock.h>
-#include <linux/cache.h>
-
-/* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */
-typedef struct {
- unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
#define HARDIRQ_BITS 8
+#include <asm-generic/hardirq.h>
#endif /* __SPARC_HARDIRQ_H */
diff --git a/arch/sparc/include/asm/irq_32.h b/arch/sparc/include/asm/irq_32.h
index ea43057d476..cbf4801deaa 100644
--- a/arch/sparc/include/asm/irq_32.h
+++ b/arch/sparc/include/asm/irq_32.h
@@ -6,10 +6,10 @@
#ifndef _SPARC_IRQ_H
#define _SPARC_IRQ_H
-#include <linux/interrupt.h>
-
#define NR_IRQS 16
+#include <linux/interrupt.h>
+
#define irq_canonicalize(irq) (irq)
extern void __init init_IRQ(void);
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 0ff92fa2206..f3cb790fa2a 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -41,8 +41,8 @@
#define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL)
#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL)
#define VMALLOC_START _AC(0x0000000100000000,UL)
-#define VMALLOC_END _AC(0x0000000200000000,UL)
-#define VMEMMAP_BASE _AC(0x0000000200000000,UL)
+#define VMALLOC_END _AC(0x0000010000000000,UL)
+#define VMEMMAP_BASE _AC(0x0000010000000000,UL)
#define vmemmap ((struct page *)VMEMMAP_BASE)
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S
index 3ea6e8cde8c..1d361477d7d 100644
--- a/arch/sparc/kernel/ktlb.S
+++ b/arch/sparc/kernel/ktlb.S
@@ -280,8 +280,8 @@ kvmap_dtlb_nonlinear:
#ifdef CONFIG_SPARSEMEM_VMEMMAP
/* Do not use the TSB for vmemmap. */
- mov (VMEMMAP_BASE >> 24), %g5
- sllx %g5, 24, %g5
+ mov (VMEMMAP_BASE >> 40), %g5
+ sllx %g5, 40, %g5
cmp %g4,%g5
bgeu,pn %xcc, kvmap_vmemmap
nop
@@ -293,8 +293,8 @@ kvmap_dtlb_tsbmiss:
sethi %hi(MODULES_VADDR), %g5
cmp %g4, %g5
blu,pn %xcc, kvmap_dtlb_longpath
- mov (VMALLOC_END >> 24), %g5
- sllx %g5, 24, %g5
+ mov (VMALLOC_END >> 40), %g5
+ sllx %g5, 40, %g5
cmp %g4, %g5
bgeu,pn %xcc, kvmap_dtlb_longpath
nop
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 2d6a1b10c81..04db9274389 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -56,7 +56,8 @@ struct cpu_hw_events {
struct perf_event *events[MAX_HWEVENTS];
unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
- int enabled;
+ u64 pcr;
+ int enabled;
};
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
@@ -68,8 +69,30 @@ struct perf_event_map {
#define PIC_LOWER 0x02
};
+static unsigned long perf_event_encode(const struct perf_event_map *pmap)
+{
+ return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask;
+}
+
+static void perf_event_decode(unsigned long val, u16 *enc, u8 *msk)
+{
+ *msk = val & 0xff;
+ *enc = val >> 16;
+}
+
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+#define CACHE_OP_UNSUPPORTED 0xfffe
+#define CACHE_OP_NONSENSE 0xffff
+
+typedef struct perf_event_map cache_map_t
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+
struct sparc_pmu {
const struct perf_event_map *(*event_map)(int);
+ const cache_map_t *cache_map;
int max_events;
int upper_shift;
int lower_shift;
@@ -80,21 +103,109 @@ struct sparc_pmu {
int lower_nop;
};
-static const struct perf_event_map ultra3i_perfmon_event_map[] = {
+static const struct perf_event_map ultra3_perfmon_event_map[] = {
[PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER },
[PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER },
[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER },
[PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER },
};
-static const struct perf_event_map *ultra3i_event_map(int event_id)
+static const struct perf_event_map *ultra3_event_map(int event_id)
{
- return &ultra3i_perfmon_event_map[event_id];
+ return &ultra3_perfmon_event_map[event_id];
}
-static const struct sparc_pmu ultra3i_pmu = {
- .event_map = ultra3i_event_map,
- .max_events = ARRAY_SIZE(ultra3i_perfmon_event_map),
+static const cache_map_t ultra3_cache_map = {
+[C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, },
+ [C(RESULT_MISS)] = { 0x09, PIC_UPPER, },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x0a, PIC_LOWER },
+ [C(RESULT_MISS)] = { 0x0a, PIC_UPPER },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, },
+ [C(RESULT_MISS)] = { 0x09, PIC_UPPER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
+ [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER, },
+ [C(RESULT_MISS)] = { 0x0c, PIC_UPPER, },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER },
+ [C(RESULT_MISS)] = { 0x0c, PIC_UPPER },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x12, PIC_UPPER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x11, PIC_UPPER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+};
+
+static const struct sparc_pmu ultra3_pmu = {
+ .event_map = ultra3_event_map,
+ .cache_map = &ultra3_cache_map,
+ .max_events = ARRAY_SIZE(ultra3_perfmon_event_map),
.upper_shift = 11,
.lower_shift = 4,
.event_mask = 0x3f,
@@ -102,6 +213,121 @@ static const struct sparc_pmu ultra3i_pmu = {
.lower_nop = 0x14,
};
+/* Niagara1 is very limited. The upper PIC is hard-locked to count
+ * only instructions, so it is free running which creates all kinds of
+ * problems. Some hardware designs make one wonder if the creator
+ * even looked at how this stuff gets used by software.
+ */
+static const struct perf_event_map niagara1_perfmon_event_map[] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, PIC_UPPER },
+ [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, PIC_UPPER },
+ [PERF_COUNT_HW_CACHE_REFERENCES] = { 0, PIC_NONE },
+ [PERF_COUNT_HW_CACHE_MISSES] = { 0x03, PIC_LOWER },
+};
+
+static const struct perf_event_map *niagara1_event_map(int event_id)
+{
+ return &niagara1_perfmon_event_map[event_id];
+}
+
+static const cache_map_t niagara1_cache_map = {
+[C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x03, PIC_LOWER, },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x03, PIC_LOWER, },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x00, PIC_UPPER },
+ [C(RESULT_MISS)] = { 0x02, PIC_LOWER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
+ [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x07, PIC_LOWER, },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x07, PIC_LOWER, },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x05, PIC_LOWER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x04, PIC_LOWER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+};
+
+static const struct sparc_pmu niagara1_pmu = {
+ .event_map = niagara1_event_map,
+ .cache_map = &niagara1_cache_map,
+ .max_events = ARRAY_SIZE(niagara1_perfmon_event_map),
+ .upper_shift = 0,
+ .lower_shift = 4,
+ .event_mask = 0x7,
+ .upper_nop = 0x0,
+ .lower_nop = 0x0,
+};
+
static const struct perf_event_map niagara2_perfmon_event_map[] = {
[PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER },
[PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER },
@@ -116,8 +342,96 @@ static const struct perf_event_map *niagara2_event_map(int event_id)
return &niagara2_perfmon_event_map[event_id];
}
+static const cache_map_t niagara2_cache_map = {
+[C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, },
+ [C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, },
+ [C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x02ff, PIC_UPPER | PIC_LOWER, },
+ [C(RESULT_MISS)] = { 0x0301, PIC_UPPER | PIC_LOWER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
+ [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, },
+ [C(RESULT_MISS)] = { 0x0330, PIC_UPPER | PIC_LOWER, },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, },
+ [C(RESULT_MISS)] = { 0x0320, PIC_UPPER | PIC_LOWER, },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0x0b08, PIC_UPPER | PIC_LOWER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { 0xb04, PIC_UPPER | PIC_LOWER, },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+[C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
+ [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
+ [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
+ },
+},
+};
+
static const struct sparc_pmu niagara2_pmu = {
.event_map = niagara2_event_map,
+ .cache_map = &niagara2_cache_map,
.max_events = ARRAY_SIZE(niagara2_perfmon_event_map),
.upper_shift = 19,
.lower_shift = 6,
@@ -151,23 +465,30 @@ static u64 nop_for_index(int idx)
sparc_pmu->lower_nop, idx);
}
-static inline void sparc_pmu_enable_event(struct hw_perf_event *hwc,
- int idx)
+static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx)
{
u64 val, mask = mask_for_index(idx);
- val = pcr_ops->read();
- pcr_ops->write((val & ~mask) | hwc->config);
+ val = cpuc->pcr;
+ val &= ~mask;
+ val |= hwc->config;
+ cpuc->pcr = val;
+
+ pcr_ops->write(cpuc->pcr);
}
-static inline void sparc_pmu_disable_event(struct hw_perf_event *hwc,
- int idx)
+static inline void sparc_pmu_disable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx)
{
u64 mask = mask_for_index(idx);
u64 nop = nop_for_index(idx);
- u64 val = pcr_ops->read();
+ u64 val;
- pcr_ops->write((val & ~mask) | nop);
+ val = cpuc->pcr;
+ val &= ~mask;
+ val |= nop;
+ cpuc->pcr = val;
+
+ pcr_ops->write(cpuc->pcr);
}
void hw_perf_enable(void)
@@ -182,7 +503,7 @@ void hw_perf_enable(void)
cpuc->enabled = 1;
barrier();
- val = pcr_ops->read();
+ val = cpuc->pcr;
for (i = 0; i < MAX_HWEVENTS; i++) {
struct perf_event *cp = cpuc->events[i];
@@ -194,7 +515,9 @@ void hw_perf_enable(void)
val |= hwc->config_base;
}
- pcr_ops->write(val);
+ cpuc->pcr = val;
+
+ pcr_ops->write(cpuc->pcr);
}
void hw_perf_disable(void)
@@ -207,10 +530,12 @@ void hw_perf_disable(void)
cpuc->enabled = 0;
- val = pcr_ops->read();
+ val = cpuc->pcr;
val &= ~(PCR_UTRACE | PCR_STRACE |
sparc_pmu->hv_bit | sparc_pmu->irq_bit);
- pcr_ops->write(val);
+ cpuc->pcr = val;
+
+ pcr_ops->write(cpuc->pcr);
}
static u32 read_pmc(int idx)
@@ -242,7 +567,7 @@ static void write_pmc(int idx, u64 val)
}
static int sparc_perf_event_set_period(struct perf_event *event,
- struct hw_perf_event *hwc, int idx)
+ struct hw_perf_event *hwc, int idx)
{
s64 left = atomic64_read(&hwc->period_left);
s64 period = hwc->sample_period;
@@ -282,19 +607,19 @@ static int sparc_pmu_enable(struct perf_event *event)
if (test_and_set_bit(idx, cpuc->used_mask))
return -EAGAIN;
- sparc_pmu_disable_event(hwc, idx);
+ sparc_pmu_disable_event(cpuc, hwc, idx);
cpuc->events[idx] = event;
set_bit(idx, cpuc->active_mask);
sparc_perf_event_set_period(event, hwc, idx);
- sparc_pmu_enable_event(hwc, idx);
+ sparc_pmu_enable_event(cpuc, hwc, idx);
perf_event_update_userpage(event);
return 0;
}
static u64 sparc_perf_event_update(struct perf_event *event,
- struct hw_perf_event *hwc, int idx)
+ struct hw_perf_event *hwc, int idx)
{
int shift = 64 - 32;
u64 prev_raw_count, new_raw_count;
@@ -324,7 +649,7 @@ static void sparc_pmu_disable(struct perf_event *event)
int idx = hwc->idx;
clear_bit(idx, cpuc->active_mask);
- sparc_pmu_disable_event(hwc, idx);
+ sparc_pmu_disable_event(cpuc, hwc, idx);
barrier();
@@ -338,18 +663,29 @@ static void sparc_pmu_disable(struct perf_event *event)
static void sparc_pmu_read(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
+
sparc_perf_event_update(event, hwc, hwc->idx);
}
static void sparc_pmu_unthrottle(struct perf_event *event)
{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
- sparc_pmu_enable_event(hwc, hwc->idx);
+
+ sparc_pmu_enable_event(cpuc, hwc, hwc->idx);
}
static atomic_t active_events = ATOMIC_INIT(0);
static DEFINE_MUTEX(pmc_grab_mutex);
+static void perf_stop_nmi_watchdog(void *unused)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+ stop_nmi_watchdog(NULL);
+ cpuc->pcr = pcr_ops->read();
+}
+
void perf_event_grab_pmc(void)
{
if (atomic_inc_not_zero(&active_events))
@@ -358,7 +694,7 @@ void perf_event_grab_pmc(void)
mutex_lock(&pmc_grab_mutex);
if (atomic_read(&active_events) == 0) {
if (atomic_read(&nmi_active) > 0) {
- on_each_cpu(stop_nmi_watchdog, NULL, 1);
+ on_each_cpu(perf_stop_nmi_watchdog, NULL, 1);
BUG_ON(atomic_read(&nmi_active) != 0);
}
atomic_inc(&active_events);
@@ -375,30 +711,160 @@ void perf_event_release_pmc(void)
}
}
+static const struct perf_event_map *sparc_map_cache_event(u64 config)
+{
+ unsigned int cache_type, cache_op, cache_result;
+ const struct perf_event_map *pmap;
+
+ if (!sparc_pmu->cache_map)
+ return ERR_PTR(-ENOENT);
+
+ cache_type = (config >> 0) & 0xff;
+ if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+ return ERR_PTR(-EINVAL);
+
+ cache_op = (config >> 8) & 0xff;
+ if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+ return ERR_PTR(-EINVAL);
+
+ cache_result = (config >> 16) & 0xff;
+ if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+ return ERR_PTR(-EINVAL);
+
+ pmap = &((*sparc_pmu->cache_map)[cache_type][cache_op][cache_result]);
+
+ if (pmap->encoding == CACHE_OP_UNSUPPORTED)
+ return ERR_PTR(-ENOENT);
+
+ if (pmap->encoding == CACHE_OP_NONSENSE)
+ return ERR_PTR(-EINVAL);
+
+ return pmap;
+}
+
static void hw_perf_event_destroy(struct perf_event *event)
{
perf_event_release_pmc();
}
+/* Make sure all events can be scheduled into the hardware at
+ * the same time. This is simplified by the fact that we only
+ * need to support 2 simultaneous HW events.
+ */
+static int sparc_check_constraints(unsigned long *events, int n_ev)
+{
+ if (n_ev <= perf_max_events) {
+ u8 msk1, msk2;
+ u16 dummy;
+
+ if (n_ev == 1)
+ return 0;
+ BUG_ON(n_ev != 2);
+ perf_event_decode(events[0], &dummy, &msk1);
+ perf_event_decode(events[1], &dummy, &msk2);
+
+ /* If both events can go on any counter, OK. */
+ if (msk1 == (PIC_UPPER | PIC_LOWER) &&
+ msk2 == (PIC_UPPER | PIC_LOWER))
+ return 0;
+
+ /* If one event is limited to a specific counter,
+ * and the other can go on both, OK.
+ */
+ if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) &&
+ msk2 == (PIC_UPPER | PIC_LOWER))
+ return 0;
+ if ((msk2 == PIC_UPPER || msk2 == PIC_LOWER) &&
+ msk1 == (PIC_UPPER | PIC_LOWER))
+ return 0;
+
+ /* If the events are fixed to different counters, OK. */
+ if ((msk1 == PIC_UPPER && msk2 == PIC_LOWER) ||
+ (msk1 == PIC_LOWER && msk2 == PIC_UPPER))
+ return 0;
+
+ /* Otherwise, there is a conflict. */
+ }
+
+ return -1;
+}
+
+static int check_excludes(struct perf_event **evts, int n_prev, int n_new)
+{
+ int eu = 0, ek = 0, eh = 0;
+ struct perf_event *event;
+ int i, n, first;
+
+ n = n_prev + n_new;
+ if (n <= 1)
+ return 0;
+
+ first = 1;
+ for (i = 0; i < n; i++) {
+ event = evts[i];
+ if (first) {
+ eu = event->attr.exclude_user;
+ ek = event->attr.exclude_kernel;
+ eh = event->attr.exclude_hv;
+ first = 0;
+ } else if (event->attr.exclude_user != eu ||
+ event->attr.exclude_kernel != ek ||
+ event->attr.exclude_hv != eh) {
+ return -EAGAIN;
+ }
+ }
+
+ return 0;
+}
+
+static int collect_events(struct perf_event *group, int max_count,
+ struct perf_event *evts[], unsigned long *events)
+{
+ struct perf_event *event;
+ int n = 0;
+
+ if (!is_software_event(group)) {
+ if (n >= max_count)
+ return -1;
+ evts[n] = group;
+ events[n++] = group->hw.event_base;
+ }
+ list_for_each_entry(event, &group->sibling_list, group_entry) {
+ if (!is_software_event(event) &&
+ event->state != PERF_EVENT_STATE_OFF) {
+ if (n >= max_count)
+ return -1;
+ evts[n] = event;
+ events[n++] = event->hw.event_base;
+ }
+ }
+ return n;
+}
+
static int __hw_perf_event_init(struct perf_event *event)
{
struct perf_event_attr *attr = &event->attr;
+ struct perf_event *evts[MAX_HWEVENTS];
struct hw_perf_event *hwc = &event->hw;
+ unsigned long events[MAX_HWEVENTS];
const struct perf_event_map *pmap;
u64 enc;
+ int n;
if (atomic_read(&nmi_active) < 0)
return -ENODEV;
- if (attr->type != PERF_TYPE_HARDWARE)
+ if (attr->type == PERF_TYPE_HARDWARE) {
+ if (attr->config >= sparc_pmu->max_events)
+ return -EINVAL;
+ pmap = sparc_pmu->event_map(attr->config);
+ } else if (attr->type == PERF_TYPE_HW_CACHE) {
+ pmap = sparc_map_cache_event(attr->config);
+ if (IS_ERR(pmap))
+ return PTR_ERR(pmap);
+ } else
return -EOPNOTSUPP;
- if (attr->config >= sparc_pmu->max_events)
- return -EINVAL;
-
- perf_event_grab_pmc();
- event->destroy = hw_perf_event_destroy;
-
/* We save the enable bits in the config_base. So to
* turn off sampling just write 'config', and to enable
* things write 'config | config_base'.
@@ -411,15 +877,39 @@ static int __hw_perf_event_init(struct perf_event *event)
if (!attr->exclude_hv)
hwc->config_base |= sparc_pmu->hv_bit;
+ hwc->event_base = perf_event_encode(pmap);
+
+ enc = pmap->encoding;
+
+ n = 0;
+ if (event->group_leader != event) {
+ n = collect_events(event->group_leader,
+ perf_max_events - 1,
+ evts, events);
+ if (n < 0)
+ return -EINVAL;
+ }
+ events[n] = hwc->event_base;
+ evts[n] = event;
+
+ if (check_excludes(evts, n, 1))
+ return -EINVAL;
+
+ if (sparc_check_constraints(events, n + 1))
+ return -EINVAL;
+
+ /* Try to do all error checking before this point, as unwinding
+ * state after grabbing the PMC is difficult.
+ */
+ perf_event_grab_pmc();
+ event->destroy = hw_perf_event_destroy;
+
if (!hwc->sample_period) {
hwc->sample_period = MAX_PERIOD;
hwc->last_period = hwc->sample_period;
atomic64_set(&hwc->period_left, hwc->sample_period);
}
- pmap = sparc_pmu->event_map(attr->config);
-
- enc = pmap->encoding;
if (pmap->pic_mask & PIC_UPPER) {
hwc->idx = PIC_UPPER_INDEX;
enc <<= sparc_pmu->upper_shift;
@@ -472,7 +962,7 @@ void perf_event_print_debug(void)
}
static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
- unsigned long cmd, void *__args)
+ unsigned long cmd, void *__args)
{
struct die_args *args = __args;
struct perf_sample_data data;
@@ -513,7 +1003,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
continue;
if (perf_event_overflow(event, 1, &data, regs))
- sparc_pmu_disable_event(hwc, idx);
+ sparc_pmu_disable_event(cpuc, hwc, idx);
}
return NOTIFY_STOP;
@@ -525,8 +1015,15 @@ static __read_mostly struct notifier_block perf_event_nmi_notifier = {
static bool __init supported_pmu(void)
{
- if (!strcmp(sparc_pmu_type, "ultra3i")) {
- sparc_pmu = &ultra3i_pmu;
+ if (!strcmp(sparc_pmu_type, "ultra3") ||
+ !strcmp(sparc_pmu_type, "ultra3+") ||
+ !strcmp(sparc_pmu_type, "ultra3i") ||
+ !strcmp(sparc_pmu_type, "ultra4+")) {
+ sparc_pmu = &ultra3_pmu;
+ return true;
+ }
+ if (!strcmp(sparc_pmu_type, "niagara")) {
+ sparc_pmu = &niagara1_pmu;
return true;
}
if (!strcmp(sparc_pmu_type, "niagara2")) {
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c
index f97cb8b6ee5..f9024bccff1 100644
--- a/arch/sparc/oprofile/init.c
+++ b/arch/sparc/oprofile/init.c
@@ -11,6 +11,7 @@
#include <linux/oprofile.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/param.h> /* for HZ */
#ifdef CONFIG_SPARC64
#include <linux/notifier.h>
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8da93745c08..c876bace8fd 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -86,10 +86,6 @@ config STACKTRACE_SUPPORT
config HAVE_LATENCYTOP_SUPPORT
def_bool y
-config FAST_CMPXCHG_LOCAL
- bool
- default y
-
config MMU
def_bool y
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 527519b8a9f..f2824fb8c79 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -400,7 +400,7 @@ config X86_TSC
config X86_CMPXCHG64
def_bool y
- depends on X86_PAE || X86_64
+ depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM
# this should be set for all -march=.. options where the compiler
# generates cmov.
@@ -412,6 +412,7 @@ config X86_MINIMUM_CPU_FAMILY
int
default "64" if X86_64
default "6" if X86_32 && X86_P6_NOP
+ default "5" if X86_32 && X86_CMPXCHG64
default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
default "3"
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 74619c4f9fd..1733f9f65e8 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -21,8 +21,8 @@
#define __AUDIT_ARCH_LE 0x40000000
#ifndef CONFIG_AUDITSYSCALL
-#define sysexit_audit int_ret_from_sys_call
-#define sysretl_audit int_ret_from_sys_call
+#define sysexit_audit ia32_ret_from_sys_call
+#define sysretl_audit ia32_ret_from_sys_call
#endif
#define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8)
@@ -39,12 +39,12 @@
.endm
/* clobbers %eax */
- .macro CLEAR_RREGS _r9=rax
+ .macro CLEAR_RREGS offset=0, _r9=rax
xorl %eax,%eax
- movq %rax,R11(%rsp)
- movq %rax,R10(%rsp)
- movq %\_r9,R9(%rsp)
- movq %rax,R8(%rsp)
+ movq %rax,\offset+R11(%rsp)
+ movq %rax,\offset+R10(%rsp)
+ movq %\_r9,\offset+R9(%rsp)
+ movq %rax,\offset+R8(%rsp)
.endm
/*
@@ -172,6 +172,10 @@ sysexit_from_sys_call:
movl RIP-R11(%rsp),%edx /* User %eip */
CFI_REGISTER rip,rdx
RESTORE_ARGS 1,24,1,1,1,1
+ xorq %r8,%r8
+ xorq %r9,%r9
+ xorq %r10,%r10
+ xorq %r11,%r11
popfq
CFI_ADJUST_CFA_OFFSET -8
/*CFI_RESTORE rflags*/
@@ -202,7 +206,7 @@ sysexit_from_sys_call:
.macro auditsys_exit exit,ebpsave=RBP
testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10)
- jnz int_ret_from_sys_call
+ jnz ia32_ret_from_sys_call
TRACE_IRQS_ON
sti
movl %eax,%esi /* second arg, syscall return value */
@@ -218,8 +222,9 @@ sysexit_from_sys_call:
cli
TRACE_IRQS_OFF
testl %edi,TI_flags(%r10)
- jnz int_with_check
- jmp \exit
+ jz \exit
+ CLEAR_RREGS -ARGOFFSET
+ jmp int_with_check
.endm
sysenter_auditsys:
@@ -329,6 +334,9 @@ sysretl_from_sys_call:
CFI_REGISTER rip,rcx
movl EFLAGS-ARGOFFSET(%rsp),%r11d
/*CFI_REGISTER rflags,r11*/
+ xorq %r10,%r10
+ xorq %r9,%r9
+ xorq %r8,%r8
TRACE_IRQS_ON
movl RSP-ARGOFFSET(%rsp),%esp
CFI_RESTORE rsp
@@ -353,7 +361,7 @@ cstar_tracesys:
#endif
xchgl %r9d,%ebp
SAVE_REST
- CLEAR_RREGS r9
+ CLEAR_RREGS 0, r9
movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
movq %rsp,%rdi /* &pt_regs -> arg1 */
call syscall_trace_enter
@@ -425,6 +433,8 @@ ia32_do_call:
call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
ia32_sysret:
movq %rax,RAX-ARGOFFSET(%rsp)
+ia32_ret_from_sys_call:
+ CLEAR_RREGS -ARGOFFSET
jmp int_ret_from_sys_call
ia32_tracesys:
@@ -442,8 +452,8 @@ END(ia32_syscall)
ia32_badsys:
movq $0,ORIG_RAX-ARGOFFSET(%rsp)
- movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
- jmp int_ret_from_sys_call
+ movq $-ENOSYS,%rax
+ jmp ia32_sysret
quiet_ni_syscall:
movq $-ENOSYS,%rax
diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h
index 7c5ef8b14d9..46fc474fd81 100644
--- a/arch/x86/include/asm/checksum_32.h
+++ b/arch/x86/include/asm/checksum_32.h
@@ -161,7 +161,8 @@ static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
"adcl $0, %0 ;\n"
: "=&r" (sum)
: "r" (saddr), "r" (daddr),
- "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
+ "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
+ : "memory");
return csum_fold(sum);
}
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index 82ceb788a98..ee1931be659 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -312,19 +312,23 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
-#define cmpxchg64(ptr, o, n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 4)) \
- __ret = (__typeof__(*(ptr)))__cmpxchg64((ptr), \
- (unsigned long long)(o), \
- (unsigned long long)(n)); \
- else \
- __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr), \
- (unsigned long long)(o), \
- (unsigned long long)(n)); \
- __ret; \
-})
+#define cmpxchg64(ptr, o, n) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ __typeof__(*(ptr)) __old = (o); \
+ __typeof__(*(ptr)) __new = (n); \
+ alternative_io("call cmpxchg8b_emu", \
+ "lock; cmpxchg8b (%%esi)" , \
+ X86_FEATURE_CX8, \
+ "=A" (__ret), \
+ "S" ((ptr)), "0" (__old), \
+ "b" ((unsigned int)__new), \
+ "c" ((unsigned int)(__new>>32)) \
+ : "memory"); \
+ __ret; })
+
+
+
#define cmpxchg64_local(ptr, o, n) \
({ \
__typeof__(*(ptr)) __ret; \
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 3be000435fa..d83892226f7 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -796,6 +796,7 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
#define KVM_ARCH_WANT_MMU_NOTIFIER
int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
int kvm_age_hva(struct kvm *kvm, unsigned long hva);
+void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
int cpuid_maxphyaddr(struct kvm_vcpu *vcpu);
int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu);
int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index b608a64c581..f1363b72364 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -133,6 +133,8 @@ static inline void winchip_mcheck_init(struct cpuinfo_x86 *c) {}
static inline void enable_p5_mce(void) {}
#endif
+extern void (*x86_mce_decode_callback)(struct mce *m);
+
void mce_setup(struct mce *m);
void mce_log(struct mce *m);
DECLARE_PER_CPU(struct sys_device, mce_dev);
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 183c3457d2f..b1598a9436d 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -85,6 +85,18 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
static DEFINE_PER_CPU(struct mce, mces_seen);
static int cpu_missing;
+static void default_decode_mce(struct mce *m)
+{
+ pr_emerg("No human readable MCE decoding support on this CPU type.\n");
+ pr_emerg("Run the message through 'mcelog --ascii' to decode.\n");
+}
+
+/*
+ * CPU/chipset specific EDAC code can register a callback here to print
+ * MCE errors in a human-readable form:
+ */
+void (*x86_mce_decode_callback)(struct mce *m) = default_decode_mce;
+EXPORT_SYMBOL(x86_mce_decode_callback);
/* MCA banks polled by the period polling timer for corrected events */
DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
@@ -165,46 +177,46 @@ void mce_log(struct mce *mce)
set_bit(0, &mce_need_notify);
}
-void __weak decode_mce(struct mce *m)
-{
- return;
-}
-
static void print_mce(struct mce *m)
{
- printk(KERN_EMERG
- "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
+ pr_emerg("CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
m->extcpu, m->mcgstatus, m->bank, m->status);
+
if (m->ip) {
- printk(KERN_EMERG "RIP%s %02x:<%016Lx> ",
- !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
- m->cs, m->ip);
+ pr_emerg("RIP%s %02x:<%016Lx> ",
+ !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
+ m->cs, m->ip);
+
if (m->cs == __KERNEL_CS)
print_symbol("{%s}", m->ip);
- printk(KERN_CONT "\n");
+ pr_cont("\n");
}
- printk(KERN_EMERG "TSC %llx ", m->tsc);
+
+ pr_emerg("TSC %llx ", m->tsc);
if (m->addr)
- printk(KERN_CONT "ADDR %llx ", m->addr);
+ pr_cont("ADDR %llx ", m->addr);
if (m->misc)
- printk(KERN_CONT "MISC %llx ", m->misc);
- printk(KERN_CONT "\n");
- printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
- m->cpuvendor, m->cpuid, m->time, m->socketid,
- m->apicid);
+ pr_cont("MISC %llx ", m->misc);
+
+ pr_cont("\n");
+ pr_emerg("PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
+ m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid);
- decode_mce(m);
+ /*
+ * Print out human-readable details about the MCE error,
+ * (if the CPU has an implementation for that):
+ */
+ x86_mce_decode_callback(m);
}
static void print_mce_head(void)
{
- printk(KERN_EMERG "\nHARDWARE ERROR\n");
+ pr_emerg("\nHARDWARE ERROR\n");
}
static void print_mce_tail(void)
{
- printk(KERN_EMERG "This is not a software problem!\n"
- "Run through mcelog --ascii to decode and contact your hardware vendor\n");
+ pr_emerg("This is not a software problem!\n");
}
#define PANIC_TIMEOUT 5 /* 5 seconds */
@@ -218,6 +230,7 @@ static atomic_t mce_fake_paniced;
static void wait_for_panic(void)
{
long timeout = PANIC_TIMEOUT*USEC_PER_SEC;
+
preempt_disable();
local_irq_enable();
while (timeout-- > 0)
@@ -285,6 +298,7 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
static int msr_to_offset(u32 msr)
{
unsigned bank = __get_cpu_var(injectm.bank);
+
if (msr == rip_msr)
return offsetof(struct mce, ip);
if (msr == MSR_IA32_MCx_STATUS(bank))
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
index f04e7252760..3c1b12d461d 100644
--- a/arch/x86/kernel/cpu/mtrr/if.c
+++ b/arch/x86/kernel/cpu/mtrr/if.c
@@ -96,17 +96,24 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
unsigned long long base, size;
char *ptr;
char line[LINE_SIZE];
+ int length;
size_t linelen;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (!len)
- return -EINVAL;
memset(line, 0, LINE_SIZE);
- if (len > LINE_SIZE)
- len = LINE_SIZE;
- if (copy_from_user(line, buf, len - 1))
+
+ length = len;
+ length--;
+
+ if (length > LINE_SIZE - 1)
+ length = LINE_SIZE - 1;
+
+ if (length < 0)
+ return -EINVAL;
+
+ if (copy_from_user(line, buf, length))
return -EFAULT;
linelen = strlen(line);
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index 41fd965c80c..b9c830c12b4 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -206,8 +206,11 @@ static int __init setup_early_printk(char *buf)
while (*buf != '\0') {
if (!strncmp(buf, "serial", 6)) {
- early_serial_init(buf + 6);
+ buf += 6;
+ early_serial_init(buf);
early_console_register(&early_serial_console, keep);
+ if (!strncmp(buf, ",ttyS", 5))
+ buf += 5;
}
if (!strncmp(buf, "ttyS", 4)) {
early_serial_init(buf + 4);
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
index 43cec6bdda6..9c3bd4a2050 100644
--- a/arch/x86/kernel/i386_ksyms_32.c
+++ b/arch/x86/kernel/i386_ksyms_32.c
@@ -10,6 +10,16 @@
EXPORT_SYMBOL(mcount);
#endif
+/*
+ * Note, this is a prototype to get at the symbol for
+ * the export, but dont use it from C code, it is used
+ * by assembly code and is not using C calling convention!
+ */
+#ifndef CONFIG_X86_CMPXCHG64
+extern void cmpxchg8b_emu(void);
+EXPORT_SYMBOL(cmpxchg8b_emu);
+#endif
+
/* Networking helper routines. */
EXPORT_SYMBOL(csum_partial_copy_generic);
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 74656d1d4e3..39120619951 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -244,6 +244,7 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
__func__, smp_processor_id(), vector, irq);
}
+ run_local_timers();
irq_exit();
set_irq_regs(old_regs);
@@ -268,6 +269,7 @@ void smp_generic_interrupt(struct pt_regs *regs)
if (generic_interrupt_extension)
generic_interrupt_extension();
+ run_local_timers();
irq_exit();
set_irq_regs(old_regs);
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 64b838eac18..d20009b4e6e 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -35,7 +35,7 @@ int iommu_detected __read_mostly = 0;
/*
* This variable becomes 1 if iommu=pt is passed on the kernel command line.
- * If this variable is 1, IOMMU implementations do no DMA ranslation for
+ * If this variable is 1, IOMMU implementations do no DMA translation for
* devices and allow every device to access to whole physical memory. This is
* useful if a user want to use an IOMMU only for KVM device assignment to
* guests and not for driver dma translation.
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index ec1de97600e..d915d956e66 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -198,6 +198,7 @@ void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
inc_irq_stat(irq_resched_count);
+ run_local_timers();
/*
* KVM uses this interrupt to force a cpu out of guest mode
*/
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 1ae5ceba7eb..7024224f0fc 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -664,7 +664,7 @@ static void start_apic_timer(struct kvm_lapic *apic)
{
ktime_t now = apic->lapic_timer.timer.base->get_time();
- apic->lapic_timer.period = apic_get_reg(apic, APIC_TMICT) *
+ apic->lapic_timer.period = (u64)apic_get_reg(apic, APIC_TMICT) *
APIC_BUS_CYCLE_NS * apic->divide_count;
atomic_set(&apic->lapic_timer.pending, 0);
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index eca41ae9f45..685a4ffac8e 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -156,6 +156,8 @@ module_param(oos_shadow, bool, 0644);
#define CREATE_TRACE_POINTS
#include "mmutrace.h"
+#define SPTE_HOST_WRITEABLE (1ULL << PT_FIRST_AVAIL_BITS_SHIFT)
+
#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
struct kvm_rmap_desc {
@@ -634,9 +636,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
if (*spte & shadow_accessed_mask)
kvm_set_pfn_accessed(pfn);
if (is_writeble_pte(*spte))
- kvm_release_pfn_dirty(pfn);
- else
- kvm_release_pfn_clean(pfn);
+ kvm_set_pfn_dirty(pfn);
rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], sp->role.level);
if (!*rmapp) {
printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
@@ -748,7 +748,7 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
return write_protected;
}
-static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
+static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
{
u64 *spte;
int need_tlb_flush = 0;
@@ -763,8 +763,45 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
return need_tlb_flush;
}
-static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
- int (*handler)(struct kvm *kvm, unsigned long *rmapp))
+static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
+{
+ int need_flush = 0;
+ u64 *spte, new_spte;
+ pte_t *ptep = (pte_t *)data;
+ pfn_t new_pfn;
+
+ WARN_ON(pte_huge(*ptep));
+ new_pfn = pte_pfn(*ptep);
+ spte = rmap_next(kvm, rmapp, NULL);
+ while (spte) {
+ BUG_ON(!is_shadow_present_pte(*spte));
+ rmap_printk("kvm_set_pte_rmapp: spte %p %llx\n", spte, *spte);
+ need_flush = 1;
+ if (pte_write(*ptep)) {
+ rmap_remove(kvm, spte);
+ __set_spte(spte, shadow_trap_nonpresent_pte);
+ spte = rmap_next(kvm, rmapp, NULL);
+ } else {
+ new_spte = *spte &~ (PT64_BASE_ADDR_MASK);
+ new_spte |= (u64)new_pfn << PAGE_SHIFT;
+
+ new_spte &= ~PT_WRITABLE_MASK;
+ new_spte &= ~SPTE_HOST_WRITEABLE;
+ if (is_writeble_pte(*spte))
+ kvm_set_pfn_dirty(spte_to_pfn(*spte));
+ __set_spte(spte, new_spte);
+ spte = rmap_next(kvm, rmapp, spte);
+ }
+ }
+ if (need_flush)
+ kvm_flush_remote_tlbs(kvm);
+
+ return 0;
+}
+
+static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, u64 data,
+ int (*handler)(struct kvm *kvm, unsigned long *rmapp,
+ u64 data))
{
int i, j;
int retval = 0;
@@ -786,13 +823,15 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
if (hva >= start && hva < end) {
gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
- retval |= handler(kvm, &memslot->rmap[gfn_offset]);
+ retval |= handler(kvm, &memslot->rmap[gfn_offset],
+ data);
for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) {
int idx = gfn_offset;
idx /= KVM_PAGES_PER_HPAGE(PT_DIRECTORY_LEVEL + j);
retval |= handler(kvm,
- &memslot->lpage_info[j][idx].rmap_pde);
+ &memslot->lpage_info[j][idx].rmap_pde,
+ data);
}
}
}
@@ -802,10 +841,15 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
{
- return kvm_handle_hva(kvm, hva, kvm_unmap_rmapp);
+ return kvm_handle_hva(kvm, hva, 0, kvm_unmap_rmapp);
}
-static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp)
+void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
+{
+ kvm_handle_hva(kvm, hva, (u64)&pte, kvm_set_pte_rmapp);
+}
+
+static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
{
u64 *spte;
int young = 0;
@@ -841,13 +885,13 @@ static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
gfn = unalias_gfn(vcpu->kvm, gfn);
rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
- kvm_unmap_rmapp(vcpu->kvm, rmapp);
+ kvm_unmap_rmapp(vcpu->kvm, rmapp, 0);
kvm_flush_remote_tlbs(vcpu->kvm);
}
int kvm_age_hva(struct kvm *kvm, unsigned long hva)
{
- return kvm_handle_hva(kvm, hva, kvm_age_rmapp);
+ return kvm_handle_hva(kvm, hva, 0, kvm_age_rmapp);
}
#ifdef MMU_DEBUG
@@ -1756,7 +1800,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
unsigned pte_access, int user_fault,
int write_fault, int dirty, int level,
gfn_t gfn, pfn_t pfn, bool speculative,
- bool can_unsync)
+ bool can_unsync, bool reset_host_protection)
{
u64 spte;
int ret = 0;
@@ -1783,6 +1827,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn,
kvm_is_mmio_pfn(pfn));
+ if (reset_host_protection)
+ spte |= SPTE_HOST_WRITEABLE;
+
spte |= (u64)pfn << PAGE_SHIFT;
if ((pte_access & ACC_WRITE_MASK)
@@ -1828,7 +1875,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
unsigned pt_access, unsigned pte_access,
int user_fault, int write_fault, int dirty,
int *ptwrite, int level, gfn_t gfn,
- pfn_t pfn, bool speculative)
+ pfn_t pfn, bool speculative,
+ bool reset_host_protection)
{
int was_rmapped = 0;
int was_writeble = is_writeble_pte(*sptep);
@@ -1860,7 +1908,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
}
if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault,
- dirty, level, gfn, pfn, speculative, true)) {
+ dirty, level, gfn, pfn, speculative, true,
+ reset_host_protection)) {
if (write_fault)
*ptwrite = 1;
kvm_x86_ops->tlb_flush(vcpu);
@@ -1877,8 +1926,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
page_header_update_slot(vcpu->kvm, sptep, gfn);
if (!was_rmapped) {
rmap_count = rmap_add(vcpu, sptep, gfn);
- if (!is_rmap_spte(*sptep))
- kvm_release_pfn_clean(pfn);
+ kvm_release_pfn_clean(pfn);
if (rmap_count > RMAP_RECYCLE_THRESHOLD)
rmap_recycle(vcpu, sptep, gfn);
} else {
@@ -1909,7 +1957,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
if (iterator.level == level) {
mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
0, write, 1, &pt_write,
- level, gfn, pfn, false);
+ level, gfn, pfn, false, true);
++vcpu->stat.pf_fixed;
break;
}
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index d2fec9c12d2..72558f8ff3f 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -273,9 +273,13 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
if (mmu_notifier_retry(vcpu, vcpu->arch.update_pte.mmu_seq))
return;
kvm_get_pfn(pfn);
+ /*
+ * we call mmu_set_spte() with reset_host_protection = true beacuse that
+ * vcpu->arch.update_pte.pfn was fetched from get_user_pages(write = 1).
+ */
mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0,
gpte & PT_DIRTY_MASK, NULL, PT_PAGE_TABLE_LEVEL,
- gpte_to_gfn(gpte), pfn, true);
+ gpte_to_gfn(gpte), pfn, true, true);
}
/*
@@ -308,7 +312,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
user_fault, write_fault,
gw->ptes[gw->level-1] & PT_DIRTY_MASK,
ptwrite, level,
- gw->gfn, pfn, false);
+ gw->gfn, pfn, false, true);
break;
}
@@ -558,6 +562,7 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
{
int i, offset, nr_present;
+ bool reset_host_protection;
offset = nr_present = 0;
@@ -595,9 +600,16 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
nr_present++;
pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
+ if (!(sp->spt[i] & SPTE_HOST_WRITEABLE)) {
+ pte_access &= ~ACC_WRITE_MASK;
+ reset_host_protection = 0;
+ } else {
+ reset_host_protection = 1;
+ }
set_spte(vcpu, &sp->spt[i], pte_access, 0, 0,
is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn,
- spte_to_pfn(sp->spt[i]), true, false);
+ spte_to_pfn(sp->spt[i]), true, false,
+ reset_host_protection);
}
return !nr_present;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 944cc9c04b3..c17404add91 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -767,6 +767,8 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
rdtscll(tsc_this);
delta = vcpu->arch.host_tsc - tsc_this;
svm->vmcb->control.tsc_offset += delta;
+ if (is_nested(svm))
+ svm->nested.hsave->control.tsc_offset += delta;
vcpu->cpu = cpu;
kvm_migrate_timers(vcpu);
svm->asid_generation = 0;
@@ -2057,10 +2059,14 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
switch (ecx) {
case MSR_IA32_TSC: {
- u64 tsc;
+ u64 tsc_offset;
+
+ if (is_nested(svm))
+ tsc_offset = svm->nested.hsave->control.tsc_offset;
+ else
+ tsc_offset = svm->vmcb->control.tsc_offset;
- rdtscll(tsc);
- *data = svm->vmcb->control.tsc_offset + tsc;
+ *data = tsc_offset + native_read_tsc();
break;
}
case MSR_K6_STAR:
@@ -2146,10 +2152,17 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
switch (ecx) {
case MSR_IA32_TSC: {
- u64 tsc;
+ u64 tsc_offset = data - native_read_tsc();
+ u64 g_tsc_offset = 0;
+
+ if (is_nested(svm)) {
+ g_tsc_offset = svm->vmcb->control.tsc_offset -
+ svm->nested.hsave->control.tsc_offset;
+ svm->nested.hsave->control.tsc_offset = tsc_offset;
+ }
+
+ svm->vmcb->control.tsc_offset = tsc_offset + g_tsc_offset;
- rdtscll(tsc);
- svm->vmcb->control.tsc_offset = data - tsc;
break;
}
case MSR_K6_STAR:
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f3812014bd0..ed53b42caba 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -709,7 +709,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (vcpu->cpu != cpu) {
vcpu_clear(vmx);
kvm_migrate_timers(vcpu);
- vpid_sync_vcpu_all(vmx);
+ set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests);
local_irq_disable();
list_add(&vmx->local_vcpus_link,
&per_cpu(vcpus_on_cpu, cpu));
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index be451ee4424..9b9695322f5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1591,6 +1591,8 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
if (cpuid->nent < 1)
goto out;
+ if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
+ cpuid->nent = KVM_MAX_CPUID_ENTRIES;
r = -ENOMEM;
cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent);
if (!cpuid_entries)
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 9e609206fac..85f5db95c60 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -16,7 +16,9 @@ ifeq ($(CONFIG_X86_32),y)
lib-y += checksum_32.o
lib-y += strstr_32.o
lib-y += semaphore_32.o string_32.o
-
+ifneq ($(CONFIG_X86_CMPXCHG64),y)
+ lib-y += cmpxchg8b_emu.o
+endif
lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
else
obj-y += io_64.o iomap_copy_64.o
diff --git a/arch/x86/lib/cmpxchg8b_emu.S b/arch/x86/lib/cmpxchg8b_emu.S
new file mode 100644
index 00000000000..828cb710dec
--- /dev/null
+++ b/arch/x86/lib/cmpxchg8b_emu.S
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/alternative-asm.h>
+#include <asm/frame.h>
+#include <asm/dwarf2.h>
+
+
+.text
+
+/*
+ * Inputs:
+ * %esi : memory location to compare
+ * %eax : low 32 bits of old value
+ * %edx : high 32 bits of old value
+ * %ebx : low 32 bits of new value
+ * %ecx : high 32 bits of new value
+ */
+ENTRY(cmpxchg8b_emu)
+CFI_STARTPROC
+
+#
+# Emulate 'cmpxchg8b (%esi)' on UP except we don't
+# set the whole ZF thing (caller will just compare
+# eax:edx with the expected value)
+#
+cmpxchg8b_emu:
+ pushfl
+ cli
+
+ cmpl (%esi), %eax
+ jne not_same
+ cmpl 4(%esi), %edx
+ jne half_same
+
+ movl %ebx, (%esi)
+ movl %ecx, 4(%esi)
+
+ popfl
+ ret
+
+ not_same:
+ movl (%esi), %eax
+ half_same:
+ movl 4(%esi), %edx
+
+ popfl
+ ret
+
+CFI_ENDPROC
+ENDPROC(cmpxchg8b_emu)
diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c
index b53225d2cac..e133ce25e29 100644
--- a/arch/x86/xen/debugfs.c
+++ b/arch/x86/xen/debugfs.c
@@ -100,7 +100,7 @@ static int xen_array_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations u32_array_fops = {
+static const struct file_operations u32_array_fops = {
.owner = THIS_MODULE,
.open = u32_array_open,
.release= xen_array_release,
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 6593ab39cfe..8873b9b439f 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -350,6 +350,7 @@ static void blkdev_discard_end_io(struct bio *bio, int err)
if (bio->bi_private)
complete(bio->bi_private);
+ __free_page(bio_page(bio));
bio_put(bio);
}
@@ -372,30 +373,50 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
struct request_queue *q = bdev_get_queue(bdev);
int type = flags & DISCARD_FL_BARRIER ?
DISCARD_BARRIER : DISCARD_NOBARRIER;
+ struct bio *bio;
+ struct page *page;
int ret = 0;
if (!q)
return -ENXIO;
- if (!q->prepare_discard_fn)
+ if (!blk_queue_discard(q))
return -EOPNOTSUPP;
while (nr_sects && !ret) {
- struct bio *bio = bio_alloc(gfp_mask, 0);
- if (!bio)
- return -ENOMEM;
+ unsigned int sector_size = q->limits.logical_block_size;
+ unsigned int max_discard_sectors =
+ min(q->limits.max_discard_sectors, UINT_MAX >> 9);
+ bio = bio_alloc(gfp_mask, 1);
+ if (!bio)
+ goto out;
+ bio->bi_sector = sector;
bio->bi_end_io = blkdev_discard_end_io;
bio->bi_bdev = bdev;
if (flags & DISCARD_FL_WAIT)
bio->bi_private = &wait;
- bio->bi_sector = sector;
+ /*
+ * Add a zeroed one-sector payload as that's what
+ * our current implementations need. If we'll ever need
+ * more the interface will need revisiting.
+ */
+ page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ if (!page)
+ goto out_free_bio;
+ if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size)
+ goto out_free_page;
- if (nr_sects > queue_max_hw_sectors(q)) {
- bio->bi_size = queue_max_hw_sectors(q) << 9;
- nr_sects -= queue_max_hw_sectors(q);
- sector += queue_max_hw_sectors(q);
+ /*
+ * And override the bio size - the way discard works we
+ * touch many more blocks on disk than the actual payload
+ * length.
+ */
+ if (nr_sects > max_discard_sectors) {
+ bio->bi_size = max_discard_sectors << 9;
+ nr_sects -= max_discard_sectors;
+ sector += max_discard_sectors;
} else {
bio->bi_size = nr_sects << 9;
nr_sects = 0;
@@ -414,5 +435,11 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
bio_put(bio);
}
return ret;
+out_free_page:
+ __free_page(page);
+out_free_bio:
+ bio_put(bio);
+out:
+ return -ENOMEM;
}
EXPORT_SYMBOL(blkdev_issue_discard);
diff --git a/block/blk-core.c b/block/blk-core.c
index 8135228e4b2..81f34311659 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -34,6 +34,7 @@
#include "blk.h"
EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap);
+EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
static int __make_request(struct request_queue *q, struct bio *bio);
@@ -69,7 +70,7 @@ static void drive_stat_acct(struct request *rq, int new_io)
part_stat_inc(cpu, part, merges[rw]);
else {
part_round_stats(cpu, part);
- part_inc_in_flight(part, rw);
+ part_inc_in_flight(part);
}
part_stat_unlock();
@@ -1031,7 +1032,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
if (part->in_flight) {
__part_stat_add(cpu, part, time_in_queue,
- part_in_flight(part) * (now - part->stamp));
+ part->in_flight * (now - part->stamp));
__part_stat_add(cpu, part, io_ticks, (now - part->stamp));
}
part->stamp = now;
@@ -1124,7 +1125,6 @@ void init_request_from_bio(struct request *req, struct bio *bio)
req->cmd_flags |= REQ_DISCARD;
if (bio_rw_flagged(bio, BIO_RW_BARRIER))
req->cmd_flags |= REQ_SOFTBARRIER;
- req->q->prepare_discard_fn(req->q, req);
} else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER)))
req->cmd_flags |= REQ_HARDBARRIER;
@@ -1437,7 +1437,8 @@ static inline void __generic_make_request(struct bio *bio)
goto end_io;
}
- if (unlikely(nr_sectors > queue_max_hw_sectors(q))) {
+ if (unlikely(!bio_rw_flagged(bio, BIO_RW_DISCARD) &&
+ nr_sectors > queue_max_hw_sectors(q))) {
printk(KERN_ERR "bio too big device %s (%u > %u)\n",
bdevname(bio->bi_bdev, b),
bio_sectors(bio),
@@ -1470,7 +1471,7 @@ static inline void __generic_make_request(struct bio *bio)
goto end_io;
if (bio_rw_flagged(bio, BIO_RW_DISCARD) &&
- !q->prepare_discard_fn) {
+ !blk_queue_discard(q)) {
err = -EOPNOTSUPP;
goto end_io;
}
@@ -1738,7 +1739,7 @@ static void blk_account_io_done(struct request *req)
part_stat_inc(cpu, part, ios[rw]);
part_stat_add(cpu, part, ticks[rw], duration);
part_round_stats(cpu, part);
- part_dec_in_flight(part, rw);
+ part_dec_in_flight(part);
part_stat_unlock();
}
@@ -2491,6 +2492,14 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work)
}
EXPORT_SYMBOL(kblockd_schedule_work);
+int kblockd_schedule_delayed_work(struct request_queue *q,
+ struct delayed_work *work,
+ unsigned long delay)
+{
+ return queue_delayed_work(kblockd_workqueue, work, delay);
+}
+EXPORT_SYMBOL(kblockd_schedule_delayed_work);
+
int __init blk_dev_init(void)
{
BUILD_BUG_ON(__REQ_NR_BITS > 8 *
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 99cb5cf1f44..b0de8574fdc 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -351,7 +351,7 @@ static void blk_account_io_merge(struct request *req)
part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
part_round_stats(cpu, part);
- part_dec_in_flight(part, rq_data_dir(req));
+ part_dec_in_flight(part);
part_stat_unlock();
}
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 83413ff8373..e0695bca702 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -34,23 +34,6 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn)
EXPORT_SYMBOL(blk_queue_prep_rq);
/**
- * blk_queue_set_discard - set a discard_sectors function for queue
- * @q: queue
- * @dfn: prepare_discard function
- *
- * It's possible for a queue to register a discard callback which is used
- * to transform a discard request into the appropriate type for the
- * hardware. If none is registered, then discard requests are failed
- * with %EOPNOTSUPP.
- *
- */
-void blk_queue_set_discard(struct request_queue *q, prepare_discard_fn *dfn)
-{
- q->prepare_discard_fn = dfn;
-}
-EXPORT_SYMBOL(blk_queue_set_discard);
-
-/**
* blk_queue_merge_bvec - set a merge_bvec function for queue
* @q: queue
* @mbfn: merge_bvec_fn
@@ -111,7 +94,9 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->max_hw_segments = MAX_HW_SEGMENTS;
lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
lim->max_segment_size = MAX_SEGMENT_SIZE;
- lim->max_sectors = lim->max_hw_sectors = SAFE_MAX_SECTORS;
+ lim->max_sectors = BLK_DEF_MAX_SECTORS;
+ lim->max_hw_sectors = INT_MAX;
+ lim->max_discard_sectors = SAFE_MAX_SECTORS;
lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
lim->alignment_offset = 0;
@@ -164,6 +149,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
q->unplug_timer.data = (unsigned long)q;
blk_set_default_limits(&q->limits);
+ blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
/*
* If the caller didn't supply a lock, fall back to our embedded
@@ -254,6 +240,18 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors)
EXPORT_SYMBOL(blk_queue_max_hw_sectors);
/**
+ * blk_queue_max_discard_sectors - set max sectors for a single discard
+ * @q: the request queue for the device
+ * @max_discard: maximum number of sectors to discard
+ **/
+void blk_queue_max_discard_sectors(struct request_queue *q,
+ unsigned int max_discard_sectors)
+{
+ q->limits.max_discard_sectors = max_discard_sectors;
+}
+EXPORT_SYMBOL(blk_queue_max_discard_sectors);
+
+/**
* blk_queue_max_phys_segments - set max phys segments for a request for this queue
* @q: the request queue for the device
* @max_segments: max number of segments
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index b78c9c3e267..8a6d81afb28 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -452,6 +452,7 @@ int blk_register_queue(struct gendisk *disk)
if (ret) {
kobject_uevent(&q->kobj, KOBJ_REMOVE);
kobject_del(&q->kobj);
+ blk_trace_remove_sysfs(disk_to_dev(disk));
return ret;
}
@@ -465,11 +466,11 @@ void blk_unregister_queue(struct gendisk *disk)
if (WARN_ON(!q))
return;
- if (q->request_fn) {
+ if (q->request_fn)
elv_unregister_queue(q);
- kobject_uevent(&q->kobj, KOBJ_REMOVE);
- kobject_del(&q->kobj);
- kobject_put(&disk_to_dev(disk)->kobj);
- }
+ kobject_uevent(&q->kobj, KOBJ_REMOVE);
+ kobject_del(&q->kobj);
+ blk_trace_remove_sysfs(disk_to_dev(disk));
+ kobject_put(&disk_to_dev(disk)->kobj);
}
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 1ca813b16e7..9c4b679908f 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -150,7 +150,7 @@ struct cfq_data {
* idle window management
*/
struct timer_list idle_slice_timer;
- struct work_struct unplug_work;
+ struct delayed_work unplug_work;
struct cfq_queue *active_queue;
struct cfq_io_context *active_cic;
@@ -173,6 +173,7 @@ struct cfq_data {
unsigned int cfq_slice[2];
unsigned int cfq_slice_async_rq;
unsigned int cfq_slice_idle;
+ unsigned int cfq_latency;
struct list_head cic_list;
@@ -180,6 +181,8 @@ struct cfq_data {
* Fallback dummy cfqq for extreme OOM conditions
*/
struct cfq_queue oom_cfqq;
+
+ unsigned long last_end_sync_rq;
};
enum cfqq_state_flags {
@@ -265,11 +268,13 @@ static inline int cfq_bio_sync(struct bio *bio)
* scheduler run of queue, if there are requests pending and no one in the
* driver that will restart queueing
*/
-static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
+static inline void cfq_schedule_dispatch(struct cfq_data *cfqd,
+ unsigned long delay)
{
if (cfqd->busy_queues) {
cfq_log(cfqd, "schedule dispatch");
- kblockd_schedule_work(cfqd->queue, &cfqd->unplug_work);
+ kblockd_schedule_delayed_work(cfqd->queue, &cfqd->unplug_work,
+ delay);
}
}
@@ -1326,12 +1331,30 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
return 0;
/*
- * we are the only queue, allow up to 4 times of 'quantum'
+ * Sole queue user, allow bigger slice
*/
- if (cfqq->dispatched >= 4 * max_dispatch)
- return 0;
+ max_dispatch *= 4;
+ }
+
+ /*
+ * Async queues must wait a bit before being allowed dispatch.
+ * We also ramp up the dispatch depth gradually for async IO,
+ * based on the last sync IO we serviced
+ */
+ if (!cfq_cfqq_sync(cfqq) && cfqd->cfq_latency) {
+ unsigned long last_sync = jiffies - cfqd->last_end_sync_rq;
+ unsigned int depth;
+
+ depth = last_sync / cfqd->cfq_slice[1];
+ if (!depth && !cfqq->dispatched)
+ depth = 1;
+ if (depth < max_dispatch)
+ max_dispatch = depth;
}
+ if (cfqq->dispatched >= max_dispatch)
+ return 0;
+
/*
* Dispatch a request from this cfqq
*/
@@ -1376,7 +1399,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
if (unlikely(cfqd->active_queue == cfqq)) {
__cfq_slice_expired(cfqd, cfqq, 0);
- cfq_schedule_dispatch(cfqd);
+ cfq_schedule_dispatch(cfqd, 0);
}
kmem_cache_free(cfq_pool, cfqq);
@@ -1471,7 +1494,7 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
if (unlikely(cfqq == cfqd->active_queue)) {
__cfq_slice_expired(cfqd, cfqq, 0);
- cfq_schedule_dispatch(cfqd);
+ cfq_schedule_dispatch(cfqd, 0);
}
cfq_put_queue(cfqq);
@@ -1951,7 +1974,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
enable_idle = old_idle = cfq_cfqq_idle_window(cfqq);
if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
- (cfqd->hw_tag && CIC_SEEKY(cic)))
+ (!cfqd->cfq_latency && cfqd->hw_tag && CIC_SEEKY(cic)))
enable_idle = 0;
else if (sample_valid(cic->ttime_samples)) {
if (cic->ttime_mean > cfqd->cfq_slice_idle)
@@ -2157,8 +2180,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
if (cfq_cfqq_sync(cfqq))
cfqd->sync_flight--;
- if (sync)
+ if (sync) {
RQ_CIC(rq)->last_end_request = now;
+ cfqd->last_end_sync_rq = now;
+ }
/*
* If this is the active queue, check if it needs to be expired,
@@ -2186,7 +2211,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
}
if (!rq_in_driver(cfqd))
- cfq_schedule_dispatch(cfqd);
+ cfq_schedule_dispatch(cfqd, 0);
}
/*
@@ -2316,7 +2341,7 @@ queue_fail:
if (cic)
put_io_context(cic->ioc);
- cfq_schedule_dispatch(cfqd);
+ cfq_schedule_dispatch(cfqd, 0);
spin_unlock_irqrestore(q->queue_lock, flags);
cfq_log(cfqd, "set_request fail");
return 1;
@@ -2325,7 +2350,7 @@ queue_fail:
static void cfq_kick_queue(struct work_struct *work)
{
struct cfq_data *cfqd =
- container_of(work, struct cfq_data, unplug_work);
+ container_of(work, struct cfq_data, unplug_work.work);
struct request_queue *q = cfqd->queue;
spin_lock_irq(q->queue_lock);
@@ -2379,7 +2404,7 @@ static void cfq_idle_slice_timer(unsigned long data)
expire:
cfq_slice_expired(cfqd, timed_out);
out_kick:
- cfq_schedule_dispatch(cfqd);
+ cfq_schedule_dispatch(cfqd, 0);
out_cont:
spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
}
@@ -2387,7 +2412,7 @@ out_cont:
static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
{
del_timer_sync(&cfqd->idle_slice_timer);
- cancel_work_sync(&cfqd->unplug_work);
+ cancel_delayed_work_sync(&cfqd->unplug_work);
}
static void cfq_put_async_queues(struct cfq_data *cfqd)
@@ -2469,7 +2494,7 @@ static void *cfq_init_queue(struct request_queue *q)
cfqd->idle_slice_timer.function = cfq_idle_slice_timer;
cfqd->idle_slice_timer.data = (unsigned long) cfqd;
- INIT_WORK(&cfqd->unplug_work, cfq_kick_queue);
+ INIT_DELAYED_WORK(&cfqd->unplug_work, cfq_kick_queue);
cfqd->cfq_quantum = cfq_quantum;
cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
@@ -2480,8 +2505,9 @@ static void *cfq_init_queue(struct request_queue *q)
cfqd->cfq_slice[1] = cfq_slice_sync;
cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
cfqd->cfq_slice_idle = cfq_slice_idle;
+ cfqd->cfq_latency = 1;
cfqd->hw_tag = 1;
-
+ cfqd->last_end_sync_rq = jiffies;
return cfqd;
}
@@ -2549,6 +2575,7 @@ SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1);
SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
+SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0);
#undef SHOW_FUNCTION
#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
@@ -2580,6 +2607,7 @@ STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1);
STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
UINT_MAX, 0);
+STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0);
#undef STORE_FUNCTION
#define CFQ_ATTR(name) \
@@ -2595,6 +2623,7 @@ static struct elv_fs_entry cfq_attrs[] = {
CFQ_ATTR(slice_async),
CFQ_ATTR(slice_async_rq),
CFQ_ATTR(slice_idle),
+ CFQ_ATTR(low_latency),
__ATTR_NULL
};
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 7865a34e0fa..9bd086c1a4d 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -21,6 +21,11 @@ static int compat_put_int(unsigned long arg, int val)
return put_user(val, (compat_int_t __user *)compat_ptr(arg));
}
+static int compat_put_uint(unsigned long arg, unsigned int val)
+{
+ return put_user(val, (compat_uint_t __user *)compat_ptr(arg));
+}
+
static int compat_put_long(unsigned long arg, long val)
{
return put_user(val, (compat_long_t __user *)compat_ptr(arg));
@@ -734,6 +739,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
switch (cmd) {
case HDIO_GETGEO:
return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
+ case BLKPBSZGET:
+ return compat_put_uint(arg, bdev_physical_block_size(bdev));
+ case BLKIOMIN:
+ return compat_put_uint(arg, bdev_io_min(bdev));
+ case BLKIOOPT:
+ return compat_put_uint(arg, bdev_io_opt(bdev));
+ case BLKALIGNOFF:
+ return compat_put_int(arg, bdev_alignment_offset(bdev));
case BLKFLSBUF:
case BLKROSET:
case BLKDISCARD:
diff --git a/block/genhd.c b/block/genhd.c
index 517e4332cb3..5a0861da324 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -869,7 +869,6 @@ static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
-static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
#ifdef CONFIG_FAIL_MAKE_REQUEST
static struct device_attribute dev_attr_fail =
__ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
@@ -889,7 +888,6 @@ static struct attribute *disk_attrs[] = {
&dev_attr_alignment_offset.attr,
&dev_attr_capability.attr,
&dev_attr_stat.attr,
- &dev_attr_inflight.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
&dev_attr_fail.attr,
#endif
@@ -1055,7 +1053,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
part_stat_read(hd, merges[1]),
(unsigned long long)part_stat_read(hd, sectors[1]),
jiffies_to_msecs(part_stat_read(hd, ticks[1])),
- part_in_flight(hd),
+ hd->in_flight,
jiffies_to_msecs(part_stat_read(hd, io_ticks)),
jiffies_to_msecs(part_stat_read(hd, time_in_queue))
);
diff --git a/block/ioctl.c b/block/ioctl.c
index d3e6b5827a3..1f4d1de12b0 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -138,6 +138,11 @@ static int put_int(unsigned long arg, int val)
return put_user(val, (int __user *)arg);
}
+static int put_uint(unsigned long arg, unsigned int val)
+{
+ return put_user(val, (unsigned int __user *)arg);
+}
+
static int put_long(unsigned long arg, long val)
{
return put_user(val, (long __user *)arg);
@@ -263,10 +268,18 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
case BLKROGET:
return put_int(arg, bdev_read_only(bdev) != 0);
- case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
+ case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */
return put_int(arg, block_size(bdev));
- case BLKSSZGET: /* get block device hardware sector size */
+ case BLKSSZGET: /* get block device logical block size */
return put_int(arg, bdev_logical_block_size(bdev));
+ case BLKPBSZGET: /* get block device physical block size */
+ return put_uint(arg, bdev_physical_block_size(bdev));
+ case BLKIOMIN:
+ return put_uint(arg, bdev_io_min(bdev));
+ case BLKIOOPT:
+ return put_uint(arg, bdev_io_opt(bdev));
+ case BLKALIGNOFF:
+ return put_int(arg, bdev_alignment_offset(bdev));
case BLKSECTGET:
return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev)));
case BLKRASET:
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index dd8729d674e..0ed42d8870c 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -211,6 +211,18 @@ config ACPI_HOTPLUG_CPU
select ACPI_CONTAINER
default y
+config ACPI_PROCESSOR_AGGREGATOR
+ tristate "Processor Aggregator"
+ depends on ACPI_PROCESSOR
+ depends on EXPERIMENTAL
+ depends on X86
+ help
+ ACPI 4.0 defines processor Aggregator, which enables OS to perform
+ specfic processor configuration and control that applies to all
+ processors in the platform. Currently only logical processor idling
+ is defined, which is to reduce power consumption. This driver
+ support the new device.
+
config ACPI_THERMAL
tristate "Thermal Zone"
depends on ACPI_PROCESSOR
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 82cd49dc603..7702118509a 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -62,3 +62,5 @@ obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o
processor-y := processor_core.o processor_throttling.o
processor-y += processor_idle.o processor_thermal.o
processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
+
+obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
new file mode 100644
index 00000000000..0d2cdb86158
--- /dev/null
+++ b/drivers/acpi/acpi_pad.c
@@ -0,0 +1,514 @@
+/*
+ * acpi_pad.c ACPI Processor Aggregator Driver
+ *
+ * Copyright (c) 2009, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/cpu.h>
+#include <linux/clockchips.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_PROCESSOR_AGGREGATOR_CLASS "processor_aggregator"
+#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
+#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
+static DEFINE_MUTEX(isolated_cpus_lock);
+
+#define MWAIT_SUBSTATE_MASK (0xf)
+#define MWAIT_CSTATE_MASK (0xf)
+#define MWAIT_SUBSTATE_SIZE (4)
+#define CPUID_MWAIT_LEAF (5)
+#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
+#define CPUID5_ECX_INTERRUPT_BREAK (0x2)
+static unsigned long power_saving_mwait_eax;
+static void power_saving_mwait_init(void)
+{
+ unsigned int eax, ebx, ecx, edx;
+ unsigned int highest_cstate = 0;
+ unsigned int highest_subcstate = 0;
+ int i;
+
+ if (!boot_cpu_has(X86_FEATURE_MWAIT))
+ return;
+ if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
+ return;
+
+ cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
+
+ if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
+ !(ecx & CPUID5_ECX_INTERRUPT_BREAK))
+ return;
+
+ edx >>= MWAIT_SUBSTATE_SIZE;
+ for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
+ if (edx & MWAIT_SUBSTATE_MASK) {
+ highest_cstate = i;
+ highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
+ }
+ }
+ power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
+ (highest_subcstate - 1);
+
+ for_each_online_cpu(i)
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i);
+
+#if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86)
+ switch (boot_cpu_data.x86_vendor) {
+ case X86_VENDOR_AMD:
+ case X86_VENDOR_INTEL:
+ /*
+ * AMD Fam10h TSC will tick in all
+ * C/P/S0/S1 states when this bit is set.
+ */
+ if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
+ return;
+
+ /*FALL THROUGH*/
+ default:
+ /* TSC could halt in idle, so notify users */
+ mark_tsc_unstable("TSC halts in idle");
+ }
+#endif
+}
+
+static unsigned long cpu_weight[NR_CPUS];
+static int tsk_in_cpu[NR_CPUS] = {[0 ... NR_CPUS-1] = -1};
+static DECLARE_BITMAP(pad_busy_cpus_bits, NR_CPUS);
+static void round_robin_cpu(unsigned int tsk_index)
+{
+ struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
+ cpumask_var_t tmp;
+ int cpu;
+ unsigned long min_weight = -1, preferred_cpu;
+
+ if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
+ return;
+
+ mutex_lock(&isolated_cpus_lock);
+ cpumask_clear(tmp);
+ for_each_cpu(cpu, pad_busy_cpus)
+ cpumask_or(tmp, tmp, topology_thread_cpumask(cpu));
+ cpumask_andnot(tmp, cpu_online_mask, tmp);
+ /* avoid HT sibilings if possible */
+ if (cpumask_empty(tmp))
+ cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus);
+ if (cpumask_empty(tmp)) {
+ mutex_unlock(&isolated_cpus_lock);
+ return;
+ }
+ for_each_cpu(cpu, tmp) {
+ if (cpu_weight[cpu] < min_weight) {
+ min_weight = cpu_weight[cpu];
+ preferred_cpu = cpu;
+ }
+ }
+
+ if (tsk_in_cpu[tsk_index] != -1)
+ cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
+ tsk_in_cpu[tsk_index] = preferred_cpu;
+ cpumask_set_cpu(preferred_cpu, pad_busy_cpus);
+ cpu_weight[preferred_cpu]++;
+ mutex_unlock(&isolated_cpus_lock);
+
+ set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu));
+}
+
+static void exit_round_robin(unsigned int tsk_index)
+{
+ struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
+ cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
+ tsk_in_cpu[tsk_index] = -1;
+}
+
+static unsigned int idle_pct = 5; /* percentage */
+static unsigned int round_robin_time = 10; /* second */
+static int power_saving_thread(void *data)
+{
+ struct sched_param param = {.sched_priority = 1};
+ int do_sleep;
+ unsigned int tsk_index = (unsigned long)data;
+ u64 last_jiffies = 0;
+
+ sched_setscheduler(current, SCHED_RR, &param);
+
+ while (!kthread_should_stop()) {
+ int cpu;
+ u64 expire_time;
+
+ try_to_freeze();
+
+ /* round robin to cpus */
+ if (last_jiffies + round_robin_time * HZ < jiffies) {
+ last_jiffies = jiffies;
+ round_robin_cpu(tsk_index);
+ }
+
+ do_sleep = 0;
+
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we test
+ * NEED_RESCHED:
+ */
+ smp_mb();
+
+ expire_time = jiffies + HZ * (100 - idle_pct) / 100;
+
+ while (!need_resched()) {
+ local_irq_disable();
+ cpu = smp_processor_id();
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
+ &cpu);
+ stop_critical_timings();
+
+ __monitor((void *)&current_thread_info()->flags, 0, 0);
+ smp_mb();
+ if (!need_resched())
+ __mwait(power_saving_mwait_eax, 1);
+
+ start_critical_timings();
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
+ &cpu);
+ local_irq_enable();
+
+ if (jiffies > expire_time) {
+ do_sleep = 1;
+ break;
+ }
+ }
+
+ current_thread_info()->status |= TS_POLLING;
+
+ /*
+ * current sched_rt has threshold for rt task running time.
+ * When a rt task uses 95% CPU time, the rt thread will be
+ * scheduled out for 5% CPU time to not starve other tasks. But
+ * the mechanism only works when all CPUs have RT task running,
+ * as if one CPU hasn't RT task, RT task from other CPUs will
+ * borrow CPU time from this CPU and cause RT task use > 95%
+ * CPU time. To make 'avoid staration' work, takes a nap here.
+ */
+ if (do_sleep)
+ schedule_timeout_killable(HZ * idle_pct / 100);
+ }
+
+ exit_round_robin(tsk_index);
+ return 0;
+}
+
+static struct task_struct *ps_tsks[NR_CPUS];
+static unsigned int ps_tsk_num;
+static int create_power_saving_task(void)
+{
+ ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
+ (void *)(unsigned long)ps_tsk_num,
+ "power_saving/%d", ps_tsk_num);
+ if (ps_tsks[ps_tsk_num]) {
+ ps_tsk_num++;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static void destroy_power_saving_task(void)
+{
+ if (ps_tsk_num > 0) {
+ ps_tsk_num--;
+ kthread_stop(ps_tsks[ps_tsk_num]);
+ }
+}
+
+static void set_power_saving_task_num(unsigned int num)
+{
+ if (num > ps_tsk_num) {
+ while (ps_tsk_num < num) {
+ if (create_power_saving_task())
+ return;
+ }
+ } else if (num < ps_tsk_num) {
+ while (ps_tsk_num > num)
+ destroy_power_saving_task();
+ }
+}
+
+static int acpi_pad_idle_cpus(unsigned int num_cpus)
+{
+ get_online_cpus();
+
+ num_cpus = min_t(unsigned int, num_cpus, num_online_cpus());
+ set_power_saving_task_num(num_cpus);
+
+ put_online_cpus();
+ return 0;
+}
+
+static uint32_t acpi_pad_idle_cpus_num(void)
+{
+ return ps_tsk_num;
+}
+
+static ssize_t acpi_pad_rrtime_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long num;
+ if (strict_strtoul(buf, 0, &num))
+ return -EINVAL;
+ if (num < 1 || num >= 100)
+ return -EINVAL;
+ mutex_lock(&isolated_cpus_lock);
+ round_robin_time = num;
+ mutex_unlock(&isolated_cpus_lock);
+ return count;
+}
+
+static ssize_t acpi_pad_rrtime_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time);
+}
+static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR,
+ acpi_pad_rrtime_show,
+ acpi_pad_rrtime_store);
+
+static ssize_t acpi_pad_idlepct_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long num;
+ if (strict_strtoul(buf, 0, &num))
+ return -EINVAL;
+ if (num < 1 || num >= 100)
+ return -EINVAL;
+ mutex_lock(&isolated_cpus_lock);
+ idle_pct = num;
+ mutex_unlock(&isolated_cpus_lock);
+ return count;
+}
+
+static ssize_t acpi_pad_idlepct_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d", idle_pct);
+}
+static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR,
+ acpi_pad_idlepct_show,
+ acpi_pad_idlepct_store);
+
+static ssize_t acpi_pad_idlecpus_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long num;
+ if (strict_strtoul(buf, 0, &num))
+ return -EINVAL;
+ mutex_lock(&isolated_cpus_lock);
+ acpi_pad_idle_cpus(num);
+ mutex_unlock(&isolated_cpus_lock);
+ return count;
+}
+
+static ssize_t acpi_pad_idlecpus_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return cpumask_scnprintf(buf, PAGE_SIZE,
+ to_cpumask(pad_busy_cpus_bits));
+}
+static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR,
+ acpi_pad_idlecpus_show,
+ acpi_pad_idlecpus_store);
+
+static int acpi_pad_add_sysfs(struct acpi_device *device)
+{
+ int result;
+
+ result = device_create_file(&device->dev, &dev_attr_idlecpus);
+ if (result)
+ return -ENODEV;
+ result = device_create_file(&device->dev, &dev_attr_idlepct);
+ if (result) {
+ device_remove_file(&device->dev, &dev_attr_idlecpus);
+ return -ENODEV;
+ }
+ result = device_create_file(&device->dev, &dev_attr_rrtime);
+ if (result) {
+ device_remove_file(&device->dev, &dev_attr_idlecpus);
+ device_remove_file(&device->dev, &dev_attr_idlepct);
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static void acpi_pad_remove_sysfs(struct acpi_device *device)
+{
+ device_remove_file(&device->dev, &dev_attr_idlecpus);
+ device_remove_file(&device->dev, &dev_attr_idlepct);
+ device_remove_file(&device->dev, &dev_attr_rrtime);
+}
+
+/* Query firmware how many CPUs should be idle */
+static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
+{
+ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+ acpi_status status;
+ union acpi_object *package;
+ int rev, num, ret = -EINVAL;
+
+ status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer);
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+ package = buffer.pointer;
+ if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
+ goto out;
+ rev = package->package.elements[0].integer.value;
+ num = package->package.elements[1].integer.value;
+ if (rev != 1)
+ goto out;
+ *num_cpus = num;
+ ret = 0;
+out:
+ kfree(buffer.pointer);
+ return ret;
+}
+
+/* Notify firmware how many CPUs are idle */
+static void acpi_pad_ost(acpi_handle handle, int stat,
+ uint32_t idle_cpus)
+{
+ union acpi_object params[3] = {
+ {.type = ACPI_TYPE_INTEGER,},
+ {.type = ACPI_TYPE_INTEGER,},
+ {.type = ACPI_TYPE_BUFFER,},
+ };
+ struct acpi_object_list arg_list = {3, params};
+
+ params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY;
+ params[1].integer.value = stat;
+ params[2].buffer.length = 4;
+ params[2].buffer.pointer = (void *)&idle_cpus;
+ acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
+}
+
+static void acpi_pad_handle_notify(acpi_handle handle)
+{
+ int num_cpus, ret;
+ uint32_t idle_cpus;
+
+ mutex_lock(&isolated_cpus_lock);
+ if (acpi_pad_pur(handle, &num_cpus)) {
+ mutex_unlock(&isolated_cpus_lock);
+ return;
+ }
+ ret = acpi_pad_idle_cpus(num_cpus);
+ idle_cpus = acpi_pad_idle_cpus_num();
+ if (!ret)
+ acpi_pad_ost(handle, 0, idle_cpus);
+ else
+ acpi_pad_ost(handle, 1, 0);
+ mutex_unlock(&isolated_cpus_lock);
+}
+
+static void acpi_pad_notify(acpi_handle handle, u32 event,
+ void *data)
+{
+ struct acpi_device *device = data;
+
+ switch (event) {
+ case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
+ acpi_pad_handle_notify(handle);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ dev_name(&device->dev), event, 0);
+ break;
+ default:
+ printk(KERN_WARNING"Unsupported event [0x%x]\n", event);
+ break;
+ }
+}
+
+static int acpi_pad_add(struct acpi_device *device)
+{
+ acpi_status status;
+
+ strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME);
+ strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS);
+
+ if (acpi_pad_add_sysfs(device))
+ return -ENODEV;
+
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_DEVICE_NOTIFY, acpi_pad_notify, device);
+ if (ACPI_FAILURE(status)) {
+ acpi_pad_remove_sysfs(device);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int acpi_pad_remove(struct acpi_device *device,
+ int type)
+{
+ mutex_lock(&isolated_cpus_lock);
+ acpi_pad_idle_cpus(0);
+ mutex_unlock(&isolated_cpus_lock);
+
+ acpi_remove_notify_handler(device->handle,
+ ACPI_DEVICE_NOTIFY, acpi_pad_notify);
+ acpi_pad_remove_sysfs(device);
+ return 0;
+}
+
+static const struct acpi_device_id pad_device_ids[] = {
+ {"ACPI000C", 0},
+ {"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, pad_device_ids);
+
+static struct acpi_driver acpi_pad_driver = {
+ .name = "processor_aggregator",
+ .class = ACPI_PROCESSOR_AGGREGATOR_CLASS,
+ .ids = pad_device_ids,
+ .ops = {
+ .add = acpi_pad_add,
+ .remove = acpi_pad_remove,
+ },
+};
+
+static int __init acpi_pad_init(void)
+{
+ power_saving_mwait_init();
+ if (power_saving_mwait_eax == 0)
+ return -EINVAL;
+
+ return acpi_bus_register_driver(&acpi_pad_driver);
+}
+
+static void __exit acpi_pad_exit(void)
+{
+ acpi_bus_unregister_driver(&acpi_pad_driver);
+}
+
+module_init(acpi_pad_init);
+module_exit(acpi_pad_exit);
+MODULE_AUTHOR("Shaohua Li<shaohua.li@intel.com>");
+MODULE_DESCRIPTION("ACPI Processor Aggregator Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 3a2cfefc71a..7338b6a3e04 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -67,7 +67,7 @@ struct dock_station {
struct list_head dependent_devices;
struct list_head hotplug_devices;
- struct list_head sibiling;
+ struct list_head sibling;
struct platform_device *dock_device;
};
static LIST_HEAD(dock_stations);
@@ -275,7 +275,7 @@ int is_dock_device(acpi_handle handle)
if (is_dock(handle))
return 1;
- list_for_each_entry(dock_station, &dock_stations, sibiling) {
+ list_for_each_entry(dock_station, &dock_stations, sibling) {
if (find_dock_dependent_device(dock_station, handle))
return 1;
}
@@ -619,7 +619,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
* make sure this handle is for a device dependent on the dock,
* this would include the dock station itself
*/
- list_for_each_entry(dock_station, &dock_stations, sibiling) {
+ list_for_each_entry(dock_station, &dock_stations, sibling) {
/*
* An ATA bay can be in a dock and itself can be ejected
* seperately, so there are two 'dock stations' which need the
@@ -651,7 +651,7 @@ void unregister_hotplug_dock_device(acpi_handle handle)
if (!dock_station_count)
return;
- list_for_each_entry(dock_station, &dock_stations, sibiling) {
+ list_for_each_entry(dock_station, &dock_stations, sibling) {
dd = find_dock_dependent_device(dock_station, handle);
if (dd)
dock_del_hotplug_device(dock_station, dd);
@@ -787,7 +787,7 @@ static int acpi_dock_notifier_call(struct notifier_block *this,
if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
&& event != ACPI_NOTIFY_EJECT_REQUEST)
return 0;
- list_for_each_entry(dock_station, &dock_stations, sibiling) {
+ list_for_each_entry(dock_station, &dock_stations, sibling) {
if (dock_station->handle == handle) {
struct dock_data *dock_data;
@@ -958,7 +958,7 @@ static int dock_add(acpi_handle handle)
dock_station->last_dock_time = jiffies - HZ;
INIT_LIST_HEAD(&dock_station->dependent_devices);
INIT_LIST_HEAD(&dock_station->hotplug_devices);
- INIT_LIST_HEAD(&dock_station->sibiling);
+ INIT_LIST_HEAD(&dock_station->sibling);
spin_lock_init(&dock_station->dd_lock);
mutex_init(&dock_station->hp_lock);
ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
@@ -1044,7 +1044,7 @@ static int dock_add(acpi_handle handle)
add_dock_dependent_device(dock_station, dd);
dock_station_count++;
- list_add(&dock_station->sibiling, &dock_stations);
+ list_add(&dock_station->sibling, &dock_stations);
return 0;
dock_add_err_unregister:
@@ -1149,7 +1149,7 @@ static void __exit dock_exit(void)
struct dock_station *tmp;
unregister_acpi_bus_notifier(&dock_acpi_notifier);
- list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
+ list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling)
dock_remove(dock_station);
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index f70796081c4..baef28c1e63 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -119,6 +119,8 @@ static struct acpi_ec {
} *boot_ec, *first_ec;
static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
+static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
+static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
/* --------------------------------------------------------------------------
Transaction Management
@@ -232,10 +234,8 @@ static int ec_poll(struct acpi_ec *ec)
}
advance_transaction(ec, acpi_ec_read_status(ec));
} while (time_before(jiffies, delay));
- if (!ec->curr->irq_count ||
- (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
+ if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
break;
- /* try restart command if we get any false interrupts */
pr_debug(PREFIX "controller reset, restart transaction\n");
spin_lock_irqsave(&ec->curr_lock, flags);
start_transaction(ec);
@@ -899,6 +899,44 @@ static const struct acpi_device_id ec_device_ids[] = {
{"", 0},
};
+/* Some BIOS do not survive early DSDT scan, skip it */
+static int ec_skip_dsdt_scan(const struct dmi_system_id *id)
+{
+ EC_FLAGS_SKIP_DSDT_SCAN = 1;
+ return 0;
+}
+
+/* ASUStek often supplies us with broken ECDT, validate it */
+static int ec_validate_ecdt(const struct dmi_system_id *id)
+{
+ EC_FLAGS_VALIDATE_ECDT = 1;
+ return 0;
+}
+
+/* MSI EC needs special treatment, enable it */
+static int ec_flag_msi(const struct dmi_system_id *id)
+{
+ EC_FLAGS_MSI = 1;
+ EC_FLAGS_VALIDATE_ECDT = 1;
+ return 0;
+}
+
+static struct dmi_system_id __initdata ec_dmi_table[] = {
+ {
+ ec_skip_dsdt_scan, "Compal JFL92", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
+ DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL},
+ {
+ ec_flag_msi, "MSI hardware", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"),
+ DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL},
+ {
+ ec_validate_ecdt, "ASUS hardware", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
+ {},
+};
+
+
int __init acpi_ec_ecdt_probe(void)
{
acpi_status status;
@@ -911,11 +949,7 @@ int __init acpi_ec_ecdt_probe(void)
/*
* Generate a boot ec context
*/
- if (dmi_name_in_vendors("Micro-Star") ||
- dmi_name_in_vendors("Notebook")) {
- pr_info(PREFIX "Enabling special treatment for EC from MSI.\n");
- EC_FLAGS_MSI = 1;
- }
+ dmi_check_system(ec_dmi_table);
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_SUCCESS(status)) {
@@ -926,7 +960,7 @@ int __init acpi_ec_ecdt_probe(void)
boot_ec->handle = ACPI_ROOT_OBJECT;
acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
/* Don't trust ECDT, which comes from ASUSTek */
- if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0)
+ if (!EC_FLAGS_VALIDATE_ECDT)
goto install;
saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!saved_ec)
@@ -934,6 +968,10 @@ int __init acpi_ec_ecdt_probe(void)
memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
/* fall through */
}
+
+ if (EC_FLAGS_SKIP_DSDT_SCAN)
+ return -ENODEV;
+
/* This workaround is needed only on some broken machines,
* which require early EC, but fail to provide ECDT */
printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index d0d550d22a6..f8b6f555ba5 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -398,6 +398,8 @@ acpi_system_write_wakeup_device(struct file *file,
if (len > 4)
len = 4;
+ if (len < 0)
+ return -EFAULT;
if (copy_from_user(strbuf, buffer, len))
return -EFAULT;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index c2d4d6e0936..c567b46dfa0 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -863,13 +863,6 @@ static int acpi_processor_add(struct acpi_device *device)
goto err_remove_sysfs;
}
- if (pr->flags.throttling) {
- printk(KERN_INFO PREFIX "%s [%s] (supports",
- acpi_device_name(device), acpi_device_bid(device));
- printk(" %d throttling states", pr->throttling.state_count);
- printk(")\n");
- }
-
return 0;
err_remove_sysfs:
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 468921bed22..14a7481c97d 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1052,6 +1052,8 @@ static void acpi_device_set_id(struct acpi_device *device)
device->flags.bus_address = 1;
}
+ kfree(info);
+
/*
* Some devices don't reliably have _HIDs & _CIDs, so add
* synthetic HIDs to make sure drivers can find them.
@@ -1325,13 +1327,8 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
struct acpi_device **child)
{
acpi_status status;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
void *device = NULL;
- acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
- printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n",
- (char *) buffer.pointer);
-
status = acpi_bus_check_add(handle, 0, ops, &device);
if (ACPI_SUCCESS(status))
acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index a4fddb24476..f6e54bf8dd9 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -285,7 +285,7 @@ static int acpi_video_device_brightness_open_fs(struct inode *inode,
struct file *file);
static ssize_t acpi_video_device_write_brightness(struct file *file,
const char __user *buffer, size_t count, loff_t *data);
-static struct file_operations acpi_video_device_brightness_fops = {
+static const struct file_operations acpi_video_device_brightness_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_brightness_open_fs,
.read = seq_read,
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index acd1162712b..b1a257746a1 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -122,6 +122,7 @@ enum {
HOST_VERSION = 0x10, /* AHCI spec. version compliancy */
HOST_EM_LOC = 0x1c, /* Enclosure Management location */
HOST_EM_CTL = 0x20, /* Enclosure Management Control */
+ HOST_CAP2 = 0x24, /* host capabilities, extended */
/* HOST_CTL bits */
HOST_RESET = (1 << 0), /* reset controller; self-clear */
@@ -129,16 +130,29 @@ enum {
HOST_AHCI_EN = (1 << 31), /* AHCI enabled */
/* HOST_CAP bits */
+ HOST_CAP_SXS = (1 << 5), /* Supports External SATA */
HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */
- HOST_CAP_SSC = (1 << 14), /* Slumber capable */
+ HOST_CAP_CCC = (1 << 7), /* Command Completion Coalescing */
+ HOST_CAP_PART = (1 << 13), /* Partial state capable */
+ HOST_CAP_SSC = (1 << 14), /* Slumber state capable */
+ HOST_CAP_PIO_MULTI = (1 << 15), /* PIO multiple DRQ support */
+ HOST_CAP_FBS = (1 << 16), /* FIS-based switching support */
HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */
+ HOST_CAP_ONLY = (1 << 18), /* Supports AHCI mode only */
HOST_CAP_CLO = (1 << 24), /* Command List Override support */
+ HOST_CAP_LED = (1 << 25), /* Supports activity LED */
HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */
HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
+ HOST_CAP_MPS = (1 << 28), /* Mechanical presence switch */
HOST_CAP_SNTF = (1 << 29), /* SNotification register */
HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */
HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */
+ /* HOST_CAP2 bits */
+ HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */
+ HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */
+ HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */
+
/* registers for each SATA port */
PORT_LST_ADDR = 0x00, /* command list DMA addr */
PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */
@@ -267,8 +281,10 @@ struct ahci_em_priv {
struct ahci_host_priv {
unsigned int flags; /* AHCI_HFLAG_* */
u32 cap; /* cap to use */
+ u32 cap2; /* cap2 to use */
u32 port_map; /* port map to use */
u32 saved_cap; /* saved initial cap */
+ u32 saved_cap2; /* saved initial cap2 */
u32 saved_port_map; /* saved initial port_map */
u32 em_loc; /* enclosure management location */
};
@@ -331,12 +347,15 @@ static void ahci_init_sw_activity(struct ata_link *link);
static ssize_t ahci_show_host_caps(struct device *dev,
struct device_attribute *attr, char *buf);
+static ssize_t ahci_show_host_cap2(struct device *dev,
+ struct device_attribute *attr, char *buf);
static ssize_t ahci_show_host_version(struct device *dev,
struct device_attribute *attr, char *buf);
static ssize_t ahci_show_port_cmd(struct device *dev,
struct device_attribute *attr, char *buf);
DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
+DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
@@ -345,6 +364,7 @@ static struct device_attribute *ahci_shost_attrs[] = {
&dev_attr_em_message_type,
&dev_attr_em_message,
&dev_attr_ahci_host_caps,
+ &dev_attr_ahci_host_cap2,
&dev_attr_ahci_host_version,
&dev_attr_ahci_port_cmd,
NULL
@@ -447,7 +467,8 @@ static const struct ata_port_info ahci_port_info[] = {
[board_ahci_sb600] =
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
- AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255),
+ AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 |
+ AHCI_HFLAG_32BIT_ONLY),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
@@ -732,6 +753,16 @@ static ssize_t ahci_show_host_caps(struct device *dev,
return sprintf(buf, "%x\n", hpriv->cap);
}
+static ssize_t ahci_show_host_cap2(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct ata_port *ap = ata_shost_to_port(shost);
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+
+ return sprintf(buf, "%x\n", hpriv->cap2);
+}
+
static ssize_t ahci_show_host_version(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -771,7 +802,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
struct ahci_host_priv *hpriv)
{
void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
- u32 cap, port_map;
+ u32 cap, cap2, vers, port_map;
int i;
int mv;
@@ -784,6 +815,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
hpriv->saved_cap = cap = readl(mmio + HOST_CAP);
hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
+ /* CAP2 register is only defined for AHCI 1.2 and later */
+ vers = readl(mmio + HOST_VERSION);
+ if ((vers >> 16) > 1 ||
+ ((vers >> 16) == 1 && (vers & 0xFFFF) >= 0x200))
+ hpriv->saved_cap2 = cap2 = readl(mmio + HOST_CAP2);
+ else
+ hpriv->saved_cap2 = cap2 = 0;
+
/* some chips have errata preventing 64bit use */
if ((cap & HOST_CAP_64) && (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)) {
dev_printk(KERN_INFO, &pdev->dev,
@@ -869,6 +908,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
/* record values to use during operation */
hpriv->cap = cap;
+ hpriv->cap2 = cap2;
hpriv->port_map = port_map;
}
@@ -887,6 +927,8 @@ static void ahci_restore_initial_config(struct ata_host *host)
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
writel(hpriv->saved_cap, mmio + HOST_CAP);
+ if (hpriv->saved_cap2)
+ writel(hpriv->saved_cap2, mmio + HOST_CAP2);
writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
(void) readl(mmio + HOST_PORTS_IMPL); /* flush */
}
@@ -2534,13 +2576,14 @@ static void ahci_print_info(struct ata_host *host)
struct ahci_host_priv *hpriv = host->private_data;
struct pci_dev *pdev = to_pci_dev(host->dev);
void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
- u32 vers, cap, impl, speed;
+ u32 vers, cap, cap2, impl, speed;
const char *speed_s;
u16 cc;
const char *scc_s;
vers = readl(mmio + HOST_VERSION);
cap = hpriv->cap;
+ cap2 = hpriv->cap2;
impl = hpriv->port_map;
speed = (cap >> 20) & 0xf;
@@ -2583,25 +2626,29 @@ static void ahci_print_info(struct ata_host *host)
"flags: "
"%s%s%s%s%s%s%s"
"%s%s%s%s%s%s%s"
- "%s\n"
+ "%s%s%s%s%s%s\n"
,
- cap & (1 << 31) ? "64bit " : "",
- cap & (1 << 30) ? "ncq " : "",
- cap & (1 << 29) ? "sntf " : "",
- cap & (1 << 28) ? "ilck " : "",
- cap & (1 << 27) ? "stag " : "",
- cap & (1 << 26) ? "pm " : "",
- cap & (1 << 25) ? "led " : "",
-
- cap & (1 << 24) ? "clo " : "",
- cap & (1 << 19) ? "nz " : "",
- cap & (1 << 18) ? "only " : "",
- cap & (1 << 17) ? "pmp " : "",
- cap & (1 << 15) ? "pio " : "",
- cap & (1 << 14) ? "slum " : "",
- cap & (1 << 13) ? "part " : "",
- cap & (1 << 6) ? "ems ": ""
+ cap & HOST_CAP_64 ? "64bit " : "",
+ cap & HOST_CAP_NCQ ? "ncq " : "",
+ cap & HOST_CAP_SNTF ? "sntf " : "",
+ cap & HOST_CAP_MPS ? "ilck " : "",
+ cap & HOST_CAP_SSS ? "stag " : "",
+ cap & HOST_CAP_ALPM ? "pm " : "",
+ cap & HOST_CAP_LED ? "led " : "",
+ cap & HOST_CAP_CLO ? "clo " : "",
+ cap & HOST_CAP_ONLY ? "only " : "",
+ cap & HOST_CAP_PMP ? "pmp " : "",
+ cap & HOST_CAP_FBS ? "fbs " : "",
+ cap & HOST_CAP_PIO_MULTI ? "pio " : "",
+ cap & HOST_CAP_SSC ? "slum " : "",
+ cap & HOST_CAP_PART ? "part " : "",
+ cap & HOST_CAP_CCC ? "ccc " : "",
+ cap & HOST_CAP_EMS ? "ems " : "",
+ cap & HOST_CAP_SXS ? "sxs " : "",
+ cap2 & HOST_CAP2_APST ? "apst " : "",
+ cap2 & HOST_CAP2_NVMHCI ? "nvmp " : "",
+ cap2 & HOST_CAP2_BOH ? "boh " : ""
);
}
@@ -2650,17 +2697,15 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
}
}
-/*
- * SB600 ahci controller on certain boards can't do 64bit DMA with
- * older BIOS.
- */
-static bool ahci_sb600_32bit_only(struct pci_dev *pdev)
+/* only some SB600 ahci controllers can do 64bit DMA */
+static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
{
static const struct dmi_system_id sysids[] = {
/*
* The oldest version known to be broken is 0901 and
* working is 1501 which was released on 2007-10-26.
- * Force 32bit DMA on anything older than 1501.
+ * Enable 64bit DMA on 1501 and anything newer.
+ *
* Please read bko#9412 for more info.
*/
{
@@ -2672,48 +2717,29 @@ static bool ahci_sb600_32bit_only(struct pci_dev *pdev)
},
.driver_data = "20071026", /* yyyymmdd */
},
- /*
- * It's yet unknown whether more recent BIOS fixes the
- * problem. Blacklist the whole board for the time
- * being. Please read the following thread for more
- * info.
- *
- * http://thread.gmane.org/gmane.linux.ide/42326
- */
- {
- .ident = "Gigabyte GA-MA69VM-S2",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR,
- "Gigabyte Technology Co., Ltd."),
- DMI_MATCH(DMI_BOARD_NAME, "GA-MA69VM-S2"),
- },
- },
{ }
};
const struct dmi_system_id *match;
+ int year, month, date;
+ char buf[9];
match = dmi_first_match(sysids);
if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) ||
!match)
return false;
- if (match->driver_data) {
- int year, month, date;
- char buf[9];
-
- dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
- snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
-
- if (strcmp(buf, match->driver_data) >= 0)
- return false;
+ dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
+ if (strcmp(buf, match->driver_data) >= 0) {
+ dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n",
+ match->ident);
+ return true;
+ } else {
dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, "
"forcing 32bit DMA, update BIOS\n", match->ident);
- } else
- dev_printk(KERN_WARNING, &pdev->dev, "%s: this board can't "
- "do 64bit DMA, forcing 32bit\n", match->ident);
-
- return true;
+ return false;
+ }
}
static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
@@ -2858,6 +2884,55 @@ static bool ahci_broken_online(struct pci_dev *pdev)
return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
}
+#ifdef CONFIG_ATA_ACPI
+static void ahci_gtf_filter_workaround(struct ata_host *host)
+{
+ static const struct dmi_system_id sysids[] = {
+ /*
+ * Aspire 3810T issues a bunch of SATA enable commands
+ * via _GTF including an invalid one and one which is
+ * rejected by the device. Among the successful ones
+ * is FPDMA non-zero offset enable which when enabled
+ * only on the drive side leads to NCQ command
+ * failures. Filter it out.
+ */
+ {
+ .ident = "Aspire 3810T",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3810T"),
+ },
+ .driver_data = (void *)ATA_ACPI_FILTER_FPDMA_OFFSET,
+ },
+ { }
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(sysids);
+ unsigned int filter;
+ int i;
+
+ if (!dmi)
+ return;
+
+ filter = (unsigned long)dmi->driver_data;
+ dev_printk(KERN_INFO, host->dev,
+ "applying extra ACPI _GTF filter 0x%x for %s\n",
+ filter, dmi->ident);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+ struct ata_link *link;
+ struct ata_device *dev;
+
+ ata_for_each_link(link, ap, EDGE)
+ ata_for_each_dev(dev, link, ALL)
+ dev->gtf_filter |= filter;
+ }
+}
+#else
+static inline void ahci_gtf_filter_workaround(struct ata_host *host)
+{}
+#endif
+
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
@@ -2926,9 +3001,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
- /* apply sb600 32bit only quirk */
- if (ahci_sb600_32bit_only(pdev))
- hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
+ /* only some SB600s can do 64bit DMA */
+ if (ahci_sb600_enable_64bit(pdev))
+ hpriv->flags &= ~AHCI_HFLAG_32BIT_ONLY;
if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
pci_intx(pdev, 1);
@@ -3023,6 +3098,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* apply workaround for ASUS P5W DH Deluxe mainboard */
ahci_p5wdh_workaround(host);
+ /* apply gtf filter quirk */
+ ahci_gtf_filter_workaround(host);
+
/* initialize adapter */
rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
if (rc)
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 01964b6e6f6..b0882cddfd4 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -20,19 +20,9 @@
#include <acpi/acpi_bus.h>
-enum {
- ATA_ACPI_FILTER_SETXFER = 1 << 0,
- ATA_ACPI_FILTER_LOCK = 1 << 1,
- ATA_ACPI_FILTER_DIPM = 1 << 2,
-
- ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER |
- ATA_ACPI_FILTER_LOCK |
- ATA_ACPI_FILTER_DIPM,
-};
-
-static unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
+unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644);
-MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM)");
+MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM, 0x8=FPDMA non-zero offset, 0x10=FPDMA DMA Setup FIS auto-activate)");
#define NO_PORT_MULT 0xffff
#define SATA_ADR(root, pmp) (((root) << 16) | (pmp))
@@ -613,10 +603,11 @@ static void ata_acpi_gtf_to_tf(struct ata_device *dev,
tf->command = gtf->tf[6]; /* 0x1f7 */
}
-static int ata_acpi_filter_tf(const struct ata_taskfile *tf,
+static int ata_acpi_filter_tf(struct ata_device *dev,
+ const struct ata_taskfile *tf,
const struct ata_taskfile *ptf)
{
- if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_SETXFER) {
+ if (dev->gtf_filter & ATA_ACPI_FILTER_SETXFER) {
/* libata doesn't use ACPI to configure transfer mode.
* It will only confuse device configuration. Skip.
*/
@@ -625,7 +616,7 @@ static int ata_acpi_filter_tf(const struct ata_taskfile *tf,
return 1;
}
- if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_LOCK) {
+ if (dev->gtf_filter & ATA_ACPI_FILTER_LOCK) {
/* BIOS writers, sorry but we don't wanna lock
* features unless the user explicitly said so.
*/
@@ -647,12 +638,23 @@ static int ata_acpi_filter_tf(const struct ata_taskfile *tf,
return 1;
}
- if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_DIPM) {
+ if (tf->command == ATA_CMD_SET_FEATURES &&
+ tf->feature == SETFEATURES_SATA_ENABLE) {
/* inhibit enabling DIPM */
- if (tf->command == ATA_CMD_SET_FEATURES &&
- tf->feature == SETFEATURES_SATA_ENABLE &&
+ if (dev->gtf_filter & ATA_ACPI_FILTER_DIPM &&
tf->nsect == SATA_DIPM)
return 1;
+
+ /* inhibit FPDMA non-zero offset */
+ if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_OFFSET &&
+ (tf->nsect == SATA_FPDMA_OFFSET ||
+ tf->nsect == SATA_FPDMA_IN_ORDER))
+ return 1;
+
+ /* inhibit FPDMA auto activation */
+ if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_AA &&
+ tf->nsect == SATA_FPDMA_AA)
+ return 1;
}
return 0;
@@ -704,7 +706,7 @@ static int ata_acpi_run_tf(struct ata_device *dev,
pptf = &ptf;
}
- if (!ata_acpi_filter_tf(&tf, pptf)) {
+ if (!ata_acpi_filter_tf(dev, &tf, pptf)) {
rtf = tf;
err_mask = ata_exec_internal(dev, &rtf, NULL,
DMA_NONE, NULL, 0, 0);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 0ddaf43d68c..b525a098134 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5591,6 +5591,9 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
dev->link = link;
dev->devno = dev - link->device;
+#ifdef CONFIG_ATA_ACPI
+ dev->gtf_filter = ata_acpi_gtf_filter;
+#endif
ata_dev_init(dev);
}
}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index a04488f0de8..0a97822da21 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2667,14 +2667,14 @@ int ata_eh_reset(struct ata_link *link, int classify,
dev->pio_mode = XFER_PIO_0;
dev->flags &= ~ATA_DFLAG_SLEEPING;
- if (!ata_phys_link_offline(ata_dev_phys_link(dev))) {
- /* apply class override */
- if (lflags & ATA_LFLAG_ASSUME_ATA)
- classes[dev->devno] = ATA_DEV_ATA;
- else if (lflags & ATA_LFLAG_ASSUME_SEMB)
- classes[dev->devno] = ATA_DEV_SEMB_UNSUP;
- } else
- classes[dev->devno] = ATA_DEV_NONE;
+ if (ata_phys_link_offline(ata_dev_phys_link(dev)))
+ continue;
+
+ /* apply class override */
+ if (lflags & ATA_LFLAG_ASSUME_ATA)
+ classes[dev->devno] = ATA_DEV_ATA;
+ else if (lflags & ATA_LFLAG_ASSUME_SEMB)
+ classes[dev->devno] = ATA_DEV_SEMB_UNSUP;
}
/* record current link speed */
@@ -2713,34 +2713,48 @@ int ata_eh_reset(struct ata_link *link, int classify,
ap->pflags &= ~ATA_PFLAG_EH_PENDING;
spin_unlock_irqrestore(link->ap->lock, flags);
- /* Make sure onlineness and classification result correspond.
+ /*
+ * Make sure onlineness and classification result correspond.
* Hotplug could have happened during reset and some
* controllers fail to wait while a drive is spinning up after
* being hotplugged causing misdetection. By cross checking
- * link onlineness and classification result, those conditions
- * can be reliably detected and retried.
+ * link on/offlineness and classification result, those
+ * conditions can be reliably detected and retried.
*/
nr_unknown = 0;
ata_for_each_dev(dev, link, ALL) {
- /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
- if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
- classes[dev->devno] = ATA_DEV_NONE;
- if (ata_phys_link_online(ata_dev_phys_link(dev)))
+ if (ata_phys_link_online(ata_dev_phys_link(dev))) {
+ if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
+ ata_dev_printk(dev, KERN_DEBUG, "link online "
+ "but device misclassifed\n");
+ classes[dev->devno] = ATA_DEV_NONE;
nr_unknown++;
+ }
+ } else if (ata_phys_link_offline(ata_dev_phys_link(dev))) {
+ if (ata_class_enabled(classes[dev->devno]))
+ ata_dev_printk(dev, KERN_DEBUG, "link offline, "
+ "clearing class %d to NONE\n",
+ classes[dev->devno]);
+ classes[dev->devno] = ATA_DEV_NONE;
+ } else if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
+ ata_dev_printk(dev, KERN_DEBUG, "link status unknown, "
+ "clearing UNKNOWN to NONE\n");
+ classes[dev->devno] = ATA_DEV_NONE;
}
}
if (classify && nr_unknown) {
if (try < max_tries) {
ata_link_printk(link, KERN_WARNING, "link online but "
- "device misclassified, retrying\n");
+ "%d devices misclassified, retrying\n",
+ nr_unknown);
failed_link = link;
rc = -EAGAIN;
goto fail;
}
ata_link_printk(link, KERN_WARNING,
- "link online but device misclassified, "
- "device detection might fail\n");
+ "link online but %d devices misclassified, "
+ "device detection might fail\n", nr_unknown);
}
/* reset successful, schedule revalidation */
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index be8e2628f82..823e6309636 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -118,6 +118,8 @@ extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
/* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI
+extern unsigned int ata_acpi_gtf_filter;
+
extern void ata_acpi_associate_sata_port(struct ata_port *ap);
extern void ata_acpi_associate(struct ata_host *host);
extern void ata_acpi_dissociate(struct ata_host *host);
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index fc9c5d6d7d8..1432dc9d0ab 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -290,7 +290,7 @@ static void ali_warn_atapi_dma(struct ata_device *adev)
if (print_info && adev->class == ATA_DEV_ATAPI && !ali_atapi_dma) {
ata_dev_printk(adev, KERN_WARNING,
- "WARNING: ATAPI DMA disabled for reliablity issues. It can be enabled\n");
+ "WARNING: ATAPI DMA disabled for reliability issues. It can be enabled\n");
ata_dev_printk(adev, KERN_WARNING,
"WARNING: via pata_ali.atapi_dma modparam or corresponding sysfs node.\n");
}
diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c
index 7990de925d2..6fe7ded40c6 100644
--- a/drivers/ata/pata_atp867x.c
+++ b/drivers/ata/pata_atp867x.c
@@ -118,20 +118,13 @@ struct atp867x_priv {
int pci66mhz;
};
-static inline u8 atp867x_speed_to_mode(u8 speed)
-{
- return speed - XFER_UDMA_0 + 1;
-}
-
static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
struct atp867x_priv *dp = ap->private_data;
u8 speed = adev->dma_mode;
u8 b;
- u8 mode;
-
- mode = atp867x_speed_to_mode(speed);
+ u8 mode = speed - XFER_UDMA_0 + 1;
/*
* Doc 6.6.9: decrease the udma mode value by 1 for safer UDMA speed
@@ -156,25 +149,38 @@ static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
iowrite8(b, dp->dma_mode);
}
-static int atp867x_get_active_clocks_shifted(unsigned int clk)
+static int atp867x_get_active_clocks_shifted(struct ata_port *ap,
+ unsigned int clk)
{
+ struct atp867x_priv *dp = ap->private_data;
unsigned char clocks = clk;
+ /*
+ * Doc 6.6.9: increase the clock value by 1 for safer PIO speed
+ * on 66MHz bus
+ */
+ if (dp->pci66mhz)
+ clocks++;
+
switch (clocks) {
case 0:
clocks = 1;
break;
- case 1 ... 7:
- break;
- case 8 ... 12:
- clocks = 7;
+ case 1 ... 6:
break;
default:
printk(KERN_WARNING "ATP867X: active %dclk is invalid. "
- "Using default 8clk.\n", clk);
- clocks = 0; /* 8 clk */
+ "Using 12clk.\n", clk);
+ case 9 ... 12:
+ clocks = 7; /* 12 clk */
break;
+ case 7:
+ case 8: /* default 8 clk */
+ clocks = 0;
+ goto active_clock_shift_done;
}
+
+active_clock_shift_done:
return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT;
}
@@ -188,20 +194,20 @@ static int atp867x_get_recover_clocks_shifted(unsigned int clk)
break;
case 1 ... 11:
break;
- case 12:
- clocks = 0;
- break;
- case 13: case 14:
- --clocks;
+ case 13:
+ case 14:
+ --clocks; /* by the spec */
break;
case 15:
break;
default:
printk(KERN_WARNING "ATP867X: recover %dclk is invalid. "
- "Using default 15clk.\n", clk);
- clocks = 0; /* 12 clk */
+ "Using default 12clk.\n", clk);
+ case 12: /* default 12 clk */
+ clocks = 0;
break;
}
+
return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT;
}
@@ -230,25 +236,38 @@ static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev)
b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK);
iowrite8(b, dp->dma_mode);
- b = atp867x_get_active_clocks_shifted(t.active) |
- atp867x_get_recover_clocks_shifted(t.recover);
- if (dp->pci66mhz)
- b += 0x10;
+ b = atp867x_get_active_clocks_shifted(ap, t.active) |
+ atp867x_get_recover_clocks_shifted(t.recover);
if (adev->devno & 1)
iowrite8(b, dp->slave_piospd);
else
iowrite8(b, dp->mstr_piospd);
- /*
- * use the same value for comand timing as for PIO timimg
- */
+ b = atp867x_get_active_clocks_shifted(ap, t.act8b) |
+ atp867x_get_recover_clocks_shifted(t.rec8b);
+
iowrite8(b, dp->eightb_piospd);
}
+static int atp867x_cable_override(struct pci_dev *pdev)
+{
+ if (pdev->subsystem_vendor == PCI_VENDOR_ID_ARTOP &&
+ (pdev->subsystem_device == PCI_DEVICE_ID_ARTOP_ATP867A ||
+ pdev->subsystem_device == PCI_DEVICE_ID_ARTOP_ATP867B)) {
+ return 1;
+ }
+ return 0;
+}
+
static int atp867x_cable_detect(struct ata_port *ap)
{
- return ATA_CBL_PATA40_SHORT;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+ if (atp867x_cable_override(pdev))
+ return ATA_CBL_PATA40_SHORT;
+
+ return ATA_CBL_PATA_UNK;
}
static struct scsi_host_template atp867x_sht = {
@@ -471,7 +490,6 @@ static int atp867x_init_one(struct pci_dev *pdev,
static const struct ata_port_info info_867x = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
- .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &atp867x_ops,
};
@@ -515,6 +533,23 @@ err_out:
return rc;
}
+#ifdef CONFIG_PM
+static int atp867x_reinit_one(struct pci_dev *pdev)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
+
+ atp867x_fixup(host);
+
+ ata_host_resume(host);
+ return 0;
+}
+#endif
+
static struct pci_device_id atp867x_pci_tbl[] = {
{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867A), 0 },
{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867B), 0 },
@@ -526,6 +561,10 @@ static struct pci_driver atp867x_driver = {
.id_table = atp867x_pci_tbl,
.probe = atp867x_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
+ .suspend = ata_pci_device_suspend,
+ .resume = atp867x_reinit_one,
+#endif
};
static int __init atp867x_init(void)
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 703364b5217..66e181345b3 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -1306,14 +1306,6 @@ static void amb_close (struct atm_vcc * atm_vcc) {
return;
}
-/********** Set socket options for a VC **********/
-
-// int amb_getsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen);
-
-/********** Set socket options for a VC **********/
-
-// int amb_setsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen);
-
/********** Send **********/
static int amb_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) {
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 5503bfc8e13..0c302614544 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2031,7 +2031,7 @@ static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen)
+ void __user *optval,unsigned int optlen)
{
return -EINVAL;
}
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index b119640e1ee..cd5049af47a 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1244,7 +1244,7 @@ static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,
static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen)
+ void __user *optval,unsigned int optlen)
{
func_enter ();
func_exit ();
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 10f000dbe44..f766cc46b4c 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -1795,7 +1795,7 @@ fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *op
static int
-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
+fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
{
/* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 01ce241dbea..4e49021e67e 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2590,7 +2590,7 @@ static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
}
static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
- void *optval, int optlen) {
+ void *optval, unsigned int optlen) {
hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
switch (level) {
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 78c9736c357..b2c1b37ab2e 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -2862,7 +2862,7 @@ static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,
}
static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,
- void __user *optval, int optlen)
+ void __user *optval, unsigned int optlen)
{
IF_EVENT(printk(">ia_setsockopt\n");)
return -EINVAL;
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 752b1ba81f7..2e9635be048 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1517,7 +1517,7 @@ static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen)
+ void __user *optval,unsigned int optlen)
{
return -EINVAL;
}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 6fa7b0fdbdf..eb4fa194394 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -38,6 +38,7 @@
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/reboot.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
@@ -6422,16 +6423,10 @@ static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
return true;
}
-
-/*
- DAC960_ProcReadStatus implements reading /proc/rd/status.
-*/
-
-static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
- int Count, int *EOF, void *Data)
+static int dac960_proc_show(struct seq_file *m, void *v)
{
unsigned char *StatusMessage = "OK\n";
- int ControllerNumber, BytesAvailable;
+ int ControllerNumber;
for (ControllerNumber = 0;
ControllerNumber < DAC960_ControllerCount;
ControllerNumber++)
@@ -6444,52 +6439,49 @@ static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
break;
}
}
- BytesAvailable = strlen(StatusMessage) - Offset;
- if (Count >= BytesAvailable)
- {
- Count = BytesAvailable;
- *EOF = true;
- }
- if (Count <= 0) return 0;
- *Start = Page;
- memcpy(Page, &StatusMessage[Offset], Count);
- return Count;
+ seq_puts(m, StatusMessage);
+ return 0;
}
+static int dac960_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dac960_proc_show, NULL);
+}
-/*
- DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
-*/
+static const struct file_operations dac960_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = dac960_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
-static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
- int Count, int *EOF, void *Data)
+static int dac960_initial_status_proc_show(struct seq_file *m, void *v)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
- int BytesAvailable = Controller->InitialStatusLength - Offset;
- if (Count >= BytesAvailable)
- {
- Count = BytesAvailable;
- *EOF = true;
- }
- if (Count <= 0) return 0;
- *Start = Page;
- memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
- return Count;
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private;
+ seq_printf(m, "%.*s", Controller->InitialStatusLength, Controller->CombinedStatusBuffer);
+ return 0;
}
+static int dac960_initial_status_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data);
+}
-/*
- DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
-*/
+static const struct file_operations dac960_initial_status_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = dac960_initial_status_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
-static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
- int Count, int *EOF, void *Data)
+static int dac960_current_status_proc_show(struct seq_file *m, void *v)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *) m->private;
unsigned char *StatusMessage =
"No Rebuild or Consistency Check in Progress\n";
int ProgressMessageLength = strlen(StatusMessage);
- int BytesAvailable;
if (jiffies != Controller->LastCurrentStatusTime)
{
Controller->CurrentStatusLength = 0;
@@ -6513,49 +6505,41 @@ static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
}
Controller->LastCurrentStatusTime = jiffies;
}
- BytesAvailable = Controller->CurrentStatusLength - Offset;
- if (Count >= BytesAvailable)
- {
- Count = BytesAvailable;
- *EOF = true;
- }
- if (Count <= 0) return 0;
- *Start = Page;
- memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
- return Count;
+ seq_printf(m, "%.*s", Controller->CurrentStatusLength, Controller->CurrentStatusBuffer);
+ return 0;
}
+static int dac960_current_status_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dac960_current_status_proc_show, PDE(inode)->data);
+}
-/*
- DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
-*/
+static const struct file_operations dac960_current_status_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = dac960_current_status_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
-static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
- int Count, int *EOF, void *Data)
+static int dac960_user_command_proc_show(struct seq_file *m, void *v)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
- int BytesAvailable = Controller->UserStatusLength - Offset;
- if (Count >= BytesAvailable)
- {
- Count = BytesAvailable;
- *EOF = true;
- }
- if (Count <= 0) return 0;
- *Start = Page;
- memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
- return Count;
-}
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private;
+ seq_printf(m, "%.*s", Controller->UserStatusLength, Controller->UserStatusBuffer);
+ return 0;
+}
-/*
- DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
-*/
+static int dac960_user_command_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dac960_user_command_proc_show, PDE(inode)->data);
+}
-static int DAC960_ProcWriteUserCommand(struct file *file,
+static ssize_t dac960_user_command_proc_write(struct file *file,
const char __user *Buffer,
- unsigned long Count, void *Data)
+ size_t Count, loff_t *pos)
{
- DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+ DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file->f_path.dentry->d_inode)->data;
unsigned char CommandBuffer[80];
int Length;
if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
@@ -6572,6 +6556,14 @@ static int DAC960_ProcWriteUserCommand(struct file *file,
? Count : -EBUSY);
}
+static const struct file_operations dac960_user_command_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = dac960_user_command_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = dac960_user_command_proc_write,
+};
/*
DAC960_CreateProcEntries creates the /proc/rd/... entries for the
@@ -6586,23 +6578,17 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
if (DAC960_ProcDirectoryEntry == NULL) {
DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
- StatusProcEntry = create_proc_read_entry("status", 0,
+ StatusProcEntry = proc_create("status", 0,
DAC960_ProcDirectoryEntry,
- DAC960_ProcReadStatus, NULL);
+ &dac960_proc_fops);
}
sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
ControllerProcEntry = proc_mkdir(Controller->ControllerName,
DAC960_ProcDirectoryEntry);
- create_proc_read_entry("initial_status", 0, ControllerProcEntry,
- DAC960_ProcReadInitialStatus, Controller);
- create_proc_read_entry("current_status", 0, ControllerProcEntry,
- DAC960_ProcReadCurrentStatus, Controller);
- UserCommandProcEntry =
- create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
- ControllerProcEntry, DAC960_ProcReadUserCommand,
- Controller);
- UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
+ proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller);
+ proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller);
+ UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller);
Controller->ControllerProcEntry = ControllerProcEntry;
}
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 24c3e21ab26..fb5be2d95d5 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -36,9 +36,11 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#include <linux/hdreg.h>
#include <linux/spinlock.h>
#include <linux/compat.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -155,6 +157,10 @@ static struct board_type products[] = {
static ctlr_info_t *hba[MAX_CTLR];
+static struct task_struct *cciss_scan_thread;
+static DEFINE_MUTEX(scan_mutex);
+static LIST_HEAD(scan_q);
+
static void do_cciss_request(struct request_queue *q);
static irqreturn_t do_cciss_intr(int irq, void *dev_id);
static int cciss_open(struct block_device *bdev, fmode_t mode);
@@ -164,9 +170,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
static int cciss_revalidate(struct gendisk *disk);
-static int rebuild_lun_table(ctlr_info_t *h, int first_time);
+static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl);
static int deregister_disk(ctlr_info_t *h, int drv_index,
- int clear_all);
+ int clear_all, int via_ioctl);
static void cciss_read_capacity(int ctlr, int logvol, int withirq,
sector_t *total_size, unsigned int *block_size);
@@ -189,8 +195,13 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c,
static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c);
static void fail_all_cmds(unsigned long ctlr);
+static int add_to_scan_list(struct ctlr_info *h);
static int scan_thread(void *data);
static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c);
+static void cciss_hba_release(struct device *dev);
+static void cciss_device_release(struct device *dev);
+static void cciss_free_gendisk(ctlr_info_t *h, int drv_index);
+static void cciss_free_drive_info(ctlr_info_t *h, int drv_index);
#ifdef CONFIG_PROC_FS
static void cciss_procinit(int i);
@@ -245,7 +256,10 @@ static inline void removeQ(CommandList_struct *c)
#include "cciss_scsi.c" /* For SCSI tape support */
-#define RAID_UNKNOWN 6
+static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
+ "UNKNOWN"
+};
+#define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1)
#ifdef CONFIG_PROC_FS
@@ -255,9 +269,6 @@ static inline void removeQ(CommandList_struct *c)
#define ENG_GIG 1000000000
#define ENG_GIG_FACTOR (ENG_GIG/512)
#define ENGAGE_SCSI "engage scsi"
-static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
- "UNKNOWN"
-};
static struct proc_dir_entry *proc_cciss;
@@ -318,7 +329,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v)
ctlr_info_t *h = seq->private;
unsigned ctlr = h->ctlr;
loff_t *pos = v;
- drive_info_struct *drv = &h->drv[*pos];
+ drive_info_struct *drv = h->drv[*pos];
if (*pos > h->highest_lun)
return 0;
@@ -331,7 +342,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v)
vol_sz_frac *= 100;
sector_div(vol_sz_frac, ENG_GIG_FACTOR);
- if (drv->raid_level > 5)
+ if (drv->raid_level < 0 || drv->raid_level > RAID_UNKNOWN)
drv->raid_level = RAID_UNKNOWN;
seq_printf(seq, "cciss/c%dd%d:"
"\t%4u.%02uGB\tRAID %s\n",
@@ -426,7 +437,7 @@ out:
return err;
}
-static struct file_operations cciss_proc_fops = {
+static const struct file_operations cciss_proc_fops = {
.owner = THIS_MODULE,
.open = cciss_seq_open,
.read = seq_read,
@@ -454,9 +465,19 @@ static void __devinit cciss_procinit(int i)
#define to_hba(n) container_of(n, struct ctlr_info, dev)
#define to_drv(n) container_of(n, drive_info_struct, dev)
-static struct device_type cciss_host_type = {
- .name = "cciss_host",
-};
+static ssize_t host_store_rescan(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ctlr_info *h = to_hba(dev);
+
+ add_to_scan_list(h);
+ wake_up_process(cciss_scan_thread);
+ wait_for_completion_interruptible(&h->scan_wait);
+
+ return count;
+}
+DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
static ssize_t dev_show_unique_id(struct device *dev,
struct device_attribute *attr,
@@ -560,11 +581,101 @@ static ssize_t dev_show_rev(struct device *dev,
}
DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
+static ssize_t cciss_show_lunid(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ drive_info_struct *drv = to_drv(dev);
+ struct ctlr_info *h = to_hba(drv->dev.parent);
+ unsigned long flags;
+ unsigned char lunid[8];
+
+ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+ if (h->busy_configuring) {
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return -EBUSY;
+ }
+ if (!drv->heads) {
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return -ENOTTY;
+ }
+ memcpy(lunid, drv->LunID, sizeof(lunid));
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ lunid[0], lunid[1], lunid[2], lunid[3],
+ lunid[4], lunid[5], lunid[6], lunid[7]);
+}
+DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
+
+static ssize_t cciss_show_raid_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ drive_info_struct *drv = to_drv(dev);
+ struct ctlr_info *h = to_hba(drv->dev.parent);
+ int raid;
+ unsigned long flags;
+
+ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+ if (h->busy_configuring) {
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return -EBUSY;
+ }
+ raid = drv->raid_level;
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ if (raid < 0 || raid > RAID_UNKNOWN)
+ raid = RAID_UNKNOWN;
+
+ return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n",
+ raid_label[raid]);
+}
+DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
+
+static ssize_t cciss_show_usage_count(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ drive_info_struct *drv = to_drv(dev);
+ struct ctlr_info *h = to_hba(drv->dev.parent);
+ unsigned long flags;
+ int count;
+
+ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+ if (h->busy_configuring) {
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return -EBUSY;
+ }
+ count = drv->usage_count;
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+ return snprintf(buf, 20, "%d\n", count);
+}
+DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
+
+static struct attribute *cciss_host_attrs[] = {
+ &dev_attr_rescan.attr,
+ NULL
+};
+
+static struct attribute_group cciss_host_attr_group = {
+ .attrs = cciss_host_attrs,
+};
+
+static const struct attribute_group *cciss_host_attr_groups[] = {
+ &cciss_host_attr_group,
+ NULL
+};
+
+static struct device_type cciss_host_type = {
+ .name = "cciss_host",
+ .groups = cciss_host_attr_groups,
+ .release = cciss_hba_release,
+};
+
static struct attribute *cciss_dev_attrs[] = {
&dev_attr_unique_id.attr,
&dev_attr_model.attr,
&dev_attr_vendor.attr,
&dev_attr_rev.attr,
+ &dev_attr_lunid.attr,
+ &dev_attr_raid_level.attr,
+ &dev_attr_usage_count.attr,
NULL
};
@@ -580,12 +691,24 @@ static const struct attribute_group *cciss_dev_attr_groups[] = {
static struct device_type cciss_dev_type = {
.name = "cciss_device",
.groups = cciss_dev_attr_groups,
+ .release = cciss_device_release,
};
static struct bus_type cciss_bus_type = {
.name = "cciss",
};
+/*
+ * cciss_hba_release is called when the reference count
+ * of h->dev goes to zero.
+ */
+static void cciss_hba_release(struct device *dev)
+{
+ /*
+ * nothing to do, but need this to avoid a warning
+ * about not having a release handler from lib/kref.c.
+ */
+}
/*
* Initialize sysfs entry for each controller. This sets up and registers
@@ -609,6 +732,16 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h)
static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
{
device_del(&h->dev);
+ put_device(&h->dev); /* final put. */
+}
+
+/* cciss_device_release is called when the reference count
+ * of h->drv[x]dev goes to zero.
+ */
+static void cciss_device_release(struct device *dev)
+{
+ drive_info_struct *drv = to_drv(dev);
+ kfree(drv);
}
/*
@@ -617,24 +750,39 @@ static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
* /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
* /sys/block/cciss!c#d# to this entry.
*/
-static int cciss_create_ld_sysfs_entry(struct ctlr_info *h,
- drive_info_struct *drv,
+static long cciss_create_ld_sysfs_entry(struct ctlr_info *h,
int drv_index)
{
- device_initialize(&drv->dev);
- drv->dev.type = &cciss_dev_type;
- drv->dev.bus = &cciss_bus_type;
- dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index);
- drv->dev.parent = &h->dev;
- return device_add(&drv->dev);
+ struct device *dev;
+
+ if (h->drv[drv_index]->device_initialized)
+ return 0;
+
+ dev = &h->drv[drv_index]->dev;
+ device_initialize(dev);
+ dev->type = &cciss_dev_type;
+ dev->bus = &cciss_bus_type;
+ dev_set_name(dev, "c%dd%d", h->ctlr, drv_index);
+ dev->parent = &h->dev;
+ h->drv[drv_index]->device_initialized = 1;
+ return device_add(dev);
}
/*
* Remove sysfs entries for a logical drive.
*/
-static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv)
+static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index,
+ int ctlr_exiting)
{
- device_del(&drv->dev);
+ struct device *dev = &h->drv[drv_index]->dev;
+
+ /* special case for c*d0, we only destroy it on controller exit */
+ if (drv_index == 0 && !ctlr_exiting)
+ return;
+
+ device_del(dev);
+ put_device(dev); /* the "final" put. */
+ h->drv[drv_index] = NULL;
}
/*
@@ -751,7 +899,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name);
#endif /* CCISS_DEBUG */
- if (host->busy_initializing || drv->busy_configuring)
+ if (drv->busy_configuring)
return -EBUSY;
/*
* Root is allowed to open raw volume zero even if it's not configured
@@ -767,7 +915,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
if (MINOR(bdev->bd_dev) & 0x0f) {
return -ENXIO;
/* if it is, make sure we have a LUN ID */
- } else if (drv->LunID == 0) {
+ } else if (memcmp(drv->LunID, CTLR_LUNID,
+ sizeof(drv->LunID))) {
return -ENXIO;
}
}
@@ -1132,12 +1281,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
case CCISS_DEREGDISK:
case CCISS_REGNEWD:
case CCISS_REVALIDVOLS:
- return rebuild_lun_table(host, 0);
+ return rebuild_lun_table(host, 0, 1);
case CCISS_GETLUNINFO:{
LogvolInfo_struct luninfo;
- luninfo.LunID = drv->LunID;
+ memcpy(&luninfo.LunID, drv->LunID,
+ sizeof(luninfo.LunID));
luninfo.num_opens = drv->usage_count;
luninfo.num_parts = 0;
if (copy_to_user(argp, &luninfo,
@@ -1475,7 +1625,10 @@ static void cciss_check_queues(ctlr_info_t *h)
/* make sure the disk has been added and the drive is real
* because this can be called from the middle of init_one.
*/
- if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
+ if (!h->drv[curr_queue])
+ continue;
+ if (!(h->drv[curr_queue]->queue) ||
+ !(h->drv[curr_queue]->heads))
continue;
blk_start_queue(h->gendisk[curr_queue]->queue);
@@ -1532,13 +1685,11 @@ static void cciss_softirq_done(struct request *rq)
spin_unlock_irqrestore(&h->lock, flags);
}
-static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[],
- uint32_t log_unit)
+static inline void log_unit_to_scsi3addr(ctlr_info_t *h,
+ unsigned char scsi3addr[], uint32_t log_unit)
{
- log_unit = h->drv[log_unit].LunID & 0x03fff;
- memset(&scsi3addr[4], 0, 4);
- memcpy(&scsi3addr[0], &log_unit, 4);
- scsi3addr[3] |= 0x40;
+ memcpy(scsi3addr, h->drv[log_unit]->LunID,
+ sizeof(h->drv[log_unit]->LunID));
}
/* This function gets the SCSI vendor, model, and revision of a logical drive
@@ -1615,16 +1766,23 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq,
return;
}
-static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
+/*
+ * cciss_add_disk sets up the block device queue for a logical drive
+ */
+static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
int drv_index)
{
disk->queue = blk_init_queue(do_cciss_request, &h->lock);
+ if (!disk->queue)
+ goto init_queue_failure;
sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index);
disk->major = h->major;
disk->first_minor = drv_index << NWD_SHIFT;
disk->fops = &cciss_fops;
- disk->private_data = &h->drv[drv_index];
- disk->driverfs_dev = &h->drv[drv_index].dev;
+ if (cciss_create_ld_sysfs_entry(h, drv_index))
+ goto cleanup_queue;
+ disk->private_data = h->drv[drv_index];
+ disk->driverfs_dev = &h->drv[drv_index]->dev;
/* Set up queue information */
blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
@@ -1642,14 +1800,21 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
disk->queue->queuedata = h;
blk_queue_logical_block_size(disk->queue,
- h->drv[drv_index].block_size);
+ h->drv[drv_index]->block_size);
/* Make sure all queue data is written out before */
- /* setting h->drv[drv_index].queue, as setting this */
+ /* setting h->drv[drv_index]->queue, as setting this */
/* allows the interrupt handler to start the queue */
wmb();
- h->drv[drv_index].queue = disk->queue;
+ h->drv[drv_index]->queue = disk->queue;
add_disk(disk);
+ return 0;
+
+cleanup_queue:
+ blk_cleanup_queue(disk->queue);
+ disk->queue = NULL;
+init_queue_failure:
+ return -1;
}
/* This function will check the usage_count of the drive to be updated/added.
@@ -1662,7 +1827,8 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
* is also the controller node. Any changes to disk 0 will show up on
* the next reboot.
*/
-static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
+static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
+ int via_ioctl)
{
ctlr_info_t *h = hba[ctlr];
struct gendisk *disk;
@@ -1672,21 +1838,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
unsigned long flags = 0;
int ret = 0;
drive_info_struct *drvinfo;
- int was_only_controller_node;
/* Get information about the disk and modify the driver structure */
inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
- drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL);
+ drvinfo = kzalloc(sizeof(*drvinfo), GFP_KERNEL);
if (inq_buff == NULL || drvinfo == NULL)
goto mem_msg;
- /* See if we're trying to update the "controller node"
- * this will happen the when the first logical drive gets
- * created by ACU.
- */
- was_only_controller_node = (drv_index == 0 &&
- h->drv[0].raid_level == -1);
-
/* testing to see if 16-byte CDBs are already being used */
if (h->cciss_read == CCISS_READ_16) {
cciss_read_capacity_16(h->ctlr, drv_index, 1,
@@ -1719,16 +1877,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
drvinfo->model, drvinfo->rev);
cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no,
sizeof(drvinfo->serial_no));
+ /* Save the lunid in case we deregister the disk, below. */
+ memcpy(drvinfo->LunID, h->drv[drv_index]->LunID,
+ sizeof(drvinfo->LunID));
/* Is it the same disk we already know, and nothing's changed? */
- if (h->drv[drv_index].raid_level != -1 &&
+ if (h->drv[drv_index]->raid_level != -1 &&
((memcmp(drvinfo->serial_no,
- h->drv[drv_index].serial_no, 16) == 0) &&
- drvinfo->block_size == h->drv[drv_index].block_size &&
- drvinfo->nr_blocks == h->drv[drv_index].nr_blocks &&
- drvinfo->heads == h->drv[drv_index].heads &&
- drvinfo->sectors == h->drv[drv_index].sectors &&
- drvinfo->cylinders == h->drv[drv_index].cylinders))
+ h->drv[drv_index]->serial_no, 16) == 0) &&
+ drvinfo->block_size == h->drv[drv_index]->block_size &&
+ drvinfo->nr_blocks == h->drv[drv_index]->nr_blocks &&
+ drvinfo->heads == h->drv[drv_index]->heads &&
+ drvinfo->sectors == h->drv[drv_index]->sectors &&
+ drvinfo->cylinders == h->drv[drv_index]->cylinders))
/* The disk is unchanged, nothing to update */
goto freeret;
@@ -1738,18 +1899,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
* If the disk already exists then deregister it before proceeding
* (unless it's the first disk (for the controller node).
*/
- if (h->drv[drv_index].raid_level != -1 && drv_index != 0) {
+ if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) {
printk(KERN_WARNING "disk %d has changed.\n", drv_index);
spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
- h->drv[drv_index].busy_configuring = 1;
+ h->drv[drv_index]->busy_configuring = 1;
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
- /* deregister_disk sets h->drv[drv_index].queue = NULL
+ /* deregister_disk sets h->drv[drv_index]->queue = NULL
* which keeps the interrupt handler from starting
* the queue.
*/
- ret = deregister_disk(h, drv_index, 0);
- h->drv[drv_index].busy_configuring = 0;
+ ret = deregister_disk(h, drv_index, 0, via_ioctl);
}
/* If the disk is in use return */
@@ -1757,22 +1917,31 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
goto freeret;
/* Save the new information from cciss_geometry_inquiry
- * and serial number inquiry.
+ * and serial number inquiry. If the disk was deregistered
+ * above, then h->drv[drv_index] will be NULL.
*/
- h->drv[drv_index].block_size = drvinfo->block_size;
- h->drv[drv_index].nr_blocks = drvinfo->nr_blocks;
- h->drv[drv_index].heads = drvinfo->heads;
- h->drv[drv_index].sectors = drvinfo->sectors;
- h->drv[drv_index].cylinders = drvinfo->cylinders;
- h->drv[drv_index].raid_level = drvinfo->raid_level;
- memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16);
- memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1);
- memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1);
- memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1);
+ if (h->drv[drv_index] == NULL) {
+ drvinfo->device_initialized = 0;
+ h->drv[drv_index] = drvinfo;
+ drvinfo = NULL; /* so it won't be freed below. */
+ } else {
+ /* special case for cxd0 */
+ h->drv[drv_index]->block_size = drvinfo->block_size;
+ h->drv[drv_index]->nr_blocks = drvinfo->nr_blocks;
+ h->drv[drv_index]->heads = drvinfo->heads;
+ h->drv[drv_index]->sectors = drvinfo->sectors;
+ h->drv[drv_index]->cylinders = drvinfo->cylinders;
+ h->drv[drv_index]->raid_level = drvinfo->raid_level;
+ memcpy(h->drv[drv_index]->serial_no, drvinfo->serial_no, 16);
+ memcpy(h->drv[drv_index]->vendor, drvinfo->vendor,
+ VENDOR_LEN + 1);
+ memcpy(h->drv[drv_index]->model, drvinfo->model, MODEL_LEN + 1);
+ memcpy(h->drv[drv_index]->rev, drvinfo->rev, REV_LEN + 1);
+ }
++h->num_luns;
disk = h->gendisk[drv_index];
- set_capacity(disk, h->drv[drv_index].nr_blocks);
+ set_capacity(disk, h->drv[drv_index]->nr_blocks);
/* If it's not disk 0 (drv_index != 0)
* or if it was disk 0, but there was previously
@@ -1780,8 +1949,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
* (raid_leve == -1) then we want to update the
* logical drive's information.
*/
- if (drv_index || first_time)
- cciss_add_disk(h, disk, drv_index);
+ if (drv_index || first_time) {
+ if (cciss_add_disk(h, disk, drv_index) != 0) {
+ cciss_free_gendisk(h, drv_index);
+ cciss_free_drive_info(h, drv_index);
+ printk(KERN_WARNING "cciss:%d could not update "
+ "disk %d\n", h->ctlr, drv_index);
+ --h->num_luns;
+ }
+ }
freeret:
kfree(inq_buff);
@@ -1793,28 +1969,70 @@ mem_msg:
}
/* This function will find the first index of the controllers drive array
- * that has a -1 for the raid_level and will return that index. This is
- * where new drives will be added. If the index to be returned is greater
- * than the highest_lun index for the controller then highest_lun is set
- * to this new index. If there are no available indexes then -1 is returned.
- * "controller_node" is used to know if this is a real logical drive, or just
- * the controller node, which determines if this counts towards highest_lun.
+ * that has a null drv pointer and allocate the drive info struct and
+ * will return that index This is where new drives will be added.
+ * If the index to be returned is greater than the highest_lun index for
+ * the controller then highest_lun is set * to this new index.
+ * If there are no available indexes or if tha allocation fails, then -1
+ * is returned. * "controller_node" is used to know if this is a real
+ * logical drive, or just the controller node, which determines if this
+ * counts towards highest_lun.
*/
-static int cciss_find_free_drive_index(int ctlr, int controller_node)
+static int cciss_alloc_drive_info(ctlr_info_t *h, int controller_node)
{
int i;
+ drive_info_struct *drv;
+ /* Search for an empty slot for our drive info */
for (i = 0; i < CISS_MAX_LUN; i++) {
- if (hba[ctlr]->drv[i].raid_level == -1) {
- if (i > hba[ctlr]->highest_lun)
- if (!controller_node)
- hba[ctlr]->highest_lun = i;
+
+ /* if not cxd0 case, and it's occupied, skip it. */
+ if (h->drv[i] && i != 0)
+ continue;
+ /*
+ * If it's cxd0 case, and drv is alloc'ed already, and a
+ * disk is configured there, skip it.
+ */
+ if (i == 0 && h->drv[i] && h->drv[i]->raid_level != -1)
+ continue;
+
+ /*
+ * We've found an empty slot. Update highest_lun
+ * provided this isn't just the fake cxd0 controller node.
+ */
+ if (i > h->highest_lun && !controller_node)
+ h->highest_lun = i;
+
+ /* If adding a real disk at cxd0, and it's already alloc'ed */
+ if (i == 0 && h->drv[i] != NULL)
return i;
- }
+
+ /*
+ * Found an empty slot, not already alloc'ed. Allocate it.
+ * Mark it with raid_level == -1, so we know it's new later on.
+ */
+ drv = kzalloc(sizeof(*drv), GFP_KERNEL);
+ if (!drv)
+ return -1;
+ drv->raid_level = -1; /* so we know it's new */
+ h->drv[i] = drv;
+ return i;
}
return -1;
}
+static void cciss_free_drive_info(ctlr_info_t *h, int drv_index)
+{
+ kfree(h->drv[drv_index]);
+ h->drv[drv_index] = NULL;
+}
+
+static void cciss_free_gendisk(ctlr_info_t *h, int drv_index)
+{
+ put_disk(h->gendisk[drv_index]);
+ h->gendisk[drv_index] = NULL;
+}
+
/* cciss_add_gendisk finds a free hba[]->drv structure
* and allocates a gendisk if needed, and sets the lunid
* in the drvinfo structure. It returns the index into
@@ -1824,13 +2042,15 @@ static int cciss_find_free_drive_index(int ctlr, int controller_node)
* a means to talk to the controller in case no logical
* drives have yet been configured.
*/
-static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
+static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[],
+ int controller_node)
{
int drv_index;
- drv_index = cciss_find_free_drive_index(h->ctlr, controller_node);
+ drv_index = cciss_alloc_drive_info(h, controller_node);
if (drv_index == -1)
return -1;
+
/*Check if the gendisk needs to be allocated */
if (!h->gendisk[drv_index]) {
h->gendisk[drv_index] =
@@ -1839,23 +2059,24 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
printk(KERN_ERR "cciss%d: could not "
"allocate a new disk %d\n",
h->ctlr, drv_index);
- return -1;
+ goto err_free_drive_info;
}
}
- h->drv[drv_index].LunID = lunid;
- if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index))
+ memcpy(h->drv[drv_index]->LunID, lunid,
+ sizeof(h->drv[drv_index]->LunID));
+ if (cciss_create_ld_sysfs_entry(h, drv_index))
goto err_free_disk;
-
/* Don't need to mark this busy because nobody */
/* else knows about this disk yet to contend */
/* for access to it. */
- h->drv[drv_index].busy_configuring = 0;
+ h->drv[drv_index]->busy_configuring = 0;
wmb();
return drv_index;
err_free_disk:
- put_disk(h->gendisk[drv_index]);
- h->gendisk[drv_index] = NULL;
+ cciss_free_gendisk(h, drv_index);
+err_free_drive_info:
+ cciss_free_drive_info(h, drv_index);
return -1;
}
@@ -1872,21 +2093,25 @@ static void cciss_add_controller_node(ctlr_info_t *h)
if (h->gendisk[0] != NULL) /* already did this? Then bail. */
return;
- drv_index = cciss_add_gendisk(h, 0, 1);
- if (drv_index == -1) {
- printk(KERN_WARNING "cciss%d: could not "
- "add disk 0.\n", h->ctlr);
- return;
- }
- h->drv[drv_index].block_size = 512;
- h->drv[drv_index].nr_blocks = 0;
- h->drv[drv_index].heads = 0;
- h->drv[drv_index].sectors = 0;
- h->drv[drv_index].cylinders = 0;
- h->drv[drv_index].raid_level = -1;
- memset(h->drv[drv_index].serial_no, 0, 16);
+ drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1);
+ if (drv_index == -1)
+ goto error;
+ h->drv[drv_index]->block_size = 512;
+ h->drv[drv_index]->nr_blocks = 0;
+ h->drv[drv_index]->heads = 0;
+ h->drv[drv_index]->sectors = 0;
+ h->drv[drv_index]->cylinders = 0;
+ h->drv[drv_index]->raid_level = -1;
+ memset(h->drv[drv_index]->serial_no, 0, 16);
disk = h->gendisk[drv_index];
- cciss_add_disk(h, disk, drv_index);
+ if (cciss_add_disk(h, disk, drv_index) == 0)
+ return;
+ cciss_free_gendisk(h, drv_index);
+ cciss_free_drive_info(h, drv_index);
+error:
+ printk(KERN_WARNING "cciss%d: could not "
+ "add disk 0.\n", h->ctlr);
+ return;
}
/* This function will add and remove logical drives from the Logical
@@ -1897,7 +2122,8 @@ static void cciss_add_controller_node(ctlr_info_t *h)
* INPUT
* h = The controller to perform the operations on
*/
-static int rebuild_lun_table(ctlr_info_t *h, int first_time)
+static int rebuild_lun_table(ctlr_info_t *h, int first_time,
+ int via_ioctl)
{
int ctlr = h->ctlr;
int num_luns;
@@ -1907,7 +2133,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
int i;
int drv_found;
int drv_index = 0;
- __u32 lunid = 0;
+ unsigned char lunid[8] = CTLR_LUNID;
unsigned long flags;
if (!capable(CAP_SYS_RAWIO))
@@ -1960,13 +2186,13 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
drv_found = 0;
/* skip holes in the array from already deleted drives */
- if (h->drv[i].raid_level == -1)
+ if (h->drv[i] == NULL)
continue;
for (j = 0; j < num_luns; j++) {
- memcpy(&lunid, &ld_buff->LUN[j][0], 4);
- lunid = le32_to_cpu(lunid);
- if (h->drv[i].LunID == lunid) {
+ memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid));
+ if (memcmp(h->drv[i]->LunID, lunid,
+ sizeof(lunid)) == 0) {
drv_found = 1;
break;
}
@@ -1974,11 +2200,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
if (!drv_found) {
/* Deregister it from the OS, it's gone. */
spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
- h->drv[i].busy_configuring = 1;
+ h->drv[i]->busy_configuring = 1;
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
- return_code = deregister_disk(h, i, 1);
- cciss_destroy_ld_sysfs_entry(&h->drv[i]);
- h->drv[i].busy_configuring = 0;
+ return_code = deregister_disk(h, i, 1, via_ioctl);
+ if (h->drv[i] != NULL)
+ h->drv[i]->busy_configuring = 0;
}
}
@@ -1992,17 +2218,16 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
drv_found = 0;
- memcpy(&lunid, &ld_buff->LUN[i][0], 4);
- lunid = le32_to_cpu(lunid);
-
+ memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid));
/* Find if the LUN is already in the drive array
* of the driver. If so then update its info
* if not in use. If it does not exist then find
* the first free index and add it.
*/
for (j = 0; j <= h->highest_lun; j++) {
- if (h->drv[j].raid_level != -1 &&
- h->drv[j].LunID == lunid) {
+ if (h->drv[j] != NULL &&
+ memcmp(h->drv[j]->LunID, lunid,
+ sizeof(h->drv[j]->LunID)) == 0) {
drv_index = j;
drv_found = 1;
break;
@@ -2015,7 +2240,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
if (drv_index == -1)
goto freeret;
}
- cciss_update_drive_info(ctlr, drv_index, first_time);
+ cciss_update_drive_info(ctlr, drv_index, first_time,
+ via_ioctl);
} /* end for */
freeret:
@@ -2032,6 +2258,25 @@ mem_msg:
goto freeret;
}
+static void cciss_clear_drive_info(drive_info_struct *drive_info)
+{
+ /* zero out the disk size info */
+ drive_info->nr_blocks = 0;
+ drive_info->block_size = 0;
+ drive_info->heads = 0;
+ drive_info->sectors = 0;
+ drive_info->cylinders = 0;
+ drive_info->raid_level = -1;
+ memset(drive_info->serial_no, 0, sizeof(drive_info->serial_no));
+ memset(drive_info->model, 0, sizeof(drive_info->model));
+ memset(drive_info->rev, 0, sizeof(drive_info->rev));
+ memset(drive_info->vendor, 0, sizeof(drive_info->vendor));
+ /*
+ * don't clear the LUNID though, we need to remember which
+ * one this one is.
+ */
+}
+
/* This function will deregister the disk and it's queue from the
* kernel. It must be called with the controller lock held and the
* drv structures busy_configuring flag set. It's parameters are:
@@ -2046,43 +2291,48 @@ mem_msg:
* the disk in preparation for re-adding it. In this case
* the highest_lun should be left unchanged and the LunID
* should not be cleared.
+ * via_ioctl
+ * This indicates whether we've reached this path via ioctl.
+ * This affects the maximum usage count allowed for c0d0 to be messed with.
+ * If this path is reached via ioctl(), then the max_usage_count will
+ * be 1, as the process calling ioctl() has got to have the device open.
+ * If we get here via sysfs, then the max usage count will be zero.
*/
static int deregister_disk(ctlr_info_t *h, int drv_index,
- int clear_all)
+ int clear_all, int via_ioctl)
{
int i;
struct gendisk *disk;
drive_info_struct *drv;
+ int recalculate_highest_lun;
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
- drv = &h->drv[drv_index];
+ drv = h->drv[drv_index];
disk = h->gendisk[drv_index];
/* make sure logical volume is NOT is use */
if (clear_all || (h->gendisk[0] == disk)) {
- if (drv->usage_count > 1)
+ if (drv->usage_count > via_ioctl)
return -EBUSY;
} else if (drv->usage_count > 0)
return -EBUSY;
+ recalculate_highest_lun = (drv == h->drv[h->highest_lun]);
+
/* invalidate the devices and deregister the disk. If it is disk
* zero do not deregister it but just zero out it's values. This
* allows us to delete disk zero but keep the controller registered.
*/
if (h->gendisk[0] != disk) {
struct request_queue *q = disk->queue;
- if (disk->flags & GENHD_FL_UP)
+ if (disk->flags & GENHD_FL_UP) {
+ cciss_destroy_ld_sysfs_entry(h, drv_index, 0);
del_gendisk(disk);
- if (q) {
- blk_cleanup_queue(q);
- /* Set drv->queue to NULL so that we do not try
- * to call blk_start_queue on this queue in the
- * interrupt handler
- */
- drv->queue = NULL;
}
+ if (q)
+ blk_cleanup_queue(q);
/* If clear_all is set then we are deleting the logical
* drive, not just refreshing its info. For drives
* other than disk 0 we will call put_disk. We do not
@@ -2105,34 +2355,20 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
}
} else {
set_capacity(disk, 0);
+ cciss_clear_drive_info(drv);
}
--h->num_luns;
- /* zero out the disk size info */
- drv->nr_blocks = 0;
- drv->block_size = 0;
- drv->heads = 0;
- drv->sectors = 0;
- drv->cylinders = 0;
- drv->raid_level = -1; /* This can be used as a flag variable to
- * indicate that this element of the drive
- * array is free.
- */
-
- if (clear_all) {
- /* check to see if it was the last disk */
- if (drv == h->drv + h->highest_lun) {
- /* if so, find the new hightest lun */
- int i, newhighest = -1;
- for (i = 0; i <= h->highest_lun; i++) {
- /* if the disk has size > 0, it is available */
- if (h->drv[i].heads)
- newhighest = i;
- }
- h->highest_lun = newhighest;
- }
- drv->LunID = 0;
+ /* if it was the last disk, find the new hightest lun */
+ if (clear_all && recalculate_highest_lun) {
+ int i, newhighest = -1;
+ for (i = 0; i <= h->highest_lun; i++) {
+ /* if the disk has size > 0, it is available */
+ if (h->drv[i] && h->drv[i]->heads)
+ newhighest = i;
+ }
+ h->highest_lun = newhighest;
}
return 0;
}
@@ -2479,8 +2715,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
} else { /* Get geometry failed */
printk(KERN_WARNING "cciss: reading geometry failed\n");
}
- printk(KERN_INFO " heads=%d, sectors=%d, cylinders=%d\n\n",
- drv->heads, drv->sectors, drv->cylinders);
}
static void
@@ -2514,9 +2748,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
*total_size = 0;
*block_size = BLOCK_SIZE;
}
- if (*total_size != 0)
- printk(KERN_INFO " blocks= %llu block_size= %d\n",
- (unsigned long long)*total_size+1, *block_size);
kfree(buf);
}
@@ -2568,7 +2799,8 @@ static int cciss_revalidate(struct gendisk *disk)
InquiryData_struct *inq_buff = NULL;
for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
- if (h->drv[logvol].LunID == drv->LunID) {
+ if (memcmp(h->drv[logvol]->LunID, drv->LunID,
+ sizeof(drv->LunID)) == 0) {
FOUND = 1;
break;
}
@@ -3053,8 +3285,7 @@ static void do_cciss_request(struct request_queue *q)
/* The first 2 bits are reserved for controller error reporting. */
c->Header.Tag.lower = (c->cmdindex << 3);
c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
- c->Header.LUN.LogDev.VolId = drv->LunID;
- c->Header.LUN.LogDev.Mode = 1;
+ memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID));
c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
c->Request.Type.Type = TYPE_CMD; // It is a command.
c->Request.Type.Attribute = ATTR_SIMPLE;
@@ -3232,20 +3463,121 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
return IRQ_HANDLED;
}
+/**
+ * add_to_scan_list() - add controller to rescan queue
+ * @h: Pointer to the controller.
+ *
+ * Adds the controller to the rescan queue if not already on the queue.
+ *
+ * returns 1 if added to the queue, 0 if skipped (could be on the
+ * queue already, or the controller could be initializing or shutting
+ * down).
+ **/
+static int add_to_scan_list(struct ctlr_info *h)
+{
+ struct ctlr_info *test_h;
+ int found = 0;
+ int ret = 0;
+
+ if (h->busy_initializing)
+ return 0;
+
+ if (!mutex_trylock(&h->busy_shutting_down))
+ return 0;
+
+ mutex_lock(&scan_mutex);
+ list_for_each_entry(test_h, &scan_q, scan_list) {
+ if (test_h == h) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found && !h->busy_scanning) {
+ INIT_COMPLETION(h->scan_wait);
+ list_add_tail(&h->scan_list, &scan_q);
+ ret = 1;
+ }
+ mutex_unlock(&scan_mutex);
+ mutex_unlock(&h->busy_shutting_down);
+
+ return ret;
+}
+
+/**
+ * remove_from_scan_list() - remove controller from rescan queue
+ * @h: Pointer to the controller.
+ *
+ * Removes the controller from the rescan queue if present. Blocks if
+ * the controller is currently conducting a rescan.
+ **/
+static void remove_from_scan_list(struct ctlr_info *h)
+{
+ struct ctlr_info *test_h, *tmp_h;
+ int scanning = 0;
+
+ mutex_lock(&scan_mutex);
+ list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) {
+ if (test_h == h) {
+ list_del(&h->scan_list);
+ complete_all(&h->scan_wait);
+ mutex_unlock(&scan_mutex);
+ return;
+ }
+ }
+ if (&h->busy_scanning)
+ scanning = 0;
+ mutex_unlock(&scan_mutex);
+
+ if (scanning)
+ wait_for_completion(&h->scan_wait);
+}
+
+/**
+ * scan_thread() - kernel thread used to rescan controllers
+ * @data: Ignored.
+ *
+ * A kernel thread used scan for drive topology changes on
+ * controllers. The thread processes only one controller at a time
+ * using a queue. Controllers are added to the queue using
+ * add_to_scan_list() and removed from the queue either after done
+ * processing or using remove_from_scan_list().
+ *
+ * returns 0.
+ **/
static int scan_thread(void *data)
{
- ctlr_info_t *h = data;
- int rc;
- DECLARE_COMPLETION_ONSTACK(wait);
- h->rescan_wait = &wait;
+ struct ctlr_info *h;
- for (;;) {
- rc = wait_for_completion_interruptible(&wait);
+ while (1) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
if (kthread_should_stop())
break;
- if (!rc)
- rebuild_lun_table(h, 0);
+
+ while (1) {
+ mutex_lock(&scan_mutex);
+ if (list_empty(&scan_q)) {
+ mutex_unlock(&scan_mutex);
+ break;
+ }
+
+ h = list_entry(scan_q.next,
+ struct ctlr_info,
+ scan_list);
+ list_del(&h->scan_list);
+ h->busy_scanning = 1;
+ mutex_unlock(&scan_mutex);
+
+ if (h) {
+ rebuild_lun_table(h, 0, 0);
+ complete_all(&h->scan_wait);
+ mutex_lock(&scan_mutex);
+ h->busy_scanning = 0;
+ mutex_unlock(&scan_mutex);
+ }
+ }
}
+
return 0;
}
@@ -3268,8 +3600,8 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
case REPORT_LUNS_CHANGED:
printk(KERN_WARNING "cciss%d: report LUN data "
"changed\n", h->ctlr);
- if (h->rescan_wait)
- complete(h->rescan_wait);
+ add_to_scan_list(h);
+ wake_up_process(cciss_scan_thread);
return 1;
break;
case POWER_OR_RESET:
@@ -3489,7 +3821,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
if (scratchpad == CCISS_FIRMWARE_READY)
break;
set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ / 10); /* wait 100ms */
+ schedule_timeout(msecs_to_jiffies(100)); /* wait 100ms */
}
if (scratchpad != CCISS_FIRMWARE_READY) {
printk(KERN_WARNING "cciss: Board not ready. Timed out.\n");
@@ -3615,7 +3947,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
break;
/* delay and try again */
set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(10);
+ schedule_timeout(msecs_to_jiffies(1));
}
#ifdef CCISS_DEBUG
@@ -3669,15 +4001,16 @@ Enomem:
return -1;
}
-static void free_hba(int i)
+static void free_hba(int n)
{
- ctlr_info_t *p = hba[i];
- int n;
+ ctlr_info_t *h = hba[n];
+ int i;
- hba[i] = NULL;
- for (n = 0; n < CISS_MAX_LUN; n++)
- put_disk(p->gendisk[n]);
- kfree(p);
+ hba[n] = NULL;
+ for (i = 0; i < h->highest_lun + 1; i++)
+ if (h->gendisk[i] != NULL)
+ put_disk(h->gendisk[i]);
+ kfree(h);
}
/* Send a message CDB to the firmware. */
@@ -3918,6 +4251,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->busy_initializing = 1;
INIT_HLIST_HEAD(&hba[i]->cmpQ);
INIT_HLIST_HEAD(&hba[i]->reqQ);
+ mutex_init(&hba[i]->busy_shutting_down);
if (cciss_pci_init(hba[i], pdev) != 0)
goto clean0;
@@ -3926,6 +4260,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->ctlr = i;
hba[i]->pdev = pdev;
+ init_completion(&hba[i]->scan_wait);
+
if (cciss_create_hba_sysfs_entry(hba[i]))
goto clean0;
@@ -4001,8 +4337,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->num_luns = 0;
hba[i]->highest_lun = -1;
for (j = 0; j < CISS_MAX_LUN; j++) {
- hba[i]->drv[j].raid_level = -1;
- hba[i]->drv[j].queue = NULL;
+ hba[i]->drv[j] = NULL;
hba[i]->gendisk[j] = NULL;
}
@@ -4035,14 +4370,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->cciss_max_sectors = 2048;
+ rebuild_lun_table(hba[i], 1, 0);
hba[i]->busy_initializing = 0;
-
- rebuild_lun_table(hba[i], 1);
- hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i],
- "cciss_scan%02d", i);
- if (IS_ERR(hba[i]->cciss_scan_thread))
- return PTR_ERR(hba[i]->cciss_scan_thread);
-
return 1;
clean4:
@@ -4063,12 +4392,7 @@ clean1:
cciss_destroy_hba_sysfs_entry(hba[i]);
clean0:
hba[i]->busy_initializing = 0;
- /* cleanup any queues that may have been initialized */
- for (j=0; j <= hba[i]->highest_lun; j++){
- drive_info_struct *drv = &(hba[i]->drv[j]);
- if (drv->queue)
- blk_cleanup_queue(drv->queue);
- }
+
/*
* Deliberately omit pci_disable_device(): it does something nasty to
* Smart Array controllers that pci_enable_device does not undo
@@ -4125,8 +4449,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
return;
}
- kthread_stop(hba[i]->cciss_scan_thread);
+ mutex_lock(&hba[i]->busy_shutting_down);
+ remove_from_scan_list(hba[i]);
remove_proc_entry(hba[i]->devname, proc_cciss);
unregister_blkdev(hba[i]->major, hba[i]->devname);
@@ -4136,8 +4461,10 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
if (disk) {
struct request_queue *q = disk->queue;
- if (disk->flags & GENHD_FL_UP)
+ if (disk->flags & GENHD_FL_UP) {
+ cciss_destroy_ld_sysfs_entry(hba[i], j, 1);
del_gendisk(disk);
+ }
if (q)
blk_cleanup_queue(q);
}
@@ -4170,6 +4497,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
cciss_destroy_hba_sysfs_entry(hba[i]);
+ mutex_unlock(&hba[i]->busy_shutting_down);
free_hba(i);
}
@@ -4202,15 +4530,25 @@ static int __init cciss_init(void)
if (err)
return err;
+ /* Start the scan thread */
+ cciss_scan_thread = kthread_run(scan_thread, NULL, "cciss_scan");
+ if (IS_ERR(cciss_scan_thread)) {
+ err = PTR_ERR(cciss_scan_thread);
+ goto err_bus_unregister;
+ }
+
/* Register for our PCI devices */
err = pci_register_driver(&cciss_pci_driver);
if (err)
- goto err_bus_register;
+ goto err_thread_stop;
- return 0;
+ return err;
-err_bus_register:
+err_thread_stop:
+ kthread_stop(cciss_scan_thread);
+err_bus_unregister:
bus_unregister(&cciss_bus_type);
+
return err;
}
@@ -4227,6 +4565,7 @@ static void __exit cciss_cleanup(void)
cciss_remove_one(hba[i]->pdev);
}
}
+ kthread_stop(cciss_scan_thread);
remove_proc_entry("driver/cciss", NULL);
bus_unregister(&cciss_bus_type);
}
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 06a5db25b29..31524cf42c7 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -2,6 +2,7 @@
#define CCISS_H
#include <linux/genhd.h>
+#include <linux/mutex.h>
#include "cciss_cmd.h"
@@ -29,7 +30,7 @@ struct access_method {
};
typedef struct _drive_info_struct
{
- __u32 LunID;
+ unsigned char LunID[8];
int usage_count;
struct request_queue *queue;
sector_t nr_blocks;
@@ -51,6 +52,7 @@ typedef struct _drive_info_struct
char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */
char model[MODEL_LEN + 1]; /* SCSI model string */
char rev[REV_LEN + 1]; /* SCSI revision string */
+ char device_initialized; /* indicates whether dev is initialized */
} drive_info_struct;
struct ctlr_info
@@ -86,7 +88,7 @@ struct ctlr_info
BYTE cciss_read_capacity;
// information about each logical volume
- drive_info_struct drv[CISS_MAX_LUN];
+ drive_info_struct *drv[CISS_MAX_LUN];
struct access_method access;
@@ -108,6 +110,8 @@ struct ctlr_info
int nr_frees;
int busy_configuring;
int busy_initializing;
+ int busy_scanning;
+ struct mutex busy_shutting_down;
/* This element holds the zero based queue number of the last
* queue to be started. It is used for fairness.
@@ -122,8 +126,8 @@ struct ctlr_info
/* and saved for later processing */
#endif
unsigned char alive;
- struct completion *rescan_wait;
- struct task_struct *cciss_scan_thread;
+ struct list_head scan_list;
+ struct completion scan_wait;
struct device dev;
};
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index b82d438e260..6422651ec36 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -32,6 +32,7 @@
#include <linux/blkpg.h>
#include <linux/timer.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/hdreg.h>
#include <linux/spinlock.h>
@@ -177,7 +178,6 @@ static int cpqarray_register_ctlr(int ctlr, struct pci_dev *pdev);
#ifdef CONFIG_PROC_FS
static void ida_procinit(int i);
-static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
#else
static void ida_procinit(int i) {}
#endif
@@ -206,6 +206,7 @@ static const struct block_device_operations ida_fops = {
#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *proc_array;
+static const struct file_operations ida_proc_fops;
/*
* Get us a file in /proc/array that says something about each controller.
@@ -218,19 +219,16 @@ static void __init ida_procinit(int i)
if (!proc_array) return;
}
- create_proc_read_entry(hba[i]->devname, 0, proc_array,
- ida_proc_get_info, hba[i]);
+ proc_create_data(hba[i]->devname, 0, proc_array, &ida_proc_fops, hba[i]);
}
/*
* Report information about this controller.
*/
-static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+static int ida_proc_show(struct seq_file *m, void *v)
{
- off_t pos = 0;
- off_t len = 0;
- int size, i, ctlr;
- ctlr_info_t *h = (ctlr_info_t*)data;
+ int i, ctlr;
+ ctlr_info_t *h = (ctlr_info_t*)m->private;
drv_info_t *drv;
#ifdef CPQ_PROC_PRINT_QUEUES
cmdlist_t *c;
@@ -238,7 +236,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
#endif
ctlr = h->ctlr;
- size = sprintf(buffer, "%s: Compaq %s Controller\n"
+ seq_printf(m, "%s: Compaq %s Controller\n"
" Board ID: 0x%08lx\n"
" Firmware Revision: %c%c%c%c\n"
" Controller Sig: 0x%08lx\n"
@@ -258,55 +256,54 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
h->log_drives, h->phys_drives,
h->Qdepth, h->maxQsinceinit);
- pos += size; len += size;
-
- size = sprintf(buffer+len, "Logical Drive Info:\n");
- pos += size; len += size;
+ seq_puts(m, "Logical Drive Info:\n");
for(i=0; i<h->log_drives; i++) {
drv = &h->drv[i];
- size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
+ seq_printf(m, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
ctlr, i, drv->blk_size, drv->nr_blks);
- pos += size; len += size;
}
#ifdef CPQ_PROC_PRINT_QUEUES
spin_lock_irqsave(IDA_LOCK(h->ctlr), flags);
- size = sprintf(buffer+len, "\nCurrent Queues:\n");
- pos += size; len += size;
+ seq_puts(m, "\nCurrent Queues:\n");
c = h->reqQ;
- size = sprintf(buffer+len, "reqQ = %p", c); pos += size; len += size;
+ seq_printf(m, "reqQ = %p", c);
if (c) c=c->next;
while(c && c != h->reqQ) {
- size = sprintf(buffer+len, "->%p", c);
- pos += size; len += size;
+ seq_printf(m, "->%p", c);
c=c->next;
}
c = h->cmpQ;
- size = sprintf(buffer+len, "\ncmpQ = %p", c); pos += size; len += size;
+ seq_printf(m, "\ncmpQ = %p", c);
if (c) c=c->next;
while(c && c != h->cmpQ) {
- size = sprintf(buffer+len, "->%p", c);
- pos += size; len += size;
+ seq_printf(m, "->%p", c);
c=c->next;
}
- size = sprintf(buffer+len, "\n"); pos += size; len += size;
+ seq_putc(m, '\n');
spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags);
#endif
- size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n",
+ seq_printf(m, "nr_allocs = %d\nnr_frees = %d\n",
h->nr_allocs, h->nr_frees);
- pos += size; len += size;
-
- *eof = 1;
- *start = buffer+offset;
- len -= offset;
- if (len>length)
- len = length;
- return len;
+ return 0;
+}
+
+static int ida_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ida_proc_show, PDE(inode)->data);
}
+
+static const struct file_operations ida_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ida_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
#endif /* CONFIG_PROC_FS */
module_param_array(eisa, int, NULL, 0);
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index 60ab75104da..1c129211302 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -217,7 +217,7 @@ static const struct agp_bridge_driver parisc_agp_driver = {
.configure = parisc_agp_configure,
.fetch_size = parisc_agp_fetch_size,
.tlb_flush = parisc_agp_tlbflush,
- .mask_memory = parisc_agp_page_mask_memory,
+ .mask_memory = parisc_agp_mask_memory,
.masks = parisc_agp_masks,
.agp_enable = parisc_agp_enable,
.cache_flush = global_cache_flush,
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index aaca40283be..4f568cb9af3 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -393,7 +393,7 @@ static int apm_open(struct inode * inode, struct file * filp)
return as ? 0 : -ENOMEM;
}
-static struct file_operations apm_bios_fops = {
+static const struct file_operations apm_bios_fops = {
.owner = THIS_MODULE,
.read = apm_read,
.poll = apm_poll,
diff --git a/drivers/char/bfin-otp.c b/drivers/char/bfin-otp.c
index e3dd24bff51..836d4f0a876 100644
--- a/drivers/char/bfin-otp.c
+++ b/drivers/char/bfin-otp.c
@@ -217,7 +217,7 @@ static long bfin_otp_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
# define bfin_otp_ioctl NULL
#endif
-static struct file_operations bfin_otp_fops = {
+static const struct file_operations bfin_otp_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = bfin_otp_ioctl,
.read = bfin_otp_read,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index df5038bbcbc..4254457d391 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -3354,7 +3354,7 @@ static int __init cy_detect_isa(void)
continue;
}
#ifdef MODULE
- if (isparam && irq[i])
+ if (isparam && i < NR_CARDS && irq[i])
cy_isa_irq = irq[i];
else
#endif
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 52e06589821..045c930e632 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -56,6 +56,7 @@
#include <linux/errno.h> /* for -EBUSY */
#include <linux/ioport.h> /* for request_region */
#include <linux/delay.h> /* for loops_per_jiffy */
+#include <linux/sched.h>
#include <linux/smp_lock.h> /* cycle_kernel_lock() */
#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
#include <asm/uaccess.h> /* for get_user, etc. */
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 41fc11dc921..65545de3dbf 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -36,6 +36,7 @@
#include <linux/errno.h>
#include <asm/system.h>
#include <linux/poll.h>
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/ipmi.h>
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 09050797c76..ec5e3f8df64 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -35,6 +35,7 @@
#include <linux/errno.h>
#include <asm/system.h>
#include <linux/poll.h>
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/slab.h>
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 5942a9d674c..452370af95d 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -220,8 +220,7 @@ static inline int serial_paranoia_check(struct cyclades_port *info, char *name,
return 1;
}
- if ((long)info < (long)(&cy_port[0])
- || (long)(&cy_port[NR_PORTS]) < (long)info) {
+ if (info < &cy_port[0] || info >= &cy_port[NR_PORTS]) {
printk("Warning: cyclades_port out of range for (%s) in %s\n",
name, routine);
return 1;
@@ -520,15 +519,13 @@ static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id)
panic("TxInt on debug port!!!");
}
#endif
-
- info = &cy_port[channel];
-
/* validate the port number (as configured and open) */
if ((channel < 0) || (NR_PORTS <= channel)) {
base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
base_addr[CyTEOIR] = CyNOTRANS;
return IRQ_HANDLED;
}
+ info = &cy_port[channel];
info->last_active = jiffies;
if (info->tty == 0) {
base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 45d58002b06..47c2d276345 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -696,8 +696,7 @@ int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
cmd.header.in = pcrread_header;
cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
- BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE);
- rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
+ rc = transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
"attempting to read a pcr value");
if (rc == 0)
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index aafdbaebc16..feb55075819 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -518,7 +518,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
static int tty_ldisc_halt(struct tty_struct *tty)
{
clear_bit(TTY_LDISC, &tty->flags);
- return cancel_delayed_work(&tty->buf.work);
+ return cancel_delayed_work_sync(&tty->buf.work);
}
/**
@@ -756,12 +756,9 @@ void tty_ldisc_hangup(struct tty_struct *tty)
* N_TTY.
*/
if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
- /* Make sure the old ldisc is quiescent */
- tty_ldisc_halt(tty);
- flush_scheduled_work();
-
/* Avoid racing set_ldisc or tty_ldisc_release */
mutex_lock(&tty->ldisc_mutex);
+ tty_ldisc_halt(tty);
if (tty->ldisc) { /* Not yet closed */
/* Switch back to N_TTY */
tty_ldisc_reinit(tty);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 29c651ab0d7..6b36ee56e6f 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -981,8 +981,10 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
goto eperm;
if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
- sizeof(struct vt_setactivate)))
- return -EFAULT;
+ sizeof(struct vt_setactivate))) {
+ ret = -EFAULT;
+ goto out;
+ }
if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
ret = -ENXIO;
else {
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index f40ab699860..4846d50199f 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -559,7 +559,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
return status;
}
-static struct file_operations hwicap_fops = {
+static const struct file_operations hwicap_fops = {
.owner = THIS_MODULE,
.write = hwicap_write,
.read = hwicap_read,
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index abf4a2529f8..60697909ebd 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -227,7 +227,8 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
* cn_proc_mcast_ctl
* @data: message sent from userspace via the connector
*/
-static void cn_proc_mcast_ctl(struct cn_msg *msg)
+static void cn_proc_mcast_ctl(struct cn_msg *msg,
+ struct netlink_skb_parms *nsp)
{
enum proc_cn_mcast_op *mc_op = NULL;
int err = 0;
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index 4a1dfe1f4ba..210338ea222 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -78,18 +78,20 @@ void cn_queue_wrapper(struct work_struct *work)
struct cn_callback_entry *cbq =
container_of(work, struct cn_callback_entry, work);
struct cn_callback_data *d = &cbq->data;
+ struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb));
+ struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb);
- d->callback(d->callback_priv);
+ d->callback(msg, nsp);
- d->destruct_data(d->ddata);
- d->ddata = NULL;
+ kfree_skb(d->skb);
+ d->skb = NULL;
kfree(d->free);
}
static struct cn_callback_entry *
cn_queue_alloc_callback_entry(char *name, struct cb_id *id,
- void (*callback)(struct cn_msg *))
+ void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
{
struct cn_callback_entry *cbq;
@@ -123,7 +125,7 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
}
int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id,
- void (*callback)(struct cn_msg *))
+ void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
{
struct cn_callback_entry *cbq, *__cbq;
int found = 0;
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 74f52af7956..f06024668f9 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -129,21 +129,19 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
/*
* Callback helper - queues work and setup destructor for given data.
*/
-static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data)
+static int cn_call_callback(struct sk_buff *skb)
{
struct cn_callback_entry *__cbq, *__new_cbq;
struct cn_dev *dev = &cdev;
+ struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb));
int err = -ENODEV;
spin_lock_bh(&dev->cbdev->queue_lock);
list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
if (likely(!work_pending(&__cbq->work) &&
- __cbq->data.ddata == NULL)) {
- __cbq->data.callback_priv = msg;
-
- __cbq->data.ddata = data;
- __cbq->data.destruct_data = destruct_data;
+ __cbq->data.skb == NULL)) {
+ __cbq->data.skb = skb;
if (queue_cn_work(__cbq, &__cbq->work))
err = 0;
@@ -156,10 +154,8 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
if (__new_cbq) {
d = &__new_cbq->data;
- d->callback_priv = msg;
+ d->skb = skb;
d->callback = __cbq->data.callback;
- d->ddata = data;
- d->destruct_data = destruct_data;
d->free = __new_cbq;
__new_cbq->pdev = __cbq->pdev;
@@ -191,7 +187,6 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
*/
static void cn_rx_skb(struct sk_buff *__skb)
{
- struct cn_msg *msg;
struct nlmsghdr *nlh;
int err;
struct sk_buff *skb;
@@ -208,8 +203,7 @@ static void cn_rx_skb(struct sk_buff *__skb)
return;
}
- msg = NLMSG_DATA(nlh);
- err = cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
+ err = cn_call_callback(skb);
if (err < 0)
kfree_skb(skb);
}
@@ -270,7 +264,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
* May sleep.
*/
int cn_add_callback(struct cb_id *id, char *name,
- void (*callback)(struct cn_msg *))
+ void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
{
int err;
struct cn_dev *dev = &cdev;
@@ -352,7 +346,7 @@ static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
*
* Used for notification of a request's processing.
*/
-static void cn_callback(struct cn_msg *msg)
+static void cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
struct cn_ctl_msg *ctl;
struct cn_ctl_entry *ent;
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 02127e59fe8..55c9c59b3f7 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -47,6 +47,18 @@ config EDAC_DEBUG_VERBOSE
Source file name and line number where debugging message
printed will be added to debugging message.
+ config EDAC_DECODE_MCE
+ tristate "Decode MCEs in human-readable form (only on AMD for now)"
+ depends on CPU_SUP_AMD && X86_MCE
+ default y
+ ---help---
+ Enable this option if you want to decode Machine Check Exceptions
+ occuring on your machine in human-readable form.
+
+ You should definitely say Y here in case you want to decode MCEs
+ which occur really early upon boot, before the module infrastructure
+ has been initialized.
+
config EDAC_MM_EDAC
tristate "Main Memory EDAC (Error Detection And Correction) reporting"
help
@@ -59,7 +71,7 @@ config EDAC_MM_EDAC
config EDAC_AMD64
tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
- depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && CPU_SUP_AMD
+ depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
help
Support for error detection and correction on the AMD 64
Families of Memory Controllers (K8, F10h and F11h)
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 7a473bbe8ab..bc5dc232a0f 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -6,7 +6,6 @@
# GNU General Public License.
#
-
obj-$(CONFIG_EDAC) := edac_stub.o
obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
@@ -17,9 +16,7 @@ ifdef CONFIG_PCI
edac_core-objs += edac_pci.o edac_pci_sysfs.o
endif
-ifdef CONFIG_CPU_SUP_AMD
-edac_core-objs += edac_mce_amd.o
-endif
+obj-$(CONFIG_EDAC_DECODE_MCE) += edac_mce_amd.o
obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o
obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 4e551e63b6d..4f4ac82382f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -15,8 +15,8 @@ module_param(ecc_enable_override, int, 0644);
/* Lookup table for all possible MC control instances */
struct amd64_pvt;
-static struct mem_ctl_info *mci_lookup[MAX_NUMNODES];
-static struct amd64_pvt *pvt_lookup[MAX_NUMNODES];
+static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
+static struct amd64_pvt *pvt_lookup[EDAC_MAX_NUMNODES];
/*
* See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
@@ -189,7 +189,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
/* Map from a CSROW entry to the mask entry that operates on it */
static inline u32 amd64_map_to_dcs_mask(struct amd64_pvt *pvt, int csrow)
{
- return csrow >> (pvt->num_dcsm >> 3);
+ if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F)
+ return csrow;
+ else
+ return csrow >> 1;
}
/* return the 'base' address the i'th CS entry of the 'dct' DRAM controller */
@@ -279,29 +282,26 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
intlv_en = pvt->dram_IntlvEn[0];
if (intlv_en == 0) {
- for (node_id = 0; ; ) {
+ for (node_id = 0; node_id < DRAM_REG_COUNT; node_id++) {
if (amd64_base_limit_match(pvt, sys_addr, node_id))
- break;
-
- if (++node_id >= DRAM_REG_COUNT)
- goto err_no_match;
+ goto found;
}
- goto found;
+ goto err_no_match;
}
- if (unlikely((intlv_en != (0x01 << 8)) &&
- (intlv_en != (0x03 << 8)) &&
- (intlv_en != (0x07 << 8)))) {
+ if (unlikely((intlv_en != 0x01) &&
+ (intlv_en != 0x03) &&
+ (intlv_en != 0x07))) {
amd64_printk(KERN_WARNING, "junk value of 0x%x extracted from "
"IntlvEn field of DRAM Base Register for node 0: "
- "This probably indicates a BIOS bug.\n", intlv_en);
+ "this probably indicates a BIOS bug.\n", intlv_en);
return NULL;
}
bits = (((u32) sys_addr) >> 12) & intlv_en;
for (node_id = 0; ; ) {
- if ((pvt->dram_limit[node_id] & intlv_en) == bits)
+ if ((pvt->dram_IntlvSel[node_id] & intlv_en) == bits)
break; /* intlv_sel field matches */
if (++node_id >= DRAM_REG_COUNT)
@@ -311,10 +311,10 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
/* sanity test for sys_addr */
if (unlikely(!amd64_base_limit_match(pvt, sys_addr, node_id))) {
amd64_printk(KERN_WARNING,
- "%s(): sys_addr 0x%lx falls outside base/limit "
- "address range for node %d with node interleaving "
- "enabled.\n", __func__, (unsigned long)sys_addr,
- node_id);
+ "%s(): sys_addr 0x%llx falls outside base/limit "
+ "address range for node %d with node interleaving "
+ "enabled.\n",
+ __func__, sys_addr, node_id);
return NULL;
}
@@ -377,7 +377,7 @@ static int input_addr_to_csrow(struct mem_ctl_info *mci, u64 input_addr)
* base/mask register pair, test the condition shown near the start of
* section 3.5.4 (p. 84, BKDG #26094, K8, revA-E).
*/
- for (csrow = 0; csrow < CHIPSELECT_COUNT; csrow++) {
+ for (csrow = 0; csrow < pvt->cs_count; csrow++) {
/* This DRAM chip select is disabled on this node */
if ((pvt->dcsb0[csrow] & K8_DCSB_CS_ENABLE) == 0)
@@ -734,7 +734,7 @@ static void find_csrow_limits(struct mem_ctl_info *mci, int csrow,
u64 base, mask;
pvt = mci->pvt_info;
- BUG_ON((csrow < 0) || (csrow >= CHIPSELECT_COUNT));
+ BUG_ON((csrow < 0) || (csrow >= pvt->cs_count));
base = base_from_dct_base(pvt, csrow);
mask = mask_from_dct_mask(pvt, csrow);
@@ -962,35 +962,27 @@ err_reg:
*/
static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt)
{
- if (pvt->ext_model >= OPTERON_CPU_REV_F) {
+
+ if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F) {
+ pvt->dcsb_base = REV_E_DCSB_BASE_BITS;
+ pvt->dcsm_mask = REV_E_DCSM_MASK_BITS;
+ pvt->dcs_mask_notused = REV_E_DCS_NOTUSED_BITS;
+ pvt->dcs_shift = REV_E_DCS_SHIFT;
+ pvt->cs_count = 8;
+ pvt->num_dcsm = 8;
+ } else {
pvt->dcsb_base = REV_F_F1Xh_DCSB_BASE_BITS;
pvt->dcsm_mask = REV_F_F1Xh_DCSM_MASK_BITS;
pvt->dcs_mask_notused = REV_F_F1Xh_DCS_NOTUSED_BITS;
pvt->dcs_shift = REV_F_F1Xh_DCS_SHIFT;
- switch (boot_cpu_data.x86) {
- case 0xf:
- pvt->num_dcsm = REV_F_DCSM_COUNT;
- break;
-
- case 0x10:
- pvt->num_dcsm = F10_DCSM_COUNT;
- break;
-
- case 0x11:
- pvt->num_dcsm = F11_DCSM_COUNT;
- break;
-
- default:
- amd64_printk(KERN_ERR, "Unsupported family!\n");
- break;
+ if (boot_cpu_data.x86 == 0x11) {
+ pvt->cs_count = 4;
+ pvt->num_dcsm = 2;
+ } else {
+ pvt->cs_count = 8;
+ pvt->num_dcsm = 4;
}
- } else {
- pvt->dcsb_base = REV_E_DCSB_BASE_BITS;
- pvt->dcsm_mask = REV_E_DCSM_MASK_BITS;
- pvt->dcs_mask_notused = REV_E_DCS_NOTUSED_BITS;
- pvt->dcs_shift = REV_E_DCS_SHIFT;
- pvt->num_dcsm = REV_E_DCSM_COUNT;
}
}
@@ -1003,7 +995,7 @@ static void amd64_read_dct_base_mask(struct amd64_pvt *pvt)
amd64_set_dct_base_and_mask(pvt);
- for (cs = 0; cs < CHIPSELECT_COUNT; cs++) {
+ for (cs = 0; cs < pvt->cs_count; cs++) {
reg = K8_DCSB0 + (cs * 4);
err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
&pvt->dcsb0[cs]);
@@ -1130,7 +1122,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
debugf0("Reading K8_DRAM_BASE_LOW failed\n");
/* Extract parts into separate data entries */
- pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8;
+ pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 24;
pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
pvt->dram_rw_en[dram] = (low & 0x3);
@@ -1143,7 +1135,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
* Extract parts into separate data entries. Limit is the HIGHEST memory
* location of the region, so lower 24 bits need to be all ones
*/
- pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 8) | 0x00FFFFFF;
+ pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 24) | 0x00FFFFFF;
pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7;
pvt->dram_DstNode[dram] = (low & 0x7);
}
@@ -1193,7 +1185,7 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
* different from the node that detected the error.
*/
src_mci = find_mc_by_sys_addr(mci, SystemAddress);
- if (src_mci) {
+ if (!src_mci) {
amd64_mc_printk(mci, KERN_ERR,
"failed to map error address 0x%lx to a node\n",
(unsigned long)SystemAddress);
@@ -1376,8 +1368,8 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7;
- pvt->dram_base[dram] = (((((u64) high_base & 0x000000FF) << 32) |
- ((u64) low_base & 0xFFFF0000))) << 8;
+ pvt->dram_base[dram] = (((u64)high_base & 0x000000FF) << 40) |
+ (((u64)low_base & 0xFFFF0000) << 24);
low_offset = K8_DRAM_LIMIT_LOW + (dram << 3);
high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
@@ -1398,9 +1390,9 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
* Extract address values and form a LIMIT address. Limit is the HIGHEST
* memory location of the region, so low 24 bits need to be all ones.
*/
- low_limit |= 0x0000FFFF;
- pvt->dram_limit[dram] =
- ((((u64) high_limit << 32) + (u64) low_limit) << 8) | (0xFF);
+ pvt->dram_limit[dram] = (((u64)high_limit & 0x000000FF) << 40) |
+ (((u64) low_limit & 0xFFFF0000) << 24) |
+ 0x00FFFFFF;
}
static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
@@ -1566,7 +1558,7 @@ static int f10_lookup_addr_in_dct(u32 in_addr, u32 nid, u32 cs)
debugf1("InputAddr=0x%x channelselect=%d\n", in_addr, cs);
- for (csrow = 0; csrow < CHIPSELECT_COUNT; csrow++) {
+ for (csrow = 0; csrow < pvt->cs_count; csrow++) {
cs_base = amd64_get_dct_base(pvt, cs, csrow);
if (!(cs_base & K8_DCSB_CS_ENABLE))
@@ -2497,7 +2489,7 @@ err_reg:
* NOTE: CPU Revision Dependent code
*
* Input:
- * @csrow_nr ChipSelect Row Number (0..CHIPSELECT_COUNT-1)
+ * @csrow_nr ChipSelect Row Number (0..pvt->cs_count-1)
* k8 private pointer to -->
* DRAM Bank Address mapping register
* node_id
@@ -2577,7 +2569,7 @@ static int amd64_init_csrows(struct mem_ctl_info *mci)
(pvt->nbcfg & K8_NBCFG_ECC_ENABLE) ? "Enabled" : "Disabled"
);
- for (i = 0; i < CHIPSELECT_COUNT; i++) {
+ for (i = 0; i < pvt->cs_count; i++) {
csrow = &mci->csrows[i];
if ((pvt->dcsb0[i] & K8_DCSB_CS_ENABLE) == 0) {
@@ -2988,7 +2980,7 @@ static int amd64_init_2nd_stage(struct amd64_pvt *pvt)
goto err_exit;
ret = -ENOMEM;
- mci = edac_mc_alloc(0, CHIPSELECT_COUNT, pvt->channel_count, node_id);
+ mci = edac_mc_alloc(0, pvt->cs_count, pvt->channel_count, node_id);
if (!mci)
goto err_exit;
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 8ea07e2715d..c6f359a8520 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -132,6 +132,8 @@
#define EDAC_AMD64_VERSION " Ver: 3.2.0 " __DATE__
#define EDAC_MOD_STR "amd64_edac"
+#define EDAC_MAX_NUMNODES 8
+
/* Extended Model from CPUID, for CPU Revision numbers */
#define OPTERON_CPU_LE_REV_C 0
#define OPTERON_CPU_REV_D 1
@@ -142,7 +144,7 @@
#define OPTERON_CPU_REV_FA 5
/* Hardware limit on ChipSelect rows per MC and processors per system */
-#define CHIPSELECT_COUNT 8
+#define MAX_CS_COUNT 8
#define DRAM_REG_COUNT 8
@@ -193,7 +195,6 @@
*/
#define REV_E_DCSB_BASE_BITS (0xFFE0FE00ULL)
#define REV_E_DCS_SHIFT 4
-#define REV_E_DCSM_COUNT 8
#define REV_F_F1Xh_DCSB_BASE_BITS (0x1FF83FE0ULL)
#define REV_F_F1Xh_DCS_SHIFT 8
@@ -204,9 +205,6 @@
*/
#define REV_F_DCSB_BASE_BITS (0x1FF83FE0ULL)
#define REV_F_DCS_SHIFT 8
-#define REV_F_DCSM_COUNT 4
-#define F10_DCSM_COUNT 4
-#define F11_DCSM_COUNT 2
/* DRAM CS Mask Registers */
#define K8_DCSM0 0x60
@@ -374,13 +372,11 @@ enum {
#define SET_NB_DRAM_INJECTION_WRITE(word, bits) \
(BIT(((word) & 0xF) + 20) | \
- BIT(17) | \
- ((bits) & 0xF))
+ BIT(17) | bits)
#define SET_NB_DRAM_INJECTION_READ(word, bits) \
(BIT(((word) & 0xF) + 20) | \
- BIT(16) | \
- ((bits) & 0xF))
+ BIT(16) | bits)
#define K8_NBCAP 0xE8
#define K8_NBCAP_CORES (BIT(12)|BIT(13))
@@ -445,12 +441,12 @@ struct amd64_pvt {
u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */
/* DRAM CS Base Address Registers F2x[1,0][5C:40] */
- u32 dcsb0[CHIPSELECT_COUNT];
- u32 dcsb1[CHIPSELECT_COUNT];
+ u32 dcsb0[MAX_CS_COUNT];
+ u32 dcsb1[MAX_CS_COUNT];
/* DRAM CS Mask Registers F2x[1,0][6C:60] */
- u32 dcsm0[CHIPSELECT_COUNT];
- u32 dcsm1[CHIPSELECT_COUNT];
+ u32 dcsm0[MAX_CS_COUNT];
+ u32 dcsm1[MAX_CS_COUNT];
/*
* Decoded parts of DRAM BASE and LIMIT Registers
@@ -470,6 +466,7 @@ struct amd64_pvt {
*/
u32 dcsb_base; /* DCSB base bits */
u32 dcsm_mask; /* DCSM mask bits */
+ u32 cs_count; /* num chip selects (== num DCSB registers) */
u32 num_dcsm; /* Number of DCSM registers */
u32 dcs_mask_notused; /* DCSM notused mask bits */
u32 dcs_shift; /* DCSB and DCSM shift value */
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c
index d3675b76b3a..29f1f7a612d 100644
--- a/drivers/edac/amd64_edac_inj.c
+++ b/drivers/edac/amd64_edac_inj.c
@@ -1,5 +1,11 @@
#include "amd64_edac.h"
+static ssize_t amd64_inject_section_show(struct mem_ctl_info *mci, char *buf)
+{
+ struct amd64_pvt *pvt = mci->pvt_info;
+ return sprintf(buf, "0x%x\n", pvt->injection.section);
+}
+
/*
* store error injection section value which refers to one of 4 16-byte sections
* within a 64-byte cacheline
@@ -15,12 +21,26 @@ static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci,
ret = strict_strtoul(data, 10, &value);
if (ret != -EINVAL) {
+
+ if (value > 3) {
+ amd64_printk(KERN_WARNING,
+ "%s: invalid section 0x%lx\n",
+ __func__, value);
+ return -EINVAL;
+ }
+
pvt->injection.section = (u32) value;
return count;
}
return ret;
}
+static ssize_t amd64_inject_word_show(struct mem_ctl_info *mci, char *buf)
+{
+ struct amd64_pvt *pvt = mci->pvt_info;
+ return sprintf(buf, "0x%x\n", pvt->injection.word);
+}
+
/*
* store error injection word value which refers to one of 9 16-bit word of the
* 16-byte (128-bit + ECC bits) section
@@ -37,14 +57,25 @@ static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci,
ret = strict_strtoul(data, 10, &value);
if (ret != -EINVAL) {
- value = (value <= 8) ? value : 0;
- pvt->injection.word = (u32) value;
+ if (value > 8) {
+ amd64_printk(KERN_WARNING,
+ "%s: invalid word 0x%lx\n",
+ __func__, value);
+ return -EINVAL;
+ }
+ pvt->injection.word = (u32) value;
return count;
}
return ret;
}
+static ssize_t amd64_inject_ecc_vector_show(struct mem_ctl_info *mci, char *buf)
+{
+ struct amd64_pvt *pvt = mci->pvt_info;
+ return sprintf(buf, "0x%x\n", pvt->injection.bit_map);
+}
+
/*
* store 16 bit error injection vector which enables injecting errors to the
* corresponding bit within the error injection word above. When used during a
@@ -60,8 +91,14 @@ static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci,
ret = strict_strtoul(data, 16, &value);
if (ret != -EINVAL) {
- pvt->injection.bit_map = (u32) value & 0xFFFF;
+ if (value & 0xFFFF0000) {
+ amd64_printk(KERN_WARNING,
+ "%s: invalid EccVector: 0x%lx\n",
+ __func__, value);
+ return -EINVAL;
+ }
+ pvt->injection.bit_map = (u32) value;
return count;
}
return ret;
@@ -147,7 +184,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
.name = "inject_section",
.mode = (S_IRUGO | S_IWUSR)
},
- .show = NULL,
+ .show = amd64_inject_section_show,
.store = amd64_inject_section_store,
},
{
@@ -155,7 +192,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
.name = "inject_word",
.mode = (S_IRUGO | S_IWUSR)
},
- .show = NULL,
+ .show = amd64_inject_word_show,
.store = amd64_inject_word_store,
},
{
@@ -163,7 +200,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
.name = "inject_ecc_vector",
.mode = (S_IRUGO | S_IWUSR)
},
- .show = NULL,
+ .show = amd64_inject_ecc_vector_show,
.store = amd64_inject_ecc_vector_store,
},
{
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 0c21c370c9d..713ed7d3724 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -3,6 +3,7 @@
static bool report_gart_errors;
static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
+static void (*orig_mce_callback)(struct mce *m);
void amd_report_gart_errors(bool v)
{
@@ -362,7 +363,7 @@ static inline void amd_decode_err_code(unsigned int ec)
pr_warning("Huh? Unknown MCE error 0x%x\n", ec);
}
-void decode_mce(struct mce *m)
+static void amd_decode_mce(struct mce *m)
{
struct err_regs regs;
int node, ecc;
@@ -420,3 +421,32 @@ void decode_mce(struct mce *m)
amd_decode_err_code(m->status & 0xffff);
}
+
+static int __init mce_amd_init(void)
+{
+ /*
+ * We can decode MCEs for Opteron and later CPUs:
+ */
+ if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
+ (boot_cpu_data.x86 >= 0xf)) {
+ /* safe the default decode mce callback */
+ orig_mce_callback = x86_mce_decode_callback;
+
+ x86_mce_decode_callback = amd_decode_mce;
+ }
+
+ return 0;
+}
+early_initcall(mce_amd_init);
+
+#ifdef MODULE
+static void __exit mce_amd_exit(void)
+{
+ x86_mce_decode_callback = orig_mce_callback;
+}
+
+MODULE_DESCRIPTION("AMD MCE decoder");
+MODULE_ALIAS("edac-mce-amd");
+MODULE_LICENSE("GPL");
+module_exit(mce_amd_exit);
+#endif
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index ced186d7e9a..5089331544e 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -33,6 +33,7 @@
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/preempt.h>
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/time.h>
#include <linux/uaccess.h>
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 420a96e7f2d..051d1ebbd28 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -939,7 +939,7 @@ static int __init ibft_init(void)
if (ibft_addr) {
printk(KERN_INFO "iBFT detected at 0x%llx.\n",
- (u64)virt_to_phys((void *)ibft_addr));
+ (u64)isa_virt_to_bus(ibft_addr));
rc = ibft_check_device();
if (rc)
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index d53fbbfefa3..dfb15c06c88 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -65,10 +65,10 @@ void __init reserve_ibft_region(void)
* so skip that area */
if (pos == VGA_MEM)
pos += VGA_SIZE;
- virt = phys_to_virt(pos);
+ virt = isa_bus_to_virt(pos);
if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) {
unsigned long *addr =
- (unsigned long *)phys_to_virt(pos + 4);
+ (unsigned long *)isa_bus_to_virt(pos + 4);
len = *addr;
/* if the length of the table extends past 1M,
* the table cannot be valid. */
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index bb11a429394..662ed923d9e 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1487,7 +1487,7 @@ static int gpiolib_open(struct inode *inode, struct file *file)
return single_open(file, gpiolib_show, NULL);
}
-static struct file_operations gpiolib_operations = {
+static const struct file_operations gpiolib_operations = {
.open = gpiolib_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 8e7b0ebece0..5cae0b3eee9 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1556,8 +1556,6 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
struct drm_crtc *crtc;
int ret = 0;
- DRM_DEBUG_KMS("\n");
-
if (!req->flags) {
DRM_ERROR("no operation set\n");
return -EINVAL;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 819ddcbfcce..23dc9c115fd 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -454,6 +454,96 @@ out_free:
}
EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
+static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
+ u16 blue, u16 regno, struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_framebuffer *fb = fb_helper->fb;
+ int pindex;
+
+ pindex = regno;
+
+ if (fb->bits_per_pixel == 16) {
+ pindex = regno << 3;
+
+ if (fb->depth == 16 && regno > 63)
+ return;
+ if (fb->depth == 15 && regno > 31)
+ return;
+
+ if (fb->depth == 16) {
+ u16 r, g, b;
+ int i;
+ if (regno < 32) {
+ for (i = 0; i < 8; i++)
+ fb_helper->funcs->gamma_set(crtc, red,
+ green, blue, pindex + i);
+ }
+
+ fb_helper->funcs->gamma_get(crtc, &r,
+ &g, &b,
+ pindex >> 1);
+
+ for (i = 0; i < 4; i++)
+ fb_helper->funcs->gamma_set(crtc, r,
+ green, b,
+ (pindex >> 1) + i);
+ }
+ }
+
+ if (fb->depth != 16)
+ fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
+
+ if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ ((u32 *) fb->pseudo_palette)[regno] =
+ (regno << info->var.red.offset) |
+ (regno << info->var.green.offset) |
+ (regno << info->var.blue.offset);
+ }
+}
+
+int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_device *dev = fb_helper->dev;
+ u16 *red, *green, *blue, *transp;
+ struct drm_crtc *crtc;
+ int i, rc = 0;
+ int start;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ for (i = 0; i < fb_helper->crtc_count; i++) {
+ if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
+ break;
+ }
+ if (i == fb_helper->crtc_count)
+ continue;
+
+ red = cmap->red;
+ green = cmap->green;
+ blue = cmap->blue;
+ transp = cmap->transp;
+ start = cmap->start;
+
+ for (i = 0; i < cmap->len; i++) {
+ u16 hred, hgreen, hblue, htransp = 0xffff;
+
+ hred = *red++;
+ hgreen = *green++;
+ hblue = *blue++;
+
+ if (transp)
+ htransp = *transp++;
+
+ setcolreg(crtc, hred, hgreen, hblue, start++, info);
+ }
+ crtc_funcs->load_lut(crtc);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(drm_fb_helper_setcmap);
+
int drm_fb_helper_setcolreg(unsigned regno,
unsigned red,
unsigned green,
@@ -466,9 +556,11 @@ int drm_fb_helper_setcolreg(unsigned regno,
struct drm_crtc *crtc;
int i;
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- struct drm_framebuffer *fb = fb_helper->fb;
+ if (regno > 255)
+ return 1;
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
for (i = 0; i < fb_helper->crtc_count; i++) {
if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
break;
@@ -476,35 +568,9 @@ int drm_fb_helper_setcolreg(unsigned regno,
if (i == fb_helper->crtc_count)
continue;
- if (regno > 255)
- return 1;
-
- if (fb->depth == 8) {
- fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
- return 0;
- }
- if (regno < 16) {
- switch (fb->depth) {
- case 15:
- fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
- ((green & 0xf800) >> 6) |
- ((blue & 0xf800) >> 11);
- break;
- case 16:
- fb->pseudo_palette[regno] = (red & 0xf800) |
- ((green & 0xfc00) >> 5) |
- ((blue & 0xf800) >> 11);
- break;
- case 24:
- case 32:
- fb->pseudo_palette[regno] =
- (((red >> 8) & 0xff) << info->var.red.offset) |
- (((green >> 8) & 0xff) << info->var.green.offset) |
- (((blue >> 8) & 0xff) << info->var.blue.offset);
- break;
- }
- }
+ setcolreg(crtc, red, green, blue, regno, info);
+ crtc_funcs->load_lut(crtc);
}
return 0;
}
@@ -674,6 +740,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
EXPORT_SYMBOL(drm_fb_helper_pan_display);
int drm_fb_helper_single_fb_probe(struct drm_device *dev,
+ int preferred_bpp,
int (*fb_create)(struct drm_device *dev,
uint32_t fb_width,
uint32_t fb_height,
@@ -696,6 +763,11 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
struct drm_fb_helper *fb_helper;
uint32_t surface_depth = 24, surface_bpp = 32;
+ /* if driver picks 8 or 16 by default use that
+ for both depth/bpp */
+ if (preferred_bpp != surface_bpp) {
+ surface_depth = surface_bpp = preferred_bpp;
+ }
/* first up get a count of crtcs now in use and new min/maxes width/heights */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
@@ -851,10 +923,12 @@ void drm_fb_helper_free(struct drm_fb_helper *helper)
}
EXPORT_SYMBOL(drm_fb_helper_free);
-void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch)
+void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
+ uint32_t depth)
{
info->fix.type = FB_TYPE_PACKED_PIXELS;
- info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
+ FB_VISUAL_DIRECTCOLOR;
info->fix.type_aux = 0;
info->fix.xpanstep = 1; /* doing it in hw */
info->fix.ypanstep = 1; /* doing it in hw */
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 45d507ebd3f..92aeb918e0c 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1468,6 +1468,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
spin_lock_init(&dev_priv->user_irq_lock);
spin_lock_init(&dev_priv->error_lock);
dev_priv->user_irq_refcount = 0;
+ dev_priv->trace_irq_seqno = 0;
ret = drm_vblank_init(dev, I915_NUM_PIPE);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b24b2d145b7..6035d3dae85 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -202,6 +202,7 @@ typedef struct drm_i915_private {
spinlock_t user_irq_lock;
/** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
int user_irq_refcount;
+ u32 trace_irq_seqno;
/** Cached value of IMR to avoid reads in updating the bitfield */
u32 irq_mask_reg;
u32 pipestat[2];
@@ -665,6 +666,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
extern int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void i915_user_irq_get(struct drm_device *dev);
+void i915_trace_irq_get(struct drm_device *dev, u32 seqno);
void i915_user_irq_put(struct drm_device *dev);
extern void i915_enable_interrupt (struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 40727d4c291..abfc27b0c2e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1770,7 +1770,7 @@ i915_gem_retire_requests(struct drm_device *dev)
drm_i915_private_t *dev_priv = dev->dev_private;
uint32_t seqno;
- if (!dev_priv->hw_status_page)
+ if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list))
return;
seqno = i915_get_gem_seqno(dev);
@@ -1794,6 +1794,12 @@ i915_gem_retire_requests(struct drm_device *dev)
} else
break;
}
+
+ if (unlikely (dev_priv->trace_irq_seqno &&
+ i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) {
+ i915_user_irq_put(dev);
+ dev_priv->trace_irq_seqno = 0;
+ }
}
void
@@ -3352,7 +3358,7 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev,
exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
exec_len = (uint32_t) exec->batch_len;
- trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno);
+ trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1);
count = nbox ? nbox : 1;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4dfeec7cdd4..c3ceffa46ea 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -725,6 +725,16 @@ void i915_user_irq_put(struct drm_device *dev)
spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
}
+void i915_trace_irq_get(struct drm_device *dev, u32 seqno)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+ if (dev_priv->trace_irq_seqno == 0)
+ i915_user_irq_get(dev);
+
+ dev_priv->trace_irq_seqno = seqno;
+}
+
static int i915_wait_irq(struct drm_device * dev, int irq_nr)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 5567a40816f..01840d9bc38 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -158,16 +158,17 @@ TRACE_EVENT(i915_gem_request_submit,
TP_ARGS(dev, seqno),
TP_STRUCT__entry(
- __field(struct drm_device *, dev)
+ __field(u32, dev)
__field(u32, seqno)
),
TP_fast_assign(
- __entry->dev = dev;
+ __entry->dev = dev->primary->index;
__entry->seqno = seqno;
+ i915_trace_irq_get(dev, seqno);
),
- TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno)
+ TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
);
TRACE_EVENT(i915_gem_request_flush,
@@ -178,20 +179,20 @@ TRACE_EVENT(i915_gem_request_flush,
TP_ARGS(dev, seqno, flush_domains, invalidate_domains),
TP_STRUCT__entry(
- __field(struct drm_device *, dev)
+ __field(u32, dev)
__field(u32, seqno)
__field(u32, flush_domains)
__field(u32, invalidate_domains)
),
TP_fast_assign(
- __entry->dev = dev;
+ __entry->dev = dev->primary->index;
__entry->seqno = seqno;
__entry->flush_domains = flush_domains;
__entry->invalidate_domains = invalidate_domains;
),
- TP_printk("dev=%p, seqno=%u, flush=%04x, invalidate=%04x",
+ TP_printk("dev=%u, seqno=%u, flush=%04x, invalidate=%04x",
__entry->dev, __entry->seqno,
__entry->flush_domains, __entry->invalidate_domains)
);
@@ -204,16 +205,16 @@ TRACE_EVENT(i915_gem_request_complete,
TP_ARGS(dev, seqno),
TP_STRUCT__entry(
- __field(struct drm_device *, dev)
+ __field(u32, dev)
__field(u32, seqno)
),
TP_fast_assign(
- __entry->dev = dev;
+ __entry->dev = dev->primary->index;
__entry->seqno = seqno;
),
- TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno)
+ TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
);
TRACE_EVENT(i915_gem_request_retire,
@@ -223,16 +224,16 @@ TRACE_EVENT(i915_gem_request_retire,
TP_ARGS(dev, seqno),
TP_STRUCT__entry(
- __field(struct drm_device *, dev)
+ __field(u32, dev)
__field(u32, seqno)
),
TP_fast_assign(
- __entry->dev = dev;
+ __entry->dev = dev->primary->index;
__entry->seqno = seqno;
),
- TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno)
+ TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
);
TRACE_EVENT(i915_gem_request_wait_begin,
@@ -242,16 +243,16 @@ TRACE_EVENT(i915_gem_request_wait_begin,
TP_ARGS(dev, seqno),
TP_STRUCT__entry(
- __field(struct drm_device *, dev)
+ __field(u32, dev)
__field(u32, seqno)
),
TP_fast_assign(
- __entry->dev = dev;
+ __entry->dev = dev->primary->index;
__entry->seqno = seqno;
),
- TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno)
+ TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
);
TRACE_EVENT(i915_gem_request_wait_end,
@@ -261,16 +262,16 @@ TRACE_EVENT(i915_gem_request_wait_end,
TP_ARGS(dev, seqno),
TP_STRUCT__entry(
- __field(struct drm_device *, dev)
+ __field(u32, dev)
__field(u32, seqno)
),
TP_fast_assign(
- __entry->dev = dev;
+ __entry->dev = dev->primary->index;
__entry->seqno = seqno;
),
- TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno)
+ TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
);
TRACE_EVENT(i915_ring_wait_begin,
@@ -280,14 +281,14 @@ TRACE_EVENT(i915_ring_wait_begin,
TP_ARGS(dev),
TP_STRUCT__entry(
- __field(struct drm_device *, dev)
+ __field(u32, dev)
),
TP_fast_assign(
- __entry->dev = dev;
+ __entry->dev = dev->primary->index;
),
- TP_printk("dev=%p", __entry->dev)
+ TP_printk("dev=%u", __entry->dev)
);
TRACE_EVENT(i915_ring_wait_end,
@@ -297,14 +298,14 @@ TRACE_EVENT(i915_ring_wait_end,
TP_ARGS(dev),
TP_STRUCT__entry(
- __field(struct drm_device *, dev)
+ __field(u32, dev)
),
TP_fast_assign(
- __entry->dev = dev;
+ __entry->dev = dev->primary->index;
),
- TP_printk("dev=%p", __entry->dev)
+ TP_printk("dev=%u", __entry->dev)
);
#endif /* _I915_TRACE_H_ */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 93ff6c03733..3c14240cc00 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3095,7 +3095,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
struct drm_gem_object *bo;
struct drm_i915_gem_object *obj_priv;
int pipe = intel_crtc->pipe;
- int plane = intel_crtc->plane;
uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
uint32_t temp = I915_READ(control);
@@ -3182,9 +3181,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
drm_gem_object_unreference(intel_crtc->cursor_bo);
}
- if ((IS_I965G(dev) || plane == 0))
- intel_update_fbc(crtc, &crtc->mode);
-
mutex_unlock(&dev->struct_mutex);
intel_crtc->cursor_addr = addr;
@@ -3244,6 +3240,16 @@ void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
intel_crtc->lut_b[regno] = blue >> 8;
}
+void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ *red = intel_crtc->lut_r[regno] << 8;
+ *green = intel_crtc->lut_g[regno] << 8;
+ *blue = intel_crtc->lut_b[regno] << 8;
+}
+
static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size)
{
@@ -3835,6 +3841,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
.mode_set_base = intel_pipe_set_base,
.prepare = intel_crtc_prepare,
.commit = intel_crtc_commit,
+ .load_lut = intel_crtc_load_lut,
};
static const struct drm_crtc_funcs intel_crtc_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8aa4b7f30da..ef61fe9507e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -175,6 +175,8 @@ extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc);
extern void intelfb_restore(void);
extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno);
+extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno);
extern int intel_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd *mode_cmd,
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index e85d7e9eed7..2b0fe54cd92 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -60,10 +60,12 @@ static struct fb_ops intelfb_ops = {
.fb_imageblit = cfb_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
+ .fb_setcmap = drm_fb_helper_setcmap,
};
static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
.gamma_set = intel_crtc_fb_gamma_set,
+ .gamma_get = intel_crtc_fb_gamma_get,
};
@@ -123,6 +125,10 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
struct device *device = &dev->pdev->dev;
int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1;
+ /* we don't do packed 24bpp */
+ if (surface_bpp == 24)
+ surface_bpp = 32;
+
mode_cmd.width = surface_width;
mode_cmd.height = surface_height;
@@ -206,7 +212,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
// memset(info->screen_base, 0, size);
- drm_fb_helper_fill_fix(info, fb->pitch);
+ drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
/* FIXME: we really shouldn't expose mmio space at all */
@@ -244,7 +250,7 @@ int intelfb_probe(struct drm_device *dev)
int ret;
DRM_DEBUG("\n");
- ret = drm_fb_helper_single_fb_probe(dev, intelfb_create);
+ ret = drm_fb_helper_single_fb_probe(dev, 32, intelfb_create);
return ret;
}
EXPORT_SYMBOL(intelfb_probe);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index fa304e13601..663ab6de0b5 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -223,7 +223,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
connector = &intel_output->base;
drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
- DRM_MODE_CONNECTOR_DVID);
+ DRM_MODE_CONNECTOR_HDMIA);
drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
intel_output->type = INTEL_OUTPUT_HDMI;
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index c64eab493fb..9ca917931af 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1082,7 +1082,8 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
/* Ensure TV refresh is close to desired refresh */
- if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 10)
+ if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
+ < 1000)
return MODE_OK;
return MODE_CLOCK_RANGE;
}
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 6a015929dee..14fa9701aeb 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -733,6 +733,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
.mode_set_base = atombios_crtc_set_base,
.prepare = atombios_crtc_prepare,
.commit = atombios_crtc_commit,
+ .load_lut = radeon_crtc_load_lut,
};
void radeon_atombios_init_crtc(struct drm_device *dev,
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index e6cce24de80..161094c07d9 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -32,6 +32,9 @@
#include "radeon_reg.h"
#include "radeon.h"
#include "r100d.h"
+#include "rs100d.h"
+#include "rv200d.h"
+#include "rv250d.h"
#include <linux/firmware.h>
#include <linux/platform_device.h>
@@ -60,18 +63,7 @@ MODULE_FIRMWARE(FIRMWARE_R520);
/* This files gather functions specifics to:
* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
- *
- * Some of these functions might be used by newer ASICs.
*/
-int r200_init(struct radeon_device *rdev);
-void r100_hdp_reset(struct radeon_device *rdev);
-void r100_gpu_init(struct radeon_device *rdev);
-int r100_gui_wait_for_idle(struct radeon_device *rdev);
-int r100_mc_wait_for_idle(struct radeon_device *rdev);
-void r100_gpu_wait_for_vsync(struct radeon_device *rdev);
-void r100_gpu_wait_for_vsync2(struct radeon_device *rdev);
-int r100_debugfs_mc_info_init(struct radeon_device *rdev);
-
/*
* PCI GART
@@ -152,136 +144,6 @@ void r100_pci_gart_fini(struct radeon_device *rdev)
radeon_gart_fini(rdev);
}
-
-/*
- * MC
- */
-void r100_mc_disable_clients(struct radeon_device *rdev)
-{
- uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl;
-
- /* FIXME: is this function correct for rs100,rs200,rs300 ? */
- if (r100_gui_wait_for_idle(rdev)) {
- printk(KERN_WARNING "Failed to wait GUI idle while "
- "programming pipes. Bad things might happen.\n");
- }
-
- /* stop display and memory access */
- ov0_scale_cntl = RREG32(RADEON_OV0_SCALE_CNTL);
- WREG32(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
- crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
- WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
- crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL);
-
- r100_gpu_wait_for_vsync(rdev);
-
- WREG32(RADEON_CRTC_GEN_CNTL,
- (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) |
- RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
-
- if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
- crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
-
- r100_gpu_wait_for_vsync2(rdev);
- WREG32(RADEON_CRTC2_GEN_CNTL,
- (crtc2_gen_cntl &
- ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) |
- RADEON_CRTC2_DISP_REQ_EN_B);
- }
-
- udelay(500);
-}
-
-void r100_mc_setup(struct radeon_device *rdev)
-{
- uint32_t tmp;
- int r;
-
- r = r100_debugfs_mc_info_init(rdev);
- if (r) {
- DRM_ERROR("Failed to register debugfs file for R100 MC !\n");
- }
- /* Write VRAM size in case we are limiting it */
- WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
- /* Novell bug 204882 for RN50/M6/M7 with 8/16/32MB VRAM,
- * if the aperture is 64MB but we have 32MB VRAM
- * we report only 32MB VRAM but we have to set MC_FB_LOCATION
- * to 64MB, otherwise the gpu accidentially dies */
- tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
- tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
- tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
- WREG32(RADEON_MC_FB_LOCATION, tmp);
-
- /* Enable bus mastering */
- tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
- WREG32(RADEON_BUS_CNTL, tmp);
-
- if (rdev->flags & RADEON_IS_AGP) {
- tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
- tmp = REG_SET(RADEON_MC_AGP_TOP, tmp >> 16);
- tmp |= REG_SET(RADEON_MC_AGP_START, rdev->mc.gtt_location >> 16);
- WREG32(RADEON_MC_AGP_LOCATION, tmp);
- WREG32(RADEON_AGP_BASE, rdev->mc.agp_base);
- } else {
- WREG32(RADEON_MC_AGP_LOCATION, 0x0FFFFFFF);
- WREG32(RADEON_AGP_BASE, 0);
- }
-
- tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL;
- tmp |= (7 << 28);
- WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
- (void)RREG32(RADEON_HOST_PATH_CNTL);
- WREG32(RADEON_HOST_PATH_CNTL, tmp);
- (void)RREG32(RADEON_HOST_PATH_CNTL);
-}
-
-int r100_mc_init(struct radeon_device *rdev)
-{
- int r;
-
- if (r100_debugfs_rbbm_init(rdev)) {
- DRM_ERROR("Failed to register debugfs file for RBBM !\n");
- }
-
- r100_gpu_init(rdev);
- /* Disable gart which also disable out of gart access */
- r100_pci_gart_disable(rdev);
-
- /* Setup GPU memory space */
- rdev->mc.gtt_location = 0xFFFFFFFFUL;
- if (rdev->flags & RADEON_IS_AGP) {
- r = radeon_agp_init(rdev);
- if (r) {
- printk(KERN_WARNING "[drm] Disabling AGP\n");
- rdev->flags &= ~RADEON_IS_AGP;
- rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
- } else {
- rdev->mc.gtt_location = rdev->mc.agp_base;
- }
- }
- r = radeon_mc_setup(rdev);
- if (r) {
- return r;
- }
-
- r100_mc_disable_clients(rdev);
- if (r100_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "Failed to wait MC idle while "
- "programming pipes. Bad things might happen.\n");
- }
-
- r100_mc_setup(rdev);
- return 0;
-}
-
-void r100_mc_fini(struct radeon_device *rdev)
-{
-}
-
-
-/*
- * Interrupts
- */
int r100_irq_set(struct radeon_device *rdev)
{
uint32_t tmp = 0;
@@ -358,10 +220,6 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc)
return RREG32(RADEON_CRTC2_CRNT_FRAME);
}
-
-/*
- * Fence emission
- */
void r100_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence)
{
@@ -377,10 +235,6 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
}
-
-/*
- * Writeback
- */
int r100_wb_init(struct radeon_device *rdev)
{
int r;
@@ -504,10 +358,6 @@ int r100_copy_blit(struct radeon_device *rdev,
return r;
}
-
-/*
- * CP
- */
static int r100_cp_wait_for_idle(struct radeon_device *rdev)
{
unsigned i;
@@ -612,6 +462,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
}
return err;
}
+
static void r100_cp_load_microcode(struct radeon_device *rdev)
{
const __be32 *fw_data;
@@ -978,7 +829,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
header = radeon_get_ib_value(p, h_idx);
crtc_id = radeon_get_ib_value(p, h_idx + 5);
- reg = header >> 2;
+ reg = CP_PACKET0_GET_REG(header);
mutex_lock(&p->rdev->ddev->mode_config.mutex);
obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
@@ -1990,7 +1841,7 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
r100_pll_errata_after_data(rdev);
}
-int r100_init(struct radeon_device *rdev)
+void r100_set_safe_registers(struct radeon_device *rdev)
{
if (ASIC_IS_RN50(rdev)) {
rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
@@ -1999,9 +1850,8 @@ int r100_init(struct radeon_device *rdev)
rdev->config.r100.reg_safe_bm = r100_reg_safe_bm;
rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm);
} else {
- return r200_init(rdev);
+ r200_set_safe_registers(rdev);
}
- return 0;
}
/*
@@ -2299,9 +2149,11 @@ void r100_bandwidth_update(struct radeon_device *rdev)
mode1 = &rdev->mode_info.crtcs[0]->base.mode;
pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
}
- if (rdev->mode_info.crtcs[1]->base.enabled) {
- mode2 = &rdev->mode_info.crtcs[1]->base.mode;
- pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
+ if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
+ if (rdev->mode_info.crtcs[1]->base.enabled) {
+ mode2 = &rdev->mode_info.crtcs[1]->base.mode;
+ pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
+ }
}
min_mem_eff.full = rfixed_const_8(0);
@@ -3114,7 +2966,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
WREG32(R_000740_CP_CSQ_CNTL, 0);
/* Save few CRTC registers */
- save->GENMO_WT = RREG32(R_0003C0_GENMO_WT);
+ save->GENMO_WT = RREG8(R_0003C2_GENMO_WT);
save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL);
save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL);
save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET);
@@ -3124,7 +2976,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
}
/* Disable VGA aperture access */
- WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT);
+ WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & save->GENMO_WT);
/* Disable cursor, overlay, crtc */
WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1));
WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL |
@@ -3156,10 +3008,264 @@ void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
rdev->mc.vram_location);
}
/* Restore CRTC registers */
- WREG32(R_0003C0_GENMO_WT, save->GENMO_WT);
+ WREG8(R_0003C2_GENMO_WT, save->GENMO_WT);
WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL);
WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL);
if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL);
}
}
+
+void r100_vga_render_disable(struct radeon_device *rdev)
+{
+ u32 tmp;
+
+ tmp = RREG8(R_0003C2_GENMO_WT);
+ WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp);
+}
+
+static void r100_debugfs(struct radeon_device *rdev)
+{
+ int r;
+
+ r = r100_debugfs_mc_info_init(rdev);
+ if (r)
+ dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n");
+}
+
+static void r100_mc_program(struct radeon_device *rdev)
+{
+ struct r100_mc_save save;
+
+ /* Stops all mc clients */
+ r100_mc_stop(rdev, &save);
+ if (rdev->flags & RADEON_IS_AGP) {
+ WREG32(R_00014C_MC_AGP_LOCATION,
+ S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) |
+ S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
+ WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
+ if (rdev->family > CHIP_RV200)
+ WREG32(R_00015C_AGP_BASE_2,
+ upper_32_bits(rdev->mc.agp_base) & 0xff);
+ } else {
+ WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF);
+ WREG32(R_000170_AGP_BASE, 0);
+ if (rdev->family > CHIP_RV200)
+ WREG32(R_00015C_AGP_BASE_2, 0);
+ }
+ /* Wait for mc idle */
+ if (r100_mc_wait_for_idle(rdev))
+ dev_warn(rdev->dev, "Wait for MC idle timeout.\n");
+ /* Program MC, should be a 32bits limited address space */
+ WREG32(R_000148_MC_FB_LOCATION,
+ S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
+ S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
+ r100_mc_resume(rdev, &save);
+}
+
+void r100_clock_startup(struct radeon_device *rdev)
+{
+ u32 tmp;
+
+ if (radeon_dynclks != -1 && radeon_dynclks)
+ radeon_legacy_set_clock_gating(rdev, 1);
+ /* We need to force on some of the block */
+ tmp = RREG32_PLL(R_00000D_SCLK_CNTL);
+ tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
+ if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280))
+ tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1);
+ WREG32_PLL(R_00000D_SCLK_CNTL, tmp);
+}
+
+static int r100_startup(struct radeon_device *rdev)
+{
+ int r;
+
+ r100_mc_program(rdev);
+ /* Resume clock */
+ r100_clock_startup(rdev);
+ /* Initialize GPU configuration (# pipes, ...) */
+ r100_gpu_init(rdev);
+ /* Initialize GART (initialize after TTM so we can allocate
+ * memory through TTM but finalize after TTM) */
+ if (rdev->flags & RADEON_IS_PCI) {
+ r = r100_pci_gart_enable(rdev);
+ if (r)
+ return r;
+ }
+ /* Enable IRQ */
+ rdev->irq.sw_int = true;
+ r100_irq_set(rdev);
+ /* 1M ring buffer */
+ r = r100_cp_init(rdev, 1024 * 1024);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+ return r;
+ }
+ r = r100_wb_init(rdev);
+ if (r)
+ dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+ r = r100_ib_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+ return r;
+ }
+ return 0;
+}
+
+int r100_resume(struct radeon_device *rdev)
+{
+ /* Make sur GART are not working */
+ if (rdev->flags & RADEON_IS_PCI)
+ r100_pci_gart_disable(rdev);
+ /* Resume clock before doing reset */
+ r100_clock_startup(rdev);
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* post */
+ radeon_combios_asic_init(rdev->ddev);
+ /* Resume clock after posting */
+ r100_clock_startup(rdev);
+ return r100_startup(rdev);
+}
+
+int r100_suspend(struct radeon_device *rdev)
+{
+ r100_cp_disable(rdev);
+ r100_wb_disable(rdev);
+ r100_irq_disable(rdev);
+ if (rdev->flags & RADEON_IS_PCI)
+ r100_pci_gart_disable(rdev);
+ return 0;
+}
+
+void r100_fini(struct radeon_device *rdev)
+{
+ r100_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ radeon_gem_fini(rdev);
+ if (rdev->flags & RADEON_IS_PCI)
+ r100_pci_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_object_fini(rdev);
+ radeon_atombios_fini(rdev);
+ kfree(rdev->bios);
+ rdev->bios = NULL;
+}
+
+int r100_mc_init(struct radeon_device *rdev)
+{
+ int r;
+ u32 tmp;
+
+ /* Setup GPU memory space */
+ rdev->mc.vram_location = 0xFFFFFFFFUL;
+ rdev->mc.gtt_location = 0xFFFFFFFFUL;
+ if (rdev->flags & RADEON_IS_IGP) {
+ tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
+ rdev->mc.vram_location = tmp << 16;
+ }
+ if (rdev->flags & RADEON_IS_AGP) {
+ r = radeon_agp_init(rdev);
+ if (r) {
+ printk(KERN_WARNING "[drm] Disabling AGP\n");
+ rdev->flags &= ~RADEON_IS_AGP;
+ rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+ } else {
+ rdev->mc.gtt_location = rdev->mc.agp_base;
+ }
+ }
+ r = radeon_mc_setup(rdev);
+ if (r)
+ return r;
+ return 0;
+}
+
+int r100_init(struct radeon_device *rdev)
+{
+ int r;
+
+ /* Register debugfs file specific to this group of asics */
+ r100_debugfs(rdev);
+ /* Disable VGA */
+ r100_vga_render_disable(rdev);
+ /* Initialize scratch registers */
+ radeon_scratch_init(rdev);
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* TODO: disable VGA need to use VGA request */
+ /* BIOS*/
+ if (!radeon_get_bios(rdev)) {
+ if (ASIC_IS_AVIVO(rdev))
+ return -EINVAL;
+ }
+ if (rdev->is_atom_bios) {
+ dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
+ return -EINVAL;
+ } else {
+ r = radeon_combios_init(rdev);
+ if (r)
+ return r;
+ }
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev,
+ "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* check if cards are posted or not */
+ if (!radeon_card_posted(rdev) && rdev->bios) {
+ DRM_INFO("GPU not posted. posting now...\n");
+ radeon_combios_asic_init(rdev->ddev);
+ }
+ /* Set asic errata */
+ r100_errata(rdev);
+ /* Initialize clocks */
+ radeon_get_clock_info(rdev->ddev);
+ /* Get vram informations */
+ r100_vram_info(rdev);
+ /* Initialize memory controller (also test AGP) */
+ r = r100_mc_init(rdev);
+ if (r)
+ return r;
+ /* Fence driver */
+ r = radeon_fence_driver_init(rdev);
+ if (r)
+ return r;
+ r = radeon_irq_kms_init(rdev);
+ if (r)
+ return r;
+ /* Memory manager */
+ r = radeon_object_init(rdev);
+ if (r)
+ return r;
+ if (rdev->flags & RADEON_IS_PCI) {
+ r = r100_pci_gart_init(rdev);
+ if (r)
+ return r;
+ }
+ r100_set_safe_registers(rdev);
+ rdev->accel_working = true;
+ r = r100_startup(rdev);
+ if (r) {
+ /* Somethings want wront with the accel init stop accel */
+ dev_err(rdev->dev, "Disabling GPU acceleration\n");
+ r100_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ if (rdev->flags & RADEON_IS_PCI)
+ r100_pci_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rdev->accel_working = false;
+ }
+ return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h
index c4b257ec920..df29a630c46 100644
--- a/drivers/gpu/drm/radeon/r100d.h
+++ b/drivers/gpu/drm/radeon/r100d.h
@@ -381,6 +381,24 @@
#define S_000054_VCRTC_IDX_MASTER(x) (((x) & 0x7F) << 24)
#define G_000054_VCRTC_IDX_MASTER(x) (((x) >> 24) & 0x7F)
#define C_000054_VCRTC_IDX_MASTER 0x80FFFFFF
+#define R_000148_MC_FB_LOCATION 0x000148
+#define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0)
+#define G_000148_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
+#define C_000148_MC_FB_START 0xFFFF0000
+#define S_000148_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
+#define G_000148_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
+#define C_000148_MC_FB_TOP 0x0000FFFF
+#define R_00014C_MC_AGP_LOCATION 0x00014C
+#define S_00014C_MC_AGP_START(x) (((x) & 0xFFFF) << 0)
+#define G_00014C_MC_AGP_START(x) (((x) >> 0) & 0xFFFF)
+#define C_00014C_MC_AGP_START 0xFFFF0000
+#define S_00014C_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16)
+#define G_00014C_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF)
+#define C_00014C_MC_AGP_TOP 0x0000FFFF
+#define R_000170_AGP_BASE 0x000170
+#define S_000170_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_000170_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_000170_AGP_BASE_ADDR 0x00000000
#define R_00023C_DISPLAY_BASE_ADDR 0x00023C
#define S_00023C_DISPLAY_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
#define G_00023C_DISPLAY_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
@@ -403,25 +421,25 @@
#define S_000360_CUR2_LOCK(x) (((x) & 0x1) << 31)
#define G_000360_CUR2_LOCK(x) (((x) >> 31) & 0x1)
#define C_000360_CUR2_LOCK 0x7FFFFFFF
-#define R_0003C0_GENMO_WT 0x0003C0
-#define S_0003C0_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0)
-#define G_0003C0_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1)
-#define C_0003C0_GENMO_MONO_ADDRESS_B 0xFFFFFFFE
-#define S_0003C0_VGA_RAM_EN(x) (((x) & 0x1) << 1)
-#define G_0003C0_VGA_RAM_EN(x) (((x) >> 1) & 0x1)
-#define C_0003C0_VGA_RAM_EN 0xFFFFFFFD
-#define S_0003C0_VGA_CKSEL(x) (((x) & 0x3) << 2)
-#define G_0003C0_VGA_CKSEL(x) (((x) >> 2) & 0x3)
-#define C_0003C0_VGA_CKSEL 0xFFFFFFF3
-#define S_0003C0_ODD_EVEN_MD_PGSEL(x) (((x) & 0x1) << 5)
-#define G_0003C0_ODD_EVEN_MD_PGSEL(x) (((x) >> 5) & 0x1)
-#define C_0003C0_ODD_EVEN_MD_PGSEL 0xFFFFFFDF
-#define S_0003C0_VGA_HSYNC_POL(x) (((x) & 0x1) << 6)
-#define G_0003C0_VGA_HSYNC_POL(x) (((x) >> 6) & 0x1)
-#define C_0003C0_VGA_HSYNC_POL 0xFFFFFFBF
-#define S_0003C0_VGA_VSYNC_POL(x) (((x) & 0x1) << 7)
-#define G_0003C0_VGA_VSYNC_POL(x) (((x) >> 7) & 0x1)
-#define C_0003C0_VGA_VSYNC_POL 0xFFFFFF7F
+#define R_0003C2_GENMO_WT 0x0003C0
+#define S_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0)
+#define G_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1)
+#define C_0003C2_GENMO_MONO_ADDRESS_B 0xFE
+#define S_0003C2_VGA_RAM_EN(x) (((x) & 0x1) << 1)
+#define G_0003C2_VGA_RAM_EN(x) (((x) >> 1) & 0x1)
+#define C_0003C2_VGA_RAM_EN 0xFD
+#define S_0003C2_VGA_CKSEL(x) (((x) & 0x3) << 2)
+#define G_0003C2_VGA_CKSEL(x) (((x) >> 2) & 0x3)
+#define C_0003C2_VGA_CKSEL 0xF3
+#define S_0003C2_ODD_EVEN_MD_PGSEL(x) (((x) & 0x1) << 5)
+#define G_0003C2_ODD_EVEN_MD_PGSEL(x) (((x) >> 5) & 0x1)
+#define C_0003C2_ODD_EVEN_MD_PGSEL 0xDF
+#define S_0003C2_VGA_HSYNC_POL(x) (((x) & 0x1) << 6)
+#define G_0003C2_VGA_HSYNC_POL(x) (((x) >> 6) & 0x1)
+#define C_0003C2_VGA_HSYNC_POL 0xBF
+#define S_0003C2_VGA_VSYNC_POL(x) (((x) & 0x1) << 7)
+#define G_0003C2_VGA_VSYNC_POL(x) (((x) >> 7) & 0x1)
+#define C_0003C2_VGA_VSYNC_POL 0x7F
#define R_0003F8_CRTC2_GEN_CNTL 0x0003F8
#define S_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) & 0x1) << 0)
#define G_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) >> 0) & 0x1)
@@ -545,6 +563,46 @@
#define S_000774_SCRATCH_ADDR(x) (((x) & 0x7FFFFFF) << 5)
#define G_000774_SCRATCH_ADDR(x) (((x) >> 5) & 0x7FFFFFF)
#define C_000774_SCRATCH_ADDR 0x0000001F
+#define R_0007C0_CP_STAT 0x0007C0
+#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
+#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
+#define C_0007C0_MRU_BUSY 0xFFFFFFFE
+#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
+#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
+#define C_0007C0_MWU_BUSY 0xFFFFFFFD
+#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
+#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
+#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
+#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
+#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
+#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
+#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
+#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
+#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
+#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
+#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
+#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
+#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
+#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
+#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
+#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
+#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
+#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
+#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
+#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
+#define C_0007C0_CSI_BUSY 0xFFFFDFFF
+#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
+#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
+#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
+#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
+#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
+#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
+#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
+#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
+#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
+#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
+#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
+#define C_0007C0_CP_BUSY 0x7FFFFFFF
#define R_000E40_RBBM_STATUS 0x000E40
#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
@@ -604,4 +662,53 @@
#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
+
+#define R_00000D_SCLK_CNTL 0x00000D
+#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
+#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7)
+#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8
+#define S_00000D_TCLK_SRC_SEL(x) (((x) & 0x7) << 8)
+#define G_00000D_TCLK_SRC_SEL(x) (((x) >> 8) & 0x7)
+#define C_00000D_TCLK_SRC_SEL 0xFFFFF8FF
+#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16)
+#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1)
+#define C_00000D_FORCE_CP 0xFFFEFFFF
+#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17)
+#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1)
+#define C_00000D_FORCE_HDP 0xFFFDFFFF
+#define S_00000D_FORCE_DISP(x) (((x) & 0x1) << 18)
+#define G_00000D_FORCE_DISP(x) (((x) >> 18) & 0x1)
+#define C_00000D_FORCE_DISP 0xFFFBFFFF
+#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19)
+#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1)
+#define C_00000D_FORCE_TOP 0xFFF7FFFF
+#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
+#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
+#define C_00000D_FORCE_E2 0xFFEFFFFF
+#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21)
+#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1)
+#define C_00000D_FORCE_SE 0xFFDFFFFF
+#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
+#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
+#define C_00000D_FORCE_IDCT 0xFFBFFFFF
+#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23)
+#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1)
+#define C_00000D_FORCE_VIP 0xFF7FFFFF
+#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
+#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
+#define C_00000D_FORCE_RE 0xFEFFFFFF
+#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25)
+#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1)
+#define C_00000D_FORCE_PB 0xFDFFFFFF
+#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26)
+#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1)
+#define C_00000D_FORCE_TAM 0xFBFFFFFF
+#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27)
+#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1)
+#define C_00000D_FORCE_TDM 0xF7FFFFFF
+#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28)
+#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
+#define C_00000D_FORCE_RB 0xEFFFFFFF
+
+
#endif
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index cf7fea5ff2e..eb740fc3549 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -447,9 +447,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
return 0;
}
-int r200_init(struct radeon_device *rdev)
+void r200_set_safe_registers(struct radeon_device *rdev)
{
rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
- return 0;
}
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 1ebea8cc8c9..e08c4a8974c 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -33,43 +33,16 @@
#include "radeon_drm.h"
#include "r100_track.h"
#include "r300d.h"
-
+#include "rv350d.h"
#include "r300_reg_safe.h"
-/* r300,r350,rv350,rv370,rv380 depends on : */
-void r100_hdp_reset(struct radeon_device *rdev);
-int r100_cp_reset(struct radeon_device *rdev);
-int r100_rb2d_reset(struct radeon_device *rdev);
-int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
-int r100_pci_gart_enable(struct radeon_device *rdev);
-void r100_mc_setup(struct radeon_device *rdev);
-void r100_mc_disable_clients(struct radeon_device *rdev);
-int r100_gui_wait_for_idle(struct radeon_device *rdev);
-int r100_cs_packet_parse(struct radeon_cs_parser *p,
- struct radeon_cs_packet *pkt,
- unsigned idx);
-int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
-int r100_cs_parse_packet0(struct radeon_cs_parser *p,
- struct radeon_cs_packet *pkt,
- const unsigned *auth, unsigned n,
- radeon_packet0_check_t check);
-int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
- struct radeon_cs_packet *pkt,
- struct radeon_object *robj);
-
-/* This files gather functions specifics to:
- * r300,r350,rv350,rv370,rv380
- *
- * Some of these functions might be used by newer ASICs.
- */
-void r300_gpu_init(struct radeon_device *rdev);
-int r300_mc_wait_for_idle(struct radeon_device *rdev);
-int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
-
+/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 */
/*
* rv370,rv380 PCIE GART
*/
+static int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
+
void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
{
uint32_t tmp;
@@ -182,59 +155,6 @@ void rv370_pcie_gart_fini(struct radeon_device *rdev)
radeon_gart_fini(rdev);
}
-/*
- * MC
- */
-int r300_mc_init(struct radeon_device *rdev)
-{
- int r;
-
- if (r100_debugfs_rbbm_init(rdev)) {
- DRM_ERROR("Failed to register debugfs file for RBBM !\n");
- }
-
- r300_gpu_init(rdev);
- r100_pci_gart_disable(rdev);
- if (rdev->flags & RADEON_IS_PCIE) {
- rv370_pcie_gart_disable(rdev);
- }
-
- /* Setup GPU memory space */
- rdev->mc.vram_location = 0xFFFFFFFFUL;
- rdev->mc.gtt_location = 0xFFFFFFFFUL;
- if (rdev->flags & RADEON_IS_AGP) {
- r = radeon_agp_init(rdev);
- if (r) {
- printk(KERN_WARNING "[drm] Disabling AGP\n");
- rdev->flags &= ~RADEON_IS_AGP;
- rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
- } else {
- rdev->mc.gtt_location = rdev->mc.agp_base;
- }
- }
- r = radeon_mc_setup(rdev);
- if (r) {
- return r;
- }
-
- /* Program GPU memory space */
- r100_mc_disable_clients(rdev);
- if (r300_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "Failed to wait MC idle while "
- "programming pipes. Bad things might happen.\n");
- }
- r100_mc_setup(rdev);
- return 0;
-}
-
-void r300_mc_fini(struct radeon_device *rdev)
-{
-}
-
-
-/*
- * Fence emission
- */
void r300_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence)
{
@@ -260,10 +180,6 @@ void r300_fence_ring_emit(struct radeon_device *rdev,
radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
}
-
-/*
- * Global GPU functions
- */
int r300_copy_dma(struct radeon_device *rdev,
uint64_t src_offset,
uint64_t dst_offset,
@@ -582,11 +498,6 @@ void r300_vram_info(struct radeon_device *rdev)
r100_vram_init_sizes(rdev);
}
-
-/*
- * PCIE Lanes
- */
-
void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
{
uint32_t link_width_cntl, mask;
@@ -646,10 +557,6 @@ void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
}
-
-/*
- * Debugfs info
- */
#if defined(CONFIG_DEBUG_FS)
static int rv370_debugfs_pcie_gart_info(struct seq_file *m, void *data)
{
@@ -680,7 +587,7 @@ static struct drm_info_list rv370_pcie_gart_info_list[] = {
};
#endif
-int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
+static int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
{
#if defined(CONFIG_DEBUG_FS)
return radeon_debugfs_add_files(rdev, rv370_pcie_gart_info_list, 1);
@@ -689,10 +596,6 @@ int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
#endif
}
-
-/*
- * CS functions
- */
static int r300_packet0_check(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
unsigned idx, unsigned reg)
@@ -1226,12 +1129,6 @@ void r300_set_reg_safe(struct radeon_device *rdev)
rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm);
}
-int r300_init(struct radeon_device *rdev)
-{
- r300_set_reg_safe(rdev);
- return 0;
-}
-
void r300_mc_program(struct radeon_device *rdev)
{
struct r100_mc_save save;
@@ -1265,3 +1162,198 @@ void r300_mc_program(struct radeon_device *rdev)
S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
r100_mc_resume(rdev, &save);
}
+
+void r300_clock_startup(struct radeon_device *rdev)
+{
+ u32 tmp;
+
+ if (radeon_dynclks != -1 && radeon_dynclks)
+ radeon_legacy_set_clock_gating(rdev, 1);
+ /* We need to force on some of the block */
+ tmp = RREG32_PLL(R_00000D_SCLK_CNTL);
+ tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
+ if ((rdev->family == CHIP_RV350) || (rdev->family == CHIP_RV380))
+ tmp |= S_00000D_FORCE_VAP(1);
+ WREG32_PLL(R_00000D_SCLK_CNTL, tmp);
+}
+
+static int r300_startup(struct radeon_device *rdev)
+{
+ int r;
+
+ r300_mc_program(rdev);
+ /* Resume clock */
+ r300_clock_startup(rdev);
+ /* Initialize GPU configuration (# pipes, ...) */
+ r300_gpu_init(rdev);
+ /* Initialize GART (initialize after TTM so we can allocate
+ * memory through TTM but finalize after TTM) */
+ if (rdev->flags & RADEON_IS_PCIE) {
+ r = rv370_pcie_gart_enable(rdev);
+ if (r)
+ return r;
+ }
+ if (rdev->flags & RADEON_IS_PCI) {
+ r = r100_pci_gart_enable(rdev);
+ if (r)
+ return r;
+ }
+ /* Enable IRQ */
+ rdev->irq.sw_int = true;
+ r100_irq_set(rdev);
+ /* 1M ring buffer */
+ r = r100_cp_init(rdev, 1024 * 1024);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+ return r;
+ }
+ r = r100_wb_init(rdev);
+ if (r)
+ dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+ r = r100_ib_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+ return r;
+ }
+ return 0;
+}
+
+int r300_resume(struct radeon_device *rdev)
+{
+ /* Make sur GART are not working */
+ if (rdev->flags & RADEON_IS_PCIE)
+ rv370_pcie_gart_disable(rdev);
+ if (rdev->flags & RADEON_IS_PCI)
+ r100_pci_gart_disable(rdev);
+ /* Resume clock before doing reset */
+ r300_clock_startup(rdev);
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* post */
+ radeon_combios_asic_init(rdev->ddev);
+ /* Resume clock after posting */
+ r300_clock_startup(rdev);
+ return r300_startup(rdev);
+}
+
+int r300_suspend(struct radeon_device *rdev)
+{
+ r100_cp_disable(rdev);
+ r100_wb_disable(rdev);
+ r100_irq_disable(rdev);
+ if (rdev->flags & RADEON_IS_PCIE)
+ rv370_pcie_gart_disable(rdev);
+ if (rdev->flags & RADEON_IS_PCI)
+ r100_pci_gart_disable(rdev);
+ return 0;
+}
+
+void r300_fini(struct radeon_device *rdev)
+{
+ r300_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ radeon_gem_fini(rdev);
+ if (rdev->flags & RADEON_IS_PCIE)
+ rv370_pcie_gart_fini(rdev);
+ if (rdev->flags & RADEON_IS_PCI)
+ r100_pci_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_object_fini(rdev);
+ radeon_atombios_fini(rdev);
+ kfree(rdev->bios);
+ rdev->bios = NULL;
+}
+
+int r300_init(struct radeon_device *rdev)
+{
+ int r;
+
+ /* Disable VGA */
+ r100_vga_render_disable(rdev);
+ /* Initialize scratch registers */
+ radeon_scratch_init(rdev);
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* TODO: disable VGA need to use VGA request */
+ /* BIOS*/
+ if (!radeon_get_bios(rdev)) {
+ if (ASIC_IS_AVIVO(rdev))
+ return -EINVAL;
+ }
+ if (rdev->is_atom_bios) {
+ dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
+ return -EINVAL;
+ } else {
+ r = radeon_combios_init(rdev);
+ if (r)
+ return r;
+ }
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev,
+ "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* check if cards are posted or not */
+ if (!radeon_card_posted(rdev) && rdev->bios) {
+ DRM_INFO("GPU not posted. posting now...\n");
+ radeon_combios_asic_init(rdev->ddev);
+ }
+ /* Set asic errata */
+ r300_errata(rdev);
+ /* Initialize clocks */
+ radeon_get_clock_info(rdev->ddev);
+ /* Get vram informations */
+ r300_vram_info(rdev);
+ /* Initialize memory controller (also test AGP) */
+ r = r420_mc_init(rdev);
+ if (r)
+ return r;
+ /* Fence driver */
+ r = radeon_fence_driver_init(rdev);
+ if (r)
+ return r;
+ r = radeon_irq_kms_init(rdev);
+ if (r)
+ return r;
+ /* Memory manager */
+ r = radeon_object_init(rdev);
+ if (r)
+ return r;
+ if (rdev->flags & RADEON_IS_PCIE) {
+ r = rv370_pcie_gart_init(rdev);
+ if (r)
+ return r;
+ }
+ if (rdev->flags & RADEON_IS_PCI) {
+ r = r100_pci_gart_init(rdev);
+ if (r)
+ return r;
+ }
+ r300_set_reg_safe(rdev);
+ rdev->accel_working = true;
+ r = r300_startup(rdev);
+ if (r) {
+ /* Somethings want wront with the accel init stop accel */
+ dev_err(rdev->dev, "Disabling GPU acceleration\n");
+ r300_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ if (rdev->flags & RADEON_IS_PCIE)
+ rv370_pcie_gart_fini(rdev);
+ if (rdev->flags & RADEON_IS_PCI)
+ r100_pci_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rdev->accel_working = false;
+ }
+ return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h
index d4fa3eb1074..4c73114f0de 100644
--- a/drivers/gpu/drm/radeon/r300d.h
+++ b/drivers/gpu/drm/radeon/r300d.h
@@ -96,6 +96,211 @@
#define S_000170_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
#define G_000170_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
#define C_000170_AGP_BASE_ADDR 0x00000000
+#define R_0007C0_CP_STAT 0x0007C0
+#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
+#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
+#define C_0007C0_MRU_BUSY 0xFFFFFFFE
+#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
+#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
+#define C_0007C0_MWU_BUSY 0xFFFFFFFD
+#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
+#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
+#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
+#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
+#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
+#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
+#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
+#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
+#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
+#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
+#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
+#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
+#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
+#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
+#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
+#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
+#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
+#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
+#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
+#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
+#define C_0007C0_CSI_BUSY 0xFFFFDFFF
+#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
+#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
+#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
+#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
+#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
+#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
+#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
+#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
+#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
+#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
+#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
+#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
+#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
+#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
+#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
+#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
+#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
+#define C_0007C0_CP_BUSY 0x7FFFFFFF
+#define R_000E40_RBBM_STATUS 0x000E40
+#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
+#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
+#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
+#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
+#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
+#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
+#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
+#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
+#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
+#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
+#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
+#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
+#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
+#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
+#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
+#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
+#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
+#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
+#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
+#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
+#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
+#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
+#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
+#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
+#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
+#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
+#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
+#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
+#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
+#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
+#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
+#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
+#define C_000E40_E2_BUSY 0xFFFDFFFF
+#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
+#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
+#define C_000E40_RB2D_BUSY 0xFFFBFFFF
+#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
+#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
+#define C_000E40_RB3D_BUSY 0xFFF7FFFF
+#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
+#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
+#define C_000E40_VAP_BUSY 0xFFEFFFFF
+#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
+#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
+#define C_000E40_RE_BUSY 0xFFDFFFFF
+#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
+#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
+#define C_000E40_TAM_BUSY 0xFFBFFFFF
+#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
+#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
+#define C_000E40_TDM_BUSY 0xFF7FFFFF
+#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
+#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
+#define C_000E40_PB_BUSY 0xFEFFFFFF
+#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
+#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
+#define C_000E40_TIM_BUSY 0xFDFFFFFF
+#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
+#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
+#define C_000E40_GA_BUSY 0xFBFFFFFF
+#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
+#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
+#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
+#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
+#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
+#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
+#define R_00000D_SCLK_CNTL 0x00000D
+#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
+#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7)
+#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8
+#define S_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 3)
+#define G_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) >> 3) & 0x1)
+#define C_00000D_CP_MAX_DYN_STOP_LAT 0xFFFFFFF7
+#define S_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 4)
+#define G_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) >> 4) & 0x1)
+#define C_00000D_HDP_MAX_DYN_STOP_LAT 0xFFFFFFEF
+#define S_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 5)
+#define G_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) >> 5) & 0x1)
+#define C_00000D_TV_MAX_DYN_STOP_LAT 0xFFFFFFDF
+#define S_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 6)
+#define G_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) >> 6) & 0x1)
+#define C_00000D_E2_MAX_DYN_STOP_LAT 0xFFFFFFBF
+#define S_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 7)
+#define G_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) >> 7) & 0x1)
+#define C_00000D_SE_MAX_DYN_STOP_LAT 0xFFFFFF7F
+#define S_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 8)
+#define G_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 8) & 0x1)
+#define C_00000D_IDCT_MAX_DYN_STOP_LAT 0xFFFFFEFF
+#define S_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 9)
+#define G_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) >> 9) & 0x1)
+#define C_00000D_VIP_MAX_DYN_STOP_LAT 0xFFFFFDFF
+#define S_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 10)
+#define G_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) >> 10) & 0x1)
+#define C_00000D_RE_MAX_DYN_STOP_LAT 0xFFFFFBFF
+#define S_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 11)
+#define G_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) >> 11) & 0x1)
+#define C_00000D_PB_MAX_DYN_STOP_LAT 0xFFFFF7FF
+#define S_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 12)
+#define G_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) >> 12) & 0x1)
+#define C_00000D_TAM_MAX_DYN_STOP_LAT 0xFFFFEFFF
+#define S_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 13)
+#define G_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) >> 13) & 0x1)
+#define C_00000D_TDM_MAX_DYN_STOP_LAT 0xFFFFDFFF
+#define S_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 14)
+#define G_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) >> 14) & 0x1)
+#define C_00000D_RB_MAX_DYN_STOP_LAT 0xFFFFBFFF
+#define S_00000D_FORCE_DISP2(x) (((x) & 0x1) << 15)
+#define G_00000D_FORCE_DISP2(x) (((x) >> 15) & 0x1)
+#define C_00000D_FORCE_DISP2 0xFFFF7FFF
+#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16)
+#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1)
+#define C_00000D_FORCE_CP 0xFFFEFFFF
+#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17)
+#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1)
+#define C_00000D_FORCE_HDP 0xFFFDFFFF
+#define S_00000D_FORCE_DISP1(x) (((x) & 0x1) << 18)
+#define G_00000D_FORCE_DISP1(x) (((x) >> 18) & 0x1)
+#define C_00000D_FORCE_DISP1 0xFFFBFFFF
+#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19)
+#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1)
+#define C_00000D_FORCE_TOP 0xFFF7FFFF
+#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
+#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
+#define C_00000D_FORCE_E2 0xFFEFFFFF
+#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21)
+#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1)
+#define C_00000D_FORCE_SE 0xFFDFFFFF
+#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
+#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
+#define C_00000D_FORCE_IDCT 0xFFBFFFFF
+#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23)
+#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1)
+#define C_00000D_FORCE_VIP 0xFF7FFFFF
+#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
+#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
+#define C_00000D_FORCE_RE 0xFEFFFFFF
+#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25)
+#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1)
+#define C_00000D_FORCE_PB 0xFDFFFFFF
+#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26)
+#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1)
+#define C_00000D_FORCE_TAM 0xFBFFFFFF
+#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27)
+#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1)
+#define C_00000D_FORCE_TDM 0xF7FFFFFF
+#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28)
+#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
+#define C_00000D_FORCE_RB 0xEFFFFFFF
+#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29)
+#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1)
+#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF
+#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30)
+#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1)
+#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF
+#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31)
+#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1)
+#define C_00000D_FORCE_OV0 0x7FFFFFFF
+
#endif
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 49a2fdc57d2..5c7fe52de30 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -155,6 +155,9 @@ static void r420_debugfs(struct radeon_device *rdev)
static void r420_clock_resume(struct radeon_device *rdev)
{
u32 sclk_cntl;
+
+ if (radeon_dynclks != -1 && radeon_dynclks)
+ radeon_atom_set_clock_gating(rdev, 1);
sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL);
sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
if (rdev->family == CHIP_R420)
@@ -167,6 +170,8 @@ static int r420_startup(struct radeon_device *rdev)
int r;
r300_mc_program(rdev);
+ /* Resume clock */
+ r420_clock_resume(rdev);
/* Initialize GART (initialize after TTM so we can allocate
* memory through TTM but finalize after TTM) */
if (rdev->flags & RADEON_IS_PCIE) {
@@ -267,7 +272,6 @@ int r420_init(struct radeon_device *rdev)
{
int r;
- rdev->new_init_path = true;
/* Initialize scratch registers */
radeon_scratch_init(rdev);
/* Initialize surface registers */
diff --git a/drivers/gpu/drm/radeon/r420d.h b/drivers/gpu/drm/radeon/r420d.h
index a48a7db1e2a..fc78d31a0b4 100644
--- a/drivers/gpu/drm/radeon/r420d.h
+++ b/drivers/gpu/drm/radeon/r420d.h
@@ -212,9 +212,9 @@
#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
#define C_00000D_FORCE_E2 0xFFEFFFFF
-#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21)
-#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1)
-#define C_00000D_FORCE_SE 0xFFDFFFFF
+#define S_00000D_FORCE_VAP(x) (((x) & 0x1) << 21)
+#define G_00000D_FORCE_VAP(x) (((x) >> 21) & 0x1)
+#define C_00000D_FORCE_VAP 0xFFDFFFFF
#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
#define C_00000D_FORCE_IDCT 0xFFBFFFFF
@@ -224,24 +224,24 @@
#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
#define C_00000D_FORCE_RE 0xFEFFFFFF
-#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25)
-#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1)
-#define C_00000D_FORCE_PB 0xFDFFFFFF
+#define S_00000D_FORCE_SR(x) (((x) & 0x1) << 25)
+#define G_00000D_FORCE_SR(x) (((x) >> 25) & 0x1)
+#define C_00000D_FORCE_SR 0xFDFFFFFF
#define S_00000D_FORCE_PX(x) (((x) & 0x1) << 26)
#define G_00000D_FORCE_PX(x) (((x) >> 26) & 0x1)
#define C_00000D_FORCE_PX 0xFBFFFFFF
#define S_00000D_FORCE_TX(x) (((x) & 0x1) << 27)
#define G_00000D_FORCE_TX(x) (((x) >> 27) & 0x1)
#define C_00000D_FORCE_TX 0xF7FFFFFF
-#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28)
-#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
-#define C_00000D_FORCE_RB 0xEFFFFFFF
+#define S_00000D_FORCE_US(x) (((x) & 0x1) << 28)
+#define G_00000D_FORCE_US(x) (((x) >> 28) & 0x1)
+#define C_00000D_FORCE_US 0xEFFFFFFF
#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29)
#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1)
#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF
-#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30)
-#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1)
-#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF
+#define S_00000D_FORCE_SU(x) (((x) & 0x1) << 30)
+#define G_00000D_FORCE_SU(x) (((x) >> 30) & 0x1)
+#define C_00000D_FORCE_SU 0xBFFFFFFF
#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31)
#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1)
#define C_00000D_FORCE_OV0 0x7FFFFFFF
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 0bf13fccdaf..a555b7b19b4 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -186,7 +186,7 @@ static int r520_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
rdev->irq.sw_int = true;
- r100_irq_set(rdev);
+ rs600_irq_set(rdev);
/* 1M ring buffer */
r = r100_cp_init(rdev, 1024 * 1024);
if (r) {
@@ -228,7 +228,6 @@ int r520_init(struct radeon_device *rdev)
{
int r;
- rdev->new_init_path = true;
/* Initialize scratch registers */
radeon_scratch_init(rdev);
/* Initialize surface registers */
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 2e4e60edbff..609719490ec 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -65,16 +65,11 @@ MODULE_FIRMWARE("radeon/RV710_me.bin");
int r600_debugfs_mc_info_init(struct radeon_device *rdev);
-/* This files gather functions specifics to:
- * r600,rv610,rv630,rv620,rv635,rv670
- *
- * Some of these functions might be used by newer ASICs.
- */
+/* r600,rv610,rv630,rv620,rv635,rv670 */
int r600_mc_wait_for_idle(struct radeon_device *rdev);
void r600_gpu_init(struct radeon_device *rdev);
void r600_fini(struct radeon_device *rdev);
-
/*
* R600 PCIE GART
*/
@@ -168,7 +163,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
- WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12);
+ WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
@@ -225,6 +220,40 @@ void r600_pcie_gart_fini(struct radeon_device *rdev)
radeon_gart_fini(rdev);
}
+void r600_agp_enable(struct radeon_device *rdev)
+{
+ u32 tmp;
+ int i;
+
+ /* Setup L2 cache */
+ WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
+ ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+ EFFECTIVE_L2_QUEUE_SIZE(7));
+ WREG32(VM_L2_CNTL2, 0);
+ WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
+ /* Setup TLB control */
+ tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
+ SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+ EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
+ ENABLE_WAIT_L2_QUERY;
+ WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
+ WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
+ WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
+ WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
+ for (i = 0; i < 7; i++)
+ WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+}
+
int r600_mc_wait_for_idle(struct radeon_device *rdev)
{
unsigned i;
@@ -240,14 +269,9 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev)
return -1;
}
-static void r600_mc_resume(struct radeon_device *rdev)
+static void r600_mc_program(struct radeon_device *rdev)
{
- u32 d1vga_control, d2vga_control;
- u32 vga_render_control, vga_hdp_control;
- u32 d1crtc_control, d2crtc_control;
- u32 new_d1grph_primary, new_d1grph_secondary;
- u32 new_d2grph_primary, new_d2grph_secondary;
- u64 old_vram_start;
+ struct rv515_mc_save save;
u32 tmp;
int i, j;
@@ -261,85 +285,51 @@ static void r600_mc_resume(struct radeon_device *rdev)
}
WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
- d1vga_control = RREG32(D1VGA_CONTROL);
- d2vga_control = RREG32(D2VGA_CONTROL);
- vga_render_control = RREG32(VGA_RENDER_CONTROL);
- vga_hdp_control = RREG32(VGA_HDP_CONTROL);
- d1crtc_control = RREG32(D1CRTC_CONTROL);
- d2crtc_control = RREG32(D2CRTC_CONTROL);
- old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
- new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
- new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
- new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
- new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
- new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
- new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
- new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
- new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
-
- /* Stop all video */
- WREG32(D1VGA_CONTROL, 0);
- WREG32(D2VGA_CONTROL, 0);
- WREG32(VGA_RENDER_CONTROL, 0);
- WREG32(D1CRTC_UPDATE_LOCK, 1);
- WREG32(D2CRTC_UPDATE_LOCK, 1);
- WREG32(D1CRTC_CONTROL, 0);
- WREG32(D2CRTC_CONTROL, 0);
- WREG32(D1CRTC_UPDATE_LOCK, 0);
- WREG32(D2CRTC_UPDATE_LOCK, 0);
-
- mdelay(1);
+ rv515_mc_stop(rdev, &save);
if (r600_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "[drm] MC not idle !\n");
+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
}
-
- /* Lockout access through VGA aperture*/
+ /* Lockout access through VGA aperture (doesn't exist before R600) */
WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
-
/* Update configuration */
- WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
- WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
+ if (rdev->flags & RADEON_IS_AGP) {
+ if (rdev->mc.vram_start < rdev->mc.gtt_start) {
+ /* VRAM before AGP */
+ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+ rdev->mc.vram_start >> 12);
+ WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+ rdev->mc.gtt_end >> 12);
+ } else {
+ /* VRAM after AGP */
+ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+ rdev->mc.gtt_start >> 12);
+ WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+ rdev->mc.vram_end >> 12);
+ }
+ } else {
+ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
+ WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12);
+ }
WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
- tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16;
+ tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
WREG32(MC_VM_FB_LOCATION, tmp);
WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
WREG32(HDP_NONSURFACE_INFO, (2 << 7));
- WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
+ WREG32(HDP_NONSURFACE_SIZE, rdev->mc.mc_vram_size | 0x3FF);
if (rdev->flags & RADEON_IS_AGP) {
- WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16);
- WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
+ WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22);
+ WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22);
WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
} else {
WREG32(MC_VM_AGP_BASE, 0);
WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
}
- WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
- WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
- WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
- WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
- WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
-
- /* Unlock host access */
- WREG32(VGA_HDP_CONTROL, vga_hdp_control);
-
- mdelay(1);
if (r600_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "[drm] MC not idle !\n");
+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
}
-
- /* Restore video state */
- WREG32(D1CRTC_UPDATE_LOCK, 1);
- WREG32(D2CRTC_UPDATE_LOCK, 1);
- WREG32(D1CRTC_CONTROL, d1crtc_control);
- WREG32(D2CRTC_CONTROL, d2crtc_control);
- WREG32(D1CRTC_UPDATE_LOCK, 0);
- WREG32(D2CRTC_UPDATE_LOCK, 0);
- WREG32(D1VGA_CONTROL, d1vga_control);
- WREG32(D2VGA_CONTROL, d2vga_control);
- WREG32(VGA_RENDER_CONTROL, vga_render_control);
-
+ rv515_mc_resume(rdev, &save);
/* we need to own VRAM, so turn off the VGA renderer here
* to stop it overwriting our objects */
rv515_vga_render_disable(rdev);
@@ -445,9 +435,9 @@ int r600_mc_init(struct radeon_device *rdev)
}
}
rdev->mc.vram_start = rdev->mc.vram_location;
- rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+ rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
rdev->mc.gtt_start = rdev->mc.gtt_location;
- rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size;
+ rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
/* FIXME: we should enforce default clock in case GPU is not in
* default setup
*/
@@ -463,6 +453,7 @@ int r600_mc_init(struct radeon_device *rdev)
*/
int r600_gpu_soft_reset(struct radeon_device *rdev)
{
+ struct rv515_mc_save save;
u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
@@ -480,13 +471,25 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
u32 srbm_reset = 0;
+ u32 tmp;
+ dev_info(rdev->dev, "GPU softreset \n");
+ dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
+ RREG32(R_008010_GRBM_STATUS));
+ dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n",
+ RREG32(R_008014_GRBM_STATUS2));
+ dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
+ RREG32(R_000E50_SRBM_STATUS));
+ rv515_mc_stop(rdev, &save);
+ if (r600_mc_wait_for_idle(rdev)) {
+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+ }
/* Disable CP parsing/prefetching */
WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
/* Check if any of the rendering block is busy and reset it */
if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
(RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
- WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) |
+ tmp = S_008020_SOFT_RESET_CR(1) |
S_008020_SOFT_RESET_DB(1) |
S_008020_SOFT_RESET_CB(1) |
S_008020_SOFT_RESET_PA(1) |
@@ -498,14 +501,18 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
S_008020_SOFT_RESET_TC(1) |
S_008020_SOFT_RESET_TA(1) |
S_008020_SOFT_RESET_VC(1) |
- S_008020_SOFT_RESET_VGT(1));
+ S_008020_SOFT_RESET_VGT(1);
+ dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
+ WREG32(R_008020_GRBM_SOFT_RESET, tmp);
(void)RREG32(R_008020_GRBM_SOFT_RESET);
udelay(50);
WREG32(R_008020_GRBM_SOFT_RESET, 0);
(void)RREG32(R_008020_GRBM_SOFT_RESET);
}
/* Reset CP (we always reset CP) */
- WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1));
+ tmp = S_008020_SOFT_RESET_CP(1);
+ dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
+ WREG32(R_008020_GRBM_SOFT_RESET, tmp);
(void)RREG32(R_008020_GRBM_SOFT_RESET);
udelay(50);
WREG32(R_008020_GRBM_SOFT_RESET, 0);
@@ -533,6 +540,14 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
+ if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+ srbm_reset |= S_000E60_SOFT_RESET_BIF(1);
+ dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
+ WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
+ (void)RREG32(R_000E60_SRBM_SOFT_RESET);
+ udelay(50);
+ WREG32(R_000E60_SRBM_SOFT_RESET, 0);
+ (void)RREG32(R_000E60_SRBM_SOFT_RESET);
WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
(void)RREG32(R_000E60_SRBM_SOFT_RESET);
udelay(50);
@@ -540,6 +555,17 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
(void)RREG32(R_000E60_SRBM_SOFT_RESET);
/* Wait a little for things to settle down */
udelay(50);
+ dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
+ RREG32(R_008010_GRBM_STATUS));
+ dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n",
+ RREG32(R_008014_GRBM_STATUS2));
+ dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
+ RREG32(R_000E50_SRBM_STATUS));
+ /* After reset we need to reinit the asic as GPU often endup in an
+ * incoherent state.
+ */
+ atom_asic_init(rdev->mode_info.atom_context);
+ rv515_mc_resume(rdev, &save);
return 0;
}
@@ -1350,32 +1376,47 @@ int r600_ring_test(struct radeon_device *rdev)
return r;
}
-/*
- * Writeback
- */
-int r600_wb_init(struct radeon_device *rdev)
+void r600_wb_disable(struct radeon_device *rdev)
+{
+ WREG32(SCRATCH_UMSK, 0);
+ if (rdev->wb.wb_obj) {
+ radeon_object_kunmap(rdev->wb.wb_obj);
+ radeon_object_unpin(rdev->wb.wb_obj);
+ }
+}
+
+void r600_wb_fini(struct radeon_device *rdev)
+{
+ r600_wb_disable(rdev);
+ if (rdev->wb.wb_obj) {
+ radeon_object_unref(&rdev->wb.wb_obj);
+ rdev->wb.wb = NULL;
+ rdev->wb.wb_obj = NULL;
+ }
+}
+
+int r600_wb_enable(struct radeon_device *rdev)
{
int r;
if (rdev->wb.wb_obj == NULL) {
- r = radeon_object_create(rdev, NULL, 4096,
- true,
- RADEON_GEM_DOMAIN_GTT,
- false, &rdev->wb.wb_obj);
+ r = radeon_object_create(rdev, NULL, 4096, true,
+ RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
if (r) {
- DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
+ dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
return r;
}
- r = radeon_object_pin(rdev->wb.wb_obj,
- RADEON_GEM_DOMAIN_GTT,
- &rdev->wb.gpu_addr);
+ r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
+ &rdev->wb.gpu_addr);
if (r) {
- DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
+ dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r);
+ r600_wb_fini(rdev);
return r;
}
r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
if (r) {
- DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
+ dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r);
+ r600_wb_fini(rdev);
return r;
}
}
@@ -1386,21 +1427,6 @@ int r600_wb_init(struct radeon_device *rdev)
return 0;
}
-void r600_wb_fini(struct radeon_device *rdev)
-{
- if (rdev->wb.wb_obj) {
- radeon_object_kunmap(rdev->wb.wb_obj);
- radeon_object_unpin(rdev->wb.wb_obj);
- radeon_object_unref(&rdev->wb.wb_obj);
- rdev->wb.wb = NULL;
- rdev->wb.wb_obj = NULL;
- }
-}
-
-
-/*
- * CS
- */
void r600_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence)
{
@@ -1477,11 +1503,14 @@ int r600_startup(struct radeon_device *rdev)
{
int r;
- r600_gpu_reset(rdev);
- r600_mc_resume(rdev);
- r = r600_pcie_gart_enable(rdev);
- if (r)
- return r;
+ r600_mc_program(rdev);
+ if (rdev->flags & RADEON_IS_AGP) {
+ r600_agp_enable(rdev);
+ } else {
+ r = r600_pcie_gart_enable(rdev);
+ if (r)
+ return r;
+ }
r600_gpu_init(rdev);
r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
@@ -1500,9 +1529,8 @@ int r600_startup(struct radeon_device *rdev)
r = r600_cp_resume(rdev);
if (r)
return r;
- r = r600_wb_init(rdev);
- if (r)
- return r;
+ /* write back buffer are not vital so don't worry about failure */
+ r600_wb_enable(rdev);
return 0;
}
@@ -1524,15 +1552,12 @@ int r600_resume(struct radeon_device *rdev)
{
int r;
- if (radeon_gpu_reset(rdev)) {
- /* FIXME: what do we want to do here ? */
- }
+ /* Do not reset GPU before posting, on r600 hw unlike on r500 hw,
+ * posting will perform necessary task to bring back GPU into good
+ * shape.
+ */
/* post card */
- if (rdev->is_atom_bios) {
- atom_asic_init(rdev->mode_info.atom_context);
- } else {
- radeon_combios_asic_init(rdev->ddev);
- }
+ atom_asic_init(rdev->mode_info.atom_context);
/* Initialize clocks */
r = radeon_clocks_init(rdev);
if (r) {
@@ -1545,7 +1570,7 @@ int r600_resume(struct radeon_device *rdev)
return r;
}
- r = radeon_ib_test(rdev);
+ r = r600_ib_test(rdev);
if (r) {
DRM_ERROR("radeon: failled testing IB (%d).\n", r);
return r;
@@ -1553,13 +1578,12 @@ int r600_resume(struct radeon_device *rdev)
return r;
}
-
int r600_suspend(struct radeon_device *rdev)
{
/* FIXME: we should wait for ring to be empty */
r600_cp_stop(rdev);
rdev->cp.ready = false;
-
+ r600_wb_disable(rdev);
r600_pcie_gart_disable(rdev);
/* unpin shaders bo */
radeon_object_unpin(rdev->r600_blit.shader_obj);
@@ -1576,7 +1600,6 @@ int r600_init(struct radeon_device *rdev)
{
int r;
- rdev->new_init_path = true;
r = radeon_dummy_page_init(rdev);
if (r)
return r;
@@ -1593,8 +1616,10 @@ int r600_init(struct radeon_device *rdev)
return -EINVAL;
}
/* Must be an ATOMBIOS */
- if (!rdev->is_atom_bios)
+ if (!rdev->is_atom_bios) {
+ dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
return -EINVAL;
+ }
r = radeon_atombios_init(rdev);
if (r)
return r;
@@ -1616,15 +1641,8 @@ int r600_init(struct radeon_device *rdev)
if (r)
return r;
r = r600_mc_init(rdev);
- if (r) {
- if (rdev->flags & RADEON_IS_AGP) {
- /* Retry with disabling AGP */
- r600_fini(rdev);
- rdev->flags &= ~RADEON_IS_AGP;
- return r600_init(rdev);
- }
+ if (r)
return r;
- }
/* Memory manager */
r = radeon_object_init(rdev);
if (r)
@@ -1653,12 +1671,10 @@ int r600_init(struct radeon_device *rdev)
r = r600_startup(rdev);
if (r) {
- if (rdev->flags & RADEON_IS_AGP) {
- /* Retry with disabling AGP */
- r600_fini(rdev);
- rdev->flags &= ~RADEON_IS_AGP;
- return r600_init(rdev);
- }
+ r600_suspend(rdev);
+ r600_wb_fini(rdev);
+ radeon_ring_fini(rdev);
+ r600_pcie_gart_fini(rdev);
rdev->accel_working = false;
}
if (rdev->accel_working) {
@@ -1667,7 +1683,7 @@ int r600_init(struct radeon_device *rdev)
DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
rdev->accel_working = false;
}
- r = radeon_ib_test(rdev);
+ r = r600_ib_test(rdev);
if (r) {
DRM_ERROR("radeon: failled testing IB (%d).\n", r);
rdev->accel_working = false;
@@ -1683,19 +1699,15 @@ void r600_fini(struct radeon_device *rdev)
r600_blit_fini(rdev);
radeon_ring_fini(rdev);
+ r600_wb_fini(rdev);
r600_pcie_gart_fini(rdev);
radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_clocks_fini(rdev);
-#if __OS_HAS_AGP
if (rdev->flags & RADEON_IS_AGP)
radeon_agp_fini(rdev);
-#endif
radeon_object_fini(rdev);
- if (rdev->is_atom_bios)
- radeon_atombios_fini(rdev);
- else
- radeon_combios_fini(rdev);
+ radeon_atombios_fini(rdev);
kfree(rdev->bios);
rdev->bios = NULL;
radeon_dummy_page_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
index d988eece018..dec50108160 100644
--- a/drivers/gpu/drm/radeon/r600_blit.c
+++ b/drivers/gpu/drm/radeon/r600_blit.c
@@ -582,8 +582,6 @@ r600_blit_copy(struct drm_device *dev,
u64 vb_addr;
u32 *vb;
- vb = r600_nomm_get_vb_ptr(dev);
-
if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
max_bytes = 8192;
@@ -619,8 +617,8 @@ r600_blit_copy(struct drm_device *dev,
if (!dev_priv->blit_vb)
return;
set_shaders(dev);
- vb = r600_nomm_get_vb_ptr(dev);
}
+ vb = r600_nomm_get_vb_ptr(dev);
vb[0] = i2f(dst_x);
vb[1] = 0;
@@ -708,8 +706,8 @@ r600_blit_copy(struct drm_device *dev,
return;
set_shaders(dev);
- vb = r600_nomm_get_vb_ptr(dev);
}
+ vb = r600_nomm_get_vb_ptr(dev);
vb[0] = i2f(dst_x / 4);
vb[1] = 0;
@@ -777,8 +775,6 @@ r600_blit_swap(struct drm_device *dev,
u64 vb_addr;
u32 *vb;
- vb = r600_nomm_get_vb_ptr(dev);
-
if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
r600_nomm_put_vb(dev);
@@ -787,8 +783,8 @@ r600_blit_swap(struct drm_device *dev,
return;
set_shaders(dev);
- vb = r600_nomm_get_vb_ptr(dev);
}
+ vb = r600_nomm_get_vb_ptr(dev);
if (cpp == 4) {
cb_format = COLOR_8_8_8_8;
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index acae33e2ad5..93108bb31d1 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -610,7 +610,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
size_bytes, rdev->r600_blit.vb_used);
- vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
max_bytes = 8192;
@@ -653,6 +652,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
vb = r600_nomm_get_vb_ptr(dev);
#endif
}
+ vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
vb[0] = i2f(dst_x);
vb[1] = 0;
@@ -747,6 +747,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
vb = r600_nomm_get_vb_ptr(dev);
}
#endif
+ vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
vb[0] = i2f(dst_x / 4);
vb[1] = 0;
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index d28970db6a2..17e42195c63 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -252,7 +252,7 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p)
header = radeon_get_ib_value(p, h_idx);
crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
- reg = header >> 2;
+ reg = CP_PACKET0_GET_REG(header);
mutex_lock(&p->rdev->ddev->mode_config.mutex);
obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 4a9028a85c9..9b64d47f1f8 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -643,6 +643,7 @@
#define G_000E50_MCDW_BUSY(x) (((x) >> 13) & 1)
#define G_000E50_SEM_BUSY(x) (((x) >> 14) & 1)
#define G_000E50_RLC_BUSY(x) (((x) >> 15) & 1)
+#define G_000E50_BIF_BUSY(x) (((x) >> 29) & 1)
#define R_000E60_SRBM_SOFT_RESET 0x0E60
#define S_000E60_SOFT_RESET_BIF(x) (((x) & 1) << 1)
#define S_000E60_SOFT_RESET_CG(x) (((x) & 1) << 2)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 950b346e343..5ab35b81c86 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -590,18 +590,8 @@ struct radeon_asic {
void (*fini)(struct radeon_device *rdev);
int (*resume)(struct radeon_device *rdev);
int (*suspend)(struct radeon_device *rdev);
- void (*errata)(struct radeon_device *rdev);
- void (*vram_info)(struct radeon_device *rdev);
void (*vga_set_state)(struct radeon_device *rdev, bool state);
int (*gpu_reset)(struct radeon_device *rdev);
- int (*mc_init)(struct radeon_device *rdev);
- void (*mc_fini)(struct radeon_device *rdev);
- int (*wb_init)(struct radeon_device *rdev);
- void (*wb_fini)(struct radeon_device *rdev);
- int (*gart_init)(struct radeon_device *rdev);
- void (*gart_fini)(struct radeon_device *rdev);
- int (*gart_enable)(struct radeon_device *rdev);
- void (*gart_disable)(struct radeon_device *rdev);
void (*gart_tlb_flush)(struct radeon_device *rdev);
int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr);
int (*cp_init)(struct radeon_device *rdev, unsigned ring_size);
@@ -611,7 +601,6 @@ struct radeon_asic {
void (*ring_start)(struct radeon_device *rdev);
int (*ring_test)(struct radeon_device *rdev);
void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
- int (*ib_test)(struct radeon_device *rdev);
int (*irq_set)(struct radeon_device *rdev);
int (*irq_process)(struct radeon_device *rdev);
u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc);
@@ -789,7 +778,6 @@ struct radeon_device {
bool shutdown;
bool suspend;
bool need_dma32;
- bool new_init_path;
bool accel_working;
struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
const struct firmware *me_fw; /* all family ME firmware */
@@ -949,28 +937,14 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
#define radeon_resume(rdev) (rdev)->asic->resume((rdev))
#define radeon_suspend(rdev) (rdev)->asic->suspend((rdev))
#define radeon_cs_parse(p) rdev->asic->cs_parse((p))
-#define radeon_errata(rdev) (rdev)->asic->errata((rdev))
-#define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev))
#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
#define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev))
-#define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev))
-#define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
-#define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev))
-#define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev))
-#define radeon_gpu_gart_init(rdev) (rdev)->asic->gart_init((rdev))
-#define radeon_gpu_gart_fini(rdev) (rdev)->asic->gart_fini((rdev))
-#define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev))
-#define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev))
#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev))
#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p))
-#define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize))
-#define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev))
-#define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev))
#define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev))
#define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev))
#define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev))
#define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib))
-#define radeon_ib_test(rdev) (rdev)->asic->ib_test((rdev))
#define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev))
#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev))
#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc))
@@ -996,6 +970,7 @@ extern void radeon_clocks_fini(struct radeon_device *rdev);
extern void radeon_scratch_init(struct radeon_device *rdev);
extern void radeon_surface_init(struct radeon_device *rdev);
extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
+extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
@@ -1031,11 +1006,27 @@ extern int r100_wb_init(struct radeon_device *rdev);
extern void r100_hdp_reset(struct radeon_device *rdev);
extern int r100_rb2d_reset(struct radeon_device *rdev);
extern int r100_cp_reset(struct radeon_device *rdev);
+extern void r100_vga_render_disable(struct radeon_device *rdev);
+extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt,
+ struct radeon_object *robj);
+extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt,
+ const unsigned *auth, unsigned n,
+ radeon_packet0_check_t check);
+extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
+ struct radeon_cs_packet *pkt,
+ unsigned idx);
+
+/* rv200,rv250,rv280 */
+extern void r200_set_safe_registers(struct radeon_device *rdev);
/* r300,r350,rv350,rv370,rv380 */
extern void r300_set_reg_safe(struct radeon_device *rdev);
extern void r300_mc_program(struct radeon_device *rdev);
extern void r300_vram_info(struct radeon_device *rdev);
+extern void r300_clock_startup(struct radeon_device *rdev);
+extern int r300_mc_wait_for_idle(struct radeon_device *rdev);
extern int rv370_pcie_gart_init(struct radeon_device *rdev);
extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
@@ -1066,6 +1057,18 @@ extern void rv515_clock_startup(struct radeon_device *rdev);
extern void rv515_debugfs(struct radeon_device *rdev);
extern int rv515_suspend(struct radeon_device *rdev);
+/* rs400 */
+extern int rs400_gart_init(struct radeon_device *rdev);
+extern int rs400_gart_enable(struct radeon_device *rdev);
+extern void rs400_gart_adjust_size(struct radeon_device *rdev);
+extern void rs400_gart_disable(struct radeon_device *rdev);
+extern void rs400_gart_fini(struct radeon_device *rdev);
+
+/* rs600 */
+extern void rs600_set_safe_registers(struct radeon_device *rdev);
+extern int rs600_irq_set(struct radeon_device *rdev);
+extern void rs600_irq_disable(struct radeon_device *rdev);
+
/* rs690, rs740 */
extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
struct drm_display_mode *mode1,
@@ -1083,8 +1086,9 @@ extern int r600_pcie_gart_init(struct radeon_device *rdev);
extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
extern int r600_ib_test(struct radeon_device *rdev);
extern int r600_ring_test(struct radeon_device *rdev);
-extern int r600_wb_init(struct radeon_device *rdev);
extern void r600_wb_fini(struct radeon_device *rdev);
+extern int r600_wb_enable(struct radeon_device *rdev);
+extern void r600_wb_disable(struct radeon_device *rdev);
extern void r600_scratch_init(struct radeon_device *rdev);
extern int r600_blit_init(struct radeon_device *rdev);
extern void r600_blit_fini(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index c8a4e7b5663..c3532c7a6f3 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -41,28 +41,17 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
/*
* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
*/
-int r100_init(struct radeon_device *rdev);
-int r200_init(struct radeon_device *rdev);
+extern int r100_init(struct radeon_device *rdev);
+extern void r100_fini(struct radeon_device *rdev);
+extern int r100_suspend(struct radeon_device *rdev);
+extern int r100_resume(struct radeon_device *rdev);
uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
-void r100_errata(struct radeon_device *rdev);
-void r100_vram_info(struct radeon_device *rdev);
void r100_vga_set_state(struct radeon_device *rdev, bool state);
int r100_gpu_reset(struct radeon_device *rdev);
-int r100_mc_init(struct radeon_device *rdev);
-void r100_mc_fini(struct radeon_device *rdev);
u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
-int r100_wb_init(struct radeon_device *rdev);
-void r100_wb_fini(struct radeon_device *rdev);
-int r100_pci_gart_init(struct radeon_device *rdev);
-void r100_pci_gart_fini(struct radeon_device *rdev);
-int r100_pci_gart_enable(struct radeon_device *rdev);
-void r100_pci_gart_disable(struct radeon_device *rdev);
void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
-int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
-void r100_cp_fini(struct radeon_device *rdev);
-void r100_cp_disable(struct radeon_device *rdev);
void r100_cp_commit(struct radeon_device *rdev);
void r100_ring_start(struct radeon_device *rdev);
int r100_irq_set(struct radeon_device *rdev);
@@ -83,33 +72,21 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
void r100_bandwidth_update(struct radeon_device *rdev);
void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
-int r100_ib_test(struct radeon_device *rdev);
int r100_ring_test(struct radeon_device *rdev);
static struct radeon_asic r100_asic = {
.init = &r100_init,
- .errata = &r100_errata,
- .vram_info = &r100_vram_info,
+ .fini = &r100_fini,
+ .suspend = &r100_suspend,
+ .resume = &r100_resume,
.vga_set_state = &r100_vga_set_state,
.gpu_reset = &r100_gpu_reset,
- .mc_init = &r100_mc_init,
- .mc_fini = &r100_mc_fini,
- .wb_init = &r100_wb_init,
- .wb_fini = &r100_wb_fini,
- .gart_init = &r100_pci_gart_init,
- .gart_fini = &r100_pci_gart_fini,
- .gart_enable = &r100_pci_gart_enable,
- .gart_disable = &r100_pci_gart_disable,
.gart_tlb_flush = &r100_pci_gart_tlb_flush,
.gart_set_page = &r100_pci_gart_set_page,
- .cp_init = &r100_cp_init,
- .cp_fini = &r100_cp_fini,
- .cp_disable = &r100_cp_disable,
.cp_commit = &r100_cp_commit,
.ring_start = &r100_ring_start,
.ring_test = &r100_ring_test,
.ring_ib_execute = &r100_ring_ib_execute,
- .ib_test = &r100_ib_test,
.irq_set = &r100_irq_set,
.irq_process = &r100_irq_process,
.get_vblank_counter = &r100_get_vblank_counter,
@@ -131,55 +108,38 @@ static struct radeon_asic r100_asic = {
/*
* r300,r350,rv350,rv380
*/
-int r300_init(struct radeon_device *rdev);
-void r300_errata(struct radeon_device *rdev);
-void r300_vram_info(struct radeon_device *rdev);
-int r300_gpu_reset(struct radeon_device *rdev);
-int r300_mc_init(struct radeon_device *rdev);
-void r300_mc_fini(struct radeon_device *rdev);
-void r300_ring_start(struct radeon_device *rdev);
-void r300_fence_ring_emit(struct radeon_device *rdev,
- struct radeon_fence *fence);
-int r300_cs_parse(struct radeon_cs_parser *p);
-int rv370_pcie_gart_init(struct radeon_device *rdev);
-void rv370_pcie_gart_fini(struct radeon_device *rdev);
-int rv370_pcie_gart_enable(struct radeon_device *rdev);
-void rv370_pcie_gart_disable(struct radeon_device *rdev);
-void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
-int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
-uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
-void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
-void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
-int r300_copy_dma(struct radeon_device *rdev,
- uint64_t src_offset,
- uint64_t dst_offset,
- unsigned num_pages,
- struct radeon_fence *fence);
-
+extern int r300_init(struct radeon_device *rdev);
+extern void r300_fini(struct radeon_device *rdev);
+extern int r300_suspend(struct radeon_device *rdev);
+extern int r300_resume(struct radeon_device *rdev);
+extern int r300_gpu_reset(struct radeon_device *rdev);
+extern void r300_ring_start(struct radeon_device *rdev);
+extern void r300_fence_ring_emit(struct radeon_device *rdev,
+ struct radeon_fence *fence);
+extern int r300_cs_parse(struct radeon_cs_parser *p);
+extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
+extern int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
+extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
+extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
+extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
+extern int r300_copy_dma(struct radeon_device *rdev,
+ uint64_t src_offset,
+ uint64_t dst_offset,
+ unsigned num_pages,
+ struct radeon_fence *fence);
static struct radeon_asic r300_asic = {
.init = &r300_init,
- .errata = &r300_errata,
- .vram_info = &r300_vram_info,
+ .fini = &r300_fini,
+ .suspend = &r300_suspend,
+ .resume = &r300_resume,
.vga_set_state = &r100_vga_set_state,
.gpu_reset = &r300_gpu_reset,
- .mc_init = &r300_mc_init,
- .mc_fini = &r300_mc_fini,
- .wb_init = &r100_wb_init,
- .wb_fini = &r100_wb_fini,
- .gart_init = &r100_pci_gart_init,
- .gart_fini = &r100_pci_gart_fini,
- .gart_enable = &r100_pci_gart_enable,
- .gart_disable = &r100_pci_gart_disable,
.gart_tlb_flush = &r100_pci_gart_tlb_flush,
.gart_set_page = &r100_pci_gart_set_page,
- .cp_init = &r100_cp_init,
- .cp_fini = &r100_cp_fini,
- .cp_disable = &r100_cp_disable,
.cp_commit = &r100_cp_commit,
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ring_ib_execute = &r100_ring_ib_execute,
- .ib_test = &r100_ib_test,
.irq_set = &r100_irq_set,
.irq_process = &r100_irq_process,
.get_vblank_counter = &r100_get_vblank_counter,
@@ -209,26 +169,14 @@ static struct radeon_asic r420_asic = {
.fini = &r420_fini,
.suspend = &r420_suspend,
.resume = &r420_resume,
- .errata = NULL,
- .vram_info = NULL,
.vga_set_state = &r100_vga_set_state,
.gpu_reset = &r300_gpu_reset,
- .mc_init = NULL,
- .mc_fini = NULL,
- .wb_init = NULL,
- .wb_fini = NULL,
- .gart_enable = NULL,
- .gart_disable = NULL,
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
.gart_set_page = &rv370_pcie_gart_set_page,
- .cp_init = NULL,
- .cp_fini = NULL,
- .cp_disable = NULL,
.cp_commit = &r100_cp_commit,
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ring_ib_execute = &r100_ring_ib_execute,
- .ib_test = NULL,
.irq_set = &r100_irq_set,
.irq_process = &r100_irq_process,
.get_vblank_counter = &r100_get_vblank_counter,
@@ -250,42 +198,27 @@ static struct radeon_asic r420_asic = {
/*
* rs400,rs480
*/
-void rs400_errata(struct radeon_device *rdev);
-void rs400_vram_info(struct radeon_device *rdev);
-int rs400_mc_init(struct radeon_device *rdev);
-void rs400_mc_fini(struct radeon_device *rdev);
-int rs400_gart_init(struct radeon_device *rdev);
-void rs400_gart_fini(struct radeon_device *rdev);
-int rs400_gart_enable(struct radeon_device *rdev);
-void rs400_gart_disable(struct radeon_device *rdev);
+extern int rs400_init(struct radeon_device *rdev);
+extern void rs400_fini(struct radeon_device *rdev);
+extern int rs400_suspend(struct radeon_device *rdev);
+extern int rs400_resume(struct radeon_device *rdev);
void rs400_gart_tlb_flush(struct radeon_device *rdev);
int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
static struct radeon_asic rs400_asic = {
- .init = &r300_init,
- .errata = &rs400_errata,
- .vram_info = &rs400_vram_info,
+ .init = &rs400_init,
+ .fini = &rs400_fini,
+ .suspend = &rs400_suspend,
+ .resume = &rs400_resume,
.vga_set_state = &r100_vga_set_state,
.gpu_reset = &r300_gpu_reset,
- .mc_init = &rs400_mc_init,
- .mc_fini = &rs400_mc_fini,
- .wb_init = &r100_wb_init,
- .wb_fini = &r100_wb_fini,
- .gart_init = &rs400_gart_init,
- .gart_fini = &rs400_gart_fini,
- .gart_enable = &rs400_gart_enable,
- .gart_disable = &rs400_gart_disable,
.gart_tlb_flush = &rs400_gart_tlb_flush,
.gart_set_page = &rs400_gart_set_page,
- .cp_init = &r100_cp_init,
- .cp_fini = &r100_cp_fini,
- .cp_disable = &r100_cp_disable,
.cp_commit = &r100_cp_commit,
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ring_ib_execute = &r100_ring_ib_execute,
- .ib_test = &r100_ib_test,
.irq_set = &r100_irq_set,
.irq_process = &r100_irq_process,
.get_vblank_counter = &r100_get_vblank_counter,
@@ -307,18 +240,13 @@ static struct radeon_asic rs400_asic = {
/*
* rs600.
*/
-int rs600_init(struct radeon_device *rdev);
-void rs600_errata(struct radeon_device *rdev);
-void rs600_vram_info(struct radeon_device *rdev);
-int rs600_mc_init(struct radeon_device *rdev);
-void rs600_mc_fini(struct radeon_device *rdev);
+extern int rs600_init(struct radeon_device *rdev);
+extern void rs600_fini(struct radeon_device *rdev);
+extern int rs600_suspend(struct radeon_device *rdev);
+extern int rs600_resume(struct radeon_device *rdev);
int rs600_irq_set(struct radeon_device *rdev);
int rs600_irq_process(struct radeon_device *rdev);
u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
-int rs600_gart_init(struct radeon_device *rdev);
-void rs600_gart_fini(struct radeon_device *rdev);
-int rs600_gart_enable(struct radeon_device *rdev);
-void rs600_gart_disable(struct radeon_device *rdev);
void rs600_gart_tlb_flush(struct radeon_device *rdev);
int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
@@ -326,28 +254,17 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
void rs600_bandwidth_update(struct radeon_device *rdev);
static struct radeon_asic rs600_asic = {
.init = &rs600_init,
- .errata = &rs600_errata,
- .vram_info = &rs600_vram_info,
+ .fini = &rs600_fini,
+ .suspend = &rs600_suspend,
+ .resume = &rs600_resume,
.vga_set_state = &r100_vga_set_state,
.gpu_reset = &r300_gpu_reset,
- .mc_init = &rs600_mc_init,
- .mc_fini = &rs600_mc_fini,
- .wb_init = &r100_wb_init,
- .wb_fini = &r100_wb_fini,
- .gart_init = &rs600_gart_init,
- .gart_fini = &rs600_gart_fini,
- .gart_enable = &rs600_gart_enable,
- .gart_disable = &rs600_gart_disable,
.gart_tlb_flush = &rs600_gart_tlb_flush,
.gart_set_page = &rs600_gart_set_page,
- .cp_init = &r100_cp_init,
- .cp_fini = &r100_cp_fini,
- .cp_disable = &r100_cp_disable,
.cp_commit = &r100_cp_commit,
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ring_ib_execute = &r100_ring_ib_execute,
- .ib_test = &r100_ib_test,
.irq_set = &rs600_irq_set,
.irq_process = &rs600_irq_process,
.get_vblank_counter = &rs600_get_vblank_counter,
@@ -367,37 +284,26 @@ static struct radeon_asic rs600_asic = {
/*
* rs690,rs740
*/
-void rs690_errata(struct radeon_device *rdev);
-void rs690_vram_info(struct radeon_device *rdev);
-int rs690_mc_init(struct radeon_device *rdev);
-void rs690_mc_fini(struct radeon_device *rdev);
+int rs690_init(struct radeon_device *rdev);
+void rs690_fini(struct radeon_device *rdev);
+int rs690_resume(struct radeon_device *rdev);
+int rs690_suspend(struct radeon_device *rdev);
uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
void rs690_bandwidth_update(struct radeon_device *rdev);
static struct radeon_asic rs690_asic = {
- .init = &rs600_init,
- .errata = &rs690_errata,
- .vram_info = &rs690_vram_info,
+ .init = &rs690_init,
+ .fini = &rs690_fini,
+ .suspend = &rs690_suspend,
+ .resume = &rs690_resume,
.vga_set_state = &r100_vga_set_state,
.gpu_reset = &r300_gpu_reset,
- .mc_init = &rs690_mc_init,
- .mc_fini = &rs690_mc_fini,
- .wb_init = &r100_wb_init,
- .wb_fini = &r100_wb_fini,
- .gart_init = &rs400_gart_init,
- .gart_fini = &rs400_gart_fini,
- .gart_enable = &rs400_gart_enable,
- .gart_disable = &rs400_gart_disable,
.gart_tlb_flush = &rs400_gart_tlb_flush,
.gart_set_page = &rs400_gart_set_page,
- .cp_init = &r100_cp_init,
- .cp_fini = &r100_cp_fini,
- .cp_disable = &r100_cp_disable,
.cp_commit = &r100_cp_commit,
.ring_start = &r300_ring_start,
.ring_test = &r100_ring_test,
.ring_ib_execute = &r100_ring_ib_execute,
- .ib_test = &r100_ib_test,
.irq_set = &rs600_irq_set,
.irq_process = &rs600_irq_process,
.get_vblank_counter = &rs600_get_vblank_counter,
@@ -435,28 +341,14 @@ static struct radeon_asic rv515_asic = {
.fini = &rv515_fini,
.suspend = &rv515_suspend,
.resume = &rv515_resume,
- .errata = NULL,
- .vram_info = NULL,
.vga_set_state = &r100_vga_set_state,
.gpu_reset = &rv515_gpu_reset,
- .mc_init = NULL,
- .mc_fini = NULL,
- .wb_init = NULL,
- .wb_fini = NULL,
- .gart_init = &rv370_pcie_gart_init,
- .gart_fini = &rv370_pcie_gart_fini,
- .gart_enable = NULL,
- .gart_disable = NULL,
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
.gart_set_page = &rv370_pcie_gart_set_page,
- .cp_init = NULL,
- .cp_fini = NULL,
- .cp_disable = NULL,
.cp_commit = &r100_cp_commit,
.ring_start = &rv515_ring_start,
.ring_test = &r100_ring_test,
.ring_ib_execute = &r100_ring_ib_execute,
- .ib_test = NULL,
.irq_set = &rs600_irq_set,
.irq_process = &rs600_irq_process,
.get_vblank_counter = &rs600_get_vblank_counter,
@@ -485,28 +377,14 @@ static struct radeon_asic r520_asic = {
.fini = &rv515_fini,
.suspend = &rv515_suspend,
.resume = &r520_resume,
- .errata = NULL,
- .vram_info = NULL,
.vga_set_state = &r100_vga_set_state,
.gpu_reset = &rv515_gpu_reset,
- .mc_init = NULL,
- .mc_fini = NULL,
- .wb_init = NULL,
- .wb_fini = NULL,
- .gart_init = NULL,
- .gart_fini = NULL,
- .gart_enable = NULL,
- .gart_disable = NULL,
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
.gart_set_page = &rv370_pcie_gart_set_page,
- .cp_init = NULL,
- .cp_fini = NULL,
- .cp_disable = NULL,
.cp_commit = &r100_cp_commit,
.ring_start = &rv515_ring_start,
.ring_test = &r100_ring_test,
.ring_ib_execute = &r100_ring_ib_execute,
- .ib_test = NULL,
.irq_set = &rs600_irq_set,
.irq_process = &rs600_irq_process,
.get_vblank_counter = &rs600_get_vblank_counter,
@@ -554,37 +432,23 @@ int r600_set_surface_reg(struct radeon_device *rdev, int reg,
uint32_t offset, uint32_t obj_size);
int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
-int r600_ib_test(struct radeon_device *rdev);
int r600_ring_test(struct radeon_device *rdev);
int r600_copy_blit(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_pages, struct radeon_fence *fence);
static struct radeon_asic r600_asic = {
- .errata = NULL,
.init = &r600_init,
.fini = &r600_fini,
.suspend = &r600_suspend,
.resume = &r600_resume,
.cp_commit = &r600_cp_commit,
- .vram_info = NULL,
.vga_set_state = &r600_vga_set_state,
.gpu_reset = &r600_gpu_reset,
- .mc_init = NULL,
- .mc_fini = NULL,
- .wb_init = &r600_wb_init,
- .wb_fini = &r600_wb_fini,
- .gart_enable = NULL,
- .gart_disable = NULL,
.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
.gart_set_page = &rs600_gart_set_page,
- .cp_init = NULL,
- .cp_fini = NULL,
- .cp_disable = NULL,
- .ring_start = NULL,
.ring_test = &r600_ring_test,
.ring_ib_execute = &r600_ring_ib_execute,
- .ib_test = &r600_ib_test,
.irq_set = &r600_irq_set,
.irq_process = &r600_irq_process,
.fence_ring_emit = &r600_fence_ring_emit,
@@ -611,30 +475,17 @@ int rv770_resume(struct radeon_device *rdev);
int rv770_gpu_reset(struct radeon_device *rdev);
static struct radeon_asic rv770_asic = {
- .errata = NULL,
.init = &rv770_init,
.fini = &rv770_fini,
.suspend = &rv770_suspend,
.resume = &rv770_resume,
.cp_commit = &r600_cp_commit,
- .vram_info = NULL,
.gpu_reset = &rv770_gpu_reset,
.vga_set_state = &r600_vga_set_state,
- .mc_init = NULL,
- .mc_fini = NULL,
- .wb_init = &r600_wb_init,
- .wb_fini = &r600_wb_fini,
- .gart_enable = NULL,
- .gart_disable = NULL,
.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
.gart_set_page = &rs600_gart_set_page,
- .cp_init = NULL,
- .cp_fini = NULL,
- .cp_disable = NULL,
- .ring_start = NULL,
.ring_test = &r600_ring_test,
.ring_ib_execute = &r600_ring_ib_execute,
- .ib_test = &r600_ib_test,
.irq_set = &r600_irq_set,
.irq_process = &r600_irq_process,
.fence_ring_emit = &r600_fence_ring_emit,
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 96e37a6e7ce..34a9b911951 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -33,12 +33,50 @@
/*
* BIOS.
*/
+
+/* If you boot an IGP board with a discrete card as the primary,
+ * the IGP rom is not accessible via the rom bar as the IGP rom is
+ * part of the system bios. On boot, the system bios puts a
+ * copy of the igp rom at the start of vram if a discrete card is
+ * present.
+ */
+static bool igp_read_bios_from_vram(struct radeon_device *rdev)
+{
+ uint8_t __iomem *bios;
+ resource_size_t vram_base;
+ resource_size_t size = 256 * 1024; /* ??? */
+
+ rdev->bios = NULL;
+ vram_base = drm_get_resource_start(rdev->ddev, 0);
+ bios = ioremap(vram_base, size);
+ if (!bios) {
+ DRM_ERROR("Unable to mmap vram\n");
+ return false;
+ }
+
+ if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+ iounmap(bios);
+ DRM_ERROR("bad rom signature\n");
+ return false;
+ }
+ rdev->bios = kmalloc(size, GFP_KERNEL);
+ if (rdev->bios == NULL) {
+ iounmap(bios);
+ DRM_ERROR("kmalloc failed\n");
+ return false;
+ }
+ memcpy(rdev->bios, bios, size);
+ iounmap(bios);
+ return true;
+}
+
static bool radeon_read_bios(struct radeon_device *rdev)
{
uint8_t __iomem *bios;
size_t size;
rdev->bios = NULL;
+ /* XXX: some cards may return 0 for rom size? ddx has a workaround */
bios = pci_map_rom(rdev->pdev, &size);
if (!bios) {
return false;
@@ -341,7 +379,9 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev)
static bool radeon_read_disabled_bios(struct radeon_device *rdev)
{
- if (rdev->family >= CHIP_RV770)
+ if (rdev->flags & RADEON_IS_IGP)
+ return igp_read_bios_from_vram(rdev);
+ else if (rdev->family >= CHIP_RV770)
return r700_read_disabled_bios(rdev);
else if (rdev->family >= CHIP_R600)
return r600_read_disabled_bios(rdev);
@@ -356,7 +396,12 @@ bool radeon_get_bios(struct radeon_device *rdev)
bool r;
uint16_t tmp;
- r = radeon_read_bios(rdev);
+ if (rdev->flags & RADEON_IS_IGP) {
+ r = igp_read_bios_from_vram(rdev);
+ if (r == false)
+ r = radeon_read_bios(rdev);
+ } else
+ r = radeon_read_bios(rdev);
if (r == false) {
r = radeon_read_disabled_bios(rdev);
}
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index 152eef13197..f5c32a766b1 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -411,7 +411,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
R300_PIXCLK_TRANS_ALWAYS_ONb |
R300_PIXCLK_TVO_ALWAYS_ONb |
R300_P2G2CLK_ALWAYS_ONb |
- R300_P2G2CLK_ALWAYS_ONb);
+ R300_P2G2CLK_DAC_ALWAYS_ONb);
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
} else if (rdev->family >= CHIP_RV350) {
tmp = RREG32_PLL(R300_SCLK_CNTL2);
@@ -464,7 +464,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
R300_PIXCLK_TRANS_ALWAYS_ONb |
R300_PIXCLK_TVO_ALWAYS_ONb |
R300_P2G2CLK_ALWAYS_ONb |
- R300_P2G2CLK_ALWAYS_ONb);
+ R300_P2G2CLK_DAC_ALWAYS_ONb);
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
tmp = RREG32_PLL(RADEON_MCLK_MISC);
@@ -654,7 +654,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
R300_PIXCLK_TRANS_ALWAYS_ONb |
R300_PIXCLK_TVO_ALWAYS_ONb |
R300_P2G2CLK_ALWAYS_ONb |
- R300_P2G2CLK_ALWAYS_ONb |
+ R300_P2G2CLK_DAC_ALWAYS_ONb |
R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
} else if (rdev->family >= CHIP_RV350) {
@@ -705,7 +705,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
R300_PIXCLK_TRANS_ALWAYS_ONb |
R300_PIXCLK_TVO_ALWAYS_ONb |
R300_P2G2CLK_ALWAYS_ONb |
- R300_P2G2CLK_ALWAYS_ONb |
+ R300_P2G2CLK_DAC_ALWAYS_ONb |
R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
} else {
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index ec835d56d30..3d667031de6 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -322,10 +322,6 @@ int radeon_asic_init(struct radeon_device *rdev)
case CHIP_RV380:
rdev->asic = &r300_asic;
if (rdev->flags & RADEON_IS_PCIE) {
- rdev->asic->gart_init = &rv370_pcie_gart_init;
- rdev->asic->gart_fini = &rv370_pcie_gart_fini;
- rdev->asic->gart_enable = &rv370_pcie_gart_enable;
- rdev->asic->gart_disable = &rv370_pcie_gart_disable;
rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
}
@@ -485,7 +481,6 @@ void radeon_combios_fini(struct radeon_device *rdev)
static unsigned int radeon_vga_set_decode(void *cookie, bool state)
{
struct radeon_device *rdev = cookie;
-
radeon_vga_set_state(rdev, state);
if (state)
return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
@@ -493,6 +488,29 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state)
else
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
}
+
+void radeon_agp_disable(struct radeon_device *rdev)
+{
+ rdev->flags &= ~RADEON_IS_AGP;
+ if (rdev->family >= CHIP_R600) {
+ DRM_INFO("Forcing AGP to PCIE mode\n");
+ rdev->flags |= RADEON_IS_PCIE;
+ } else if (rdev->family >= CHIP_RV515 ||
+ rdev->family == CHIP_RV380 ||
+ rdev->family == CHIP_RV410 ||
+ rdev->family == CHIP_R423) {
+ DRM_INFO("Forcing AGP to PCIE mode\n");
+ rdev->flags |= RADEON_IS_PCIE;
+ rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+ rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
+ } else {
+ DRM_INFO("Forcing AGP to PCI mode\n");
+ rdev->flags |= RADEON_IS_PCI;
+ rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
+ rdev->asic->gart_set_page = &r100_pci_gart_set_page;
+ }
+}
+
/*
* Radeon device.
*/
@@ -531,32 +549,7 @@ int radeon_device_init(struct radeon_device *rdev,
}
if (radeon_agpmode == -1) {
- rdev->flags &= ~RADEON_IS_AGP;
- if (rdev->family >= CHIP_R600) {
- DRM_INFO("Forcing AGP to PCIE mode\n");
- rdev->flags |= RADEON_IS_PCIE;
- } else if (rdev->family >= CHIP_RV515 ||
- rdev->family == CHIP_RV380 ||
- rdev->family == CHIP_RV410 ||
- rdev->family == CHIP_R423) {
- DRM_INFO("Forcing AGP to PCIE mode\n");
- rdev->flags |= RADEON_IS_PCIE;
- rdev->asic->gart_init = &rv370_pcie_gart_init;
- rdev->asic->gart_fini = &rv370_pcie_gart_fini;
- rdev->asic->gart_enable = &rv370_pcie_gart_enable;
- rdev->asic->gart_disable = &rv370_pcie_gart_disable;
- rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
- rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
- } else {
- DRM_INFO("Forcing AGP to PCI mode\n");
- rdev->flags |= RADEON_IS_PCI;
- rdev->asic->gart_init = &r100_pci_gart_init;
- rdev->asic->gart_fini = &r100_pci_gart_fini;
- rdev->asic->gart_enable = &r100_pci_gart_enable;
- rdev->asic->gart_disable = &r100_pci_gart_disable;
- rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
- rdev->asic->gart_set_page = &r100_pci_gart_set_page;
- }
+ radeon_agp_disable(rdev);
}
/* set DMA mask + need_dma32 flags.
@@ -588,111 +581,27 @@ int radeon_device_init(struct radeon_device *rdev,
DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
- rdev->new_init_path = false;
- r = radeon_init(rdev);
- if (r) {
- return r;
- }
-
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
if (r) {
return -EINVAL;
}
- if (!rdev->new_init_path) {
- /* Setup errata flags */
- radeon_errata(rdev);
- /* Initialize scratch registers */
- radeon_scratch_init(rdev);
- /* Initialize surface registers */
- radeon_surface_init(rdev);
-
- /* BIOS*/
- if (!radeon_get_bios(rdev)) {
- if (ASIC_IS_AVIVO(rdev))
- return -EINVAL;
- }
- if (rdev->is_atom_bios) {
- r = radeon_atombios_init(rdev);
- if (r) {
- return r;
- }
- } else {
- r = radeon_combios_init(rdev);
- if (r) {
- return r;
- }
- }
- /* Reset gpu before posting otherwise ATOM will enter infinite loop */
- if (radeon_gpu_reset(rdev)) {
- /* FIXME: what do we want to do here ? */
- }
- /* check if cards are posted or not */
- if (!radeon_card_posted(rdev) && rdev->bios) {
- DRM_INFO("GPU not posted. posting now...\n");
- if (rdev->is_atom_bios) {
- atom_asic_init(rdev->mode_info.atom_context);
- } else {
- radeon_combios_asic_init(rdev->ddev);
- }
- }
- /* Get clock & vram information */
- radeon_get_clock_info(rdev->ddev);
- radeon_vram_info(rdev);
- /* Initialize clocks */
- r = radeon_clocks_init(rdev);
- if (r) {
- return r;
- }
+ r = radeon_init(rdev);
+ if (r)
+ return r;
- /* Initialize memory controller (also test AGP) */
- r = radeon_mc_init(rdev);
- if (r) {
- return r;
- }
- /* Fence driver */
- r = radeon_fence_driver_init(rdev);
- if (r) {
- return r;
- }
- r = radeon_irq_kms_init(rdev);
- if (r) {
- return r;
- }
- /* Memory manager */
- r = radeon_object_init(rdev);
- if (r) {
- return r;
- }
- r = radeon_gpu_gart_init(rdev);
+ if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
+ /* Acceleration not working on AGP card try again
+ * with fallback to PCI or PCIE GART
+ */
+ radeon_gpu_reset(rdev);
+ radeon_fini(rdev);
+ radeon_agp_disable(rdev);
+ r = radeon_init(rdev);
if (r)
return r;
- /* Initialize GART (initialize after TTM so we can allocate
- * memory through TTM but finalize after TTM) */
- r = radeon_gart_enable(rdev);
- if (r)
- return 0;
- r = radeon_gem_init(rdev);
- if (r)
- return 0;
-
- /* 1M ring buffer */
- r = radeon_cp_init(rdev, 1024 * 1024);
- if (r)
- return 0;
- r = radeon_wb_init(rdev);
- if (r)
- DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
- r = radeon_ib_pool_init(rdev);
- if (r)
- return 0;
- r = radeon_ib_test(rdev);
- if (r)
- return 0;
- rdev->accel_working = true;
}
- DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
if (radeon_testing) {
radeon_test_moves(rdev);
}
@@ -706,32 +615,8 @@ void radeon_device_fini(struct radeon_device *rdev)
{
DRM_INFO("radeon: finishing device.\n");
rdev->shutdown = true;
- /* Order matter so becarefull if you rearrange anythings */
- if (!rdev->new_init_path) {
- radeon_ib_pool_fini(rdev);
- radeon_cp_fini(rdev);
- radeon_wb_fini(rdev);
- radeon_gpu_gart_fini(rdev);
- radeon_gem_fini(rdev);
- radeon_mc_fini(rdev);
-#if __OS_HAS_AGP
- radeon_agp_fini(rdev);
-#endif
- radeon_irq_kms_fini(rdev);
- vga_client_register(rdev->pdev, NULL, NULL, NULL);
- radeon_fence_driver_fini(rdev);
- radeon_clocks_fini(rdev);
- radeon_object_fini(rdev);
- if (rdev->is_atom_bios) {
- radeon_atombios_fini(rdev);
- } else {
- radeon_combios_fini(rdev);
- }
- kfree(rdev->bios);
- rdev->bios = NULL;
- } else {
- radeon_fini(rdev);
- }
+ radeon_fini(rdev);
+ vga_client_register(rdev->pdev, NULL, NULL, NULL);
iounmap(rdev->rmmio);
rdev->rmmio = NULL;
}
@@ -771,14 +656,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
radeon_save_bios_scratch_regs(rdev);
- if (!rdev->new_init_path) {
- radeon_cp_disable(rdev);
- radeon_gart_disable(rdev);
- rdev->irq.sw_int = false;
- radeon_irq_set(rdev);
- } else {
- radeon_suspend(rdev);
- }
+ radeon_suspend(rdev);
/* evict remaining vram memory */
radeon_object_evict_vram(rdev);
@@ -797,7 +675,6 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
int radeon_resume_kms(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
- int r;
acquire_console_sem();
pci_set_power_state(dev->pdev, PCI_D0);
@@ -807,43 +684,7 @@ int radeon_resume_kms(struct drm_device *dev)
return -1;
}
pci_set_master(dev->pdev);
- /* Reset gpu before posting otherwise ATOM will enter infinite loop */
- if (!rdev->new_init_path) {
- if (radeon_gpu_reset(rdev)) {
- /* FIXME: what do we want to do here ? */
- }
- /* post card */
- if (rdev->is_atom_bios) {
- atom_asic_init(rdev->mode_info.atom_context);
- } else {
- radeon_combios_asic_init(rdev->ddev);
- }
- /* Initialize clocks */
- r = radeon_clocks_init(rdev);
- if (r) {
- release_console_sem();
- return r;
- }
- /* Enable IRQ */
- rdev->irq.sw_int = true;
- radeon_irq_set(rdev);
- /* Initialize GPU Memory Controller */
- r = radeon_mc_init(rdev);
- if (r) {
- goto out;
- }
- r = radeon_gart_enable(rdev);
- if (r) {
- goto out;
- }
- r = radeon_cp_init(rdev, rdev->cp.ring_size);
- if (r) {
- goto out;
- }
- } else {
- radeon_resume(rdev);
- }
-out:
+ radeon_resume(rdev);
radeon_restore_bios_scratch_regs(rdev);
fb_set_suspend(rdev->fbdev_info, 0);
release_console_sem();
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 5d8141b1376..3655d91993a 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -106,24 +106,33 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc)
legacy_crtc_load_lut(crtc);
}
-/** Sets the color ramps on behalf of RandR */
+/** Sets the color ramps on behalf of fbcon */
void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
- if (regno == 0)
- DRM_DEBUG("gamma set %d\n", radeon_crtc->crtc_id);
radeon_crtc->lut_r[regno] = red >> 6;
radeon_crtc->lut_g[regno] = green >> 6;
radeon_crtc->lut_b[regno] = blue >> 6;
}
+/** Gets the color ramps on behalf of fbcon */
+void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+
+ *red = radeon_crtc->lut_r[regno] << 6;
+ *green = radeon_crtc->lut_g[regno] << 6;
+ *blue = radeon_crtc->lut_b[regno] << 6;
+}
+
static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
- int i, j;
+ int i;
if (size != 256) {
return;
@@ -132,23 +141,11 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
return;
}
- if (crtc->fb->depth == 16) {
- for (i = 0; i < 64; i++) {
- if (i <= 31) {
- for (j = 0; j < 8; j++) {
- radeon_crtc->lut_r[i * 8 + j] = red[i] >> 6;
- radeon_crtc->lut_b[i * 8 + j] = blue[i] >> 6;
- }
- }
- for (j = 0; j < 4; j++)
- radeon_crtc->lut_g[i * 4 + j] = green[i] >> 6;
- }
- } else {
- for (i = 0; i < 256; i++) {
- radeon_crtc->lut_r[i] = red[i] >> 6;
- radeon_crtc->lut_g[i] = green[i] >> 6;
- radeon_crtc->lut_b[i] = blue[i] >> 6;
- }
+ /* userspace palettes are always correct as is */
+ for (i = 0; i < 256; i++) {
+ radeon_crtc->lut_r[i] = red[i] >> 6;
+ radeon_crtc->lut_g[i] = green[i] >> 6;
+ radeon_crtc->lut_b[i] = blue[i] >> 6;
}
radeon_crtc_load_lut(crtc);
@@ -724,7 +721,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
if (ret) {
return ret;
}
- /* allocate crtcs - TODO single crtc */
+
+ if (rdev->flags & RADEON_SINGLE_CRTC)
+ num_crtc = 1;
+
+ /* allocate crtcs */
for (i = 0; i < num_crtc; i++) {
radeon_crtc_init(rdev->ddev, i);
}
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 621646752cd..a65ab1a0dad 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1345,6 +1345,7 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
void
radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
{
+ struct radeon_device *rdev = dev->dev_private;
struct drm_encoder *encoder;
struct radeon_encoder *radeon_encoder;
@@ -1364,7 +1365,10 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
return;
encoder = &radeon_encoder->base;
- encoder->possible_crtcs = 0x3;
+ if (rdev->flags & RADEON_SINGLE_CRTC)
+ encoder->possible_crtcs = 0x1;
+ else
+ encoder->possible_crtcs = 0x3;
encoder->possible_clones = 0;
radeon_encoder->enc_priv = NULL;
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 1ba704eedef..b38c4c8e2c6 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -55,6 +55,7 @@ static struct fb_ops radeonfb_ops = {
.fb_imageblit = cfb_imageblit,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
+ .fb_setcmap = drm_fb_helper_setcmap,
};
/**
@@ -123,6 +124,7 @@ static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bo
static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
.gamma_set = radeon_crtc_fb_gamma_set,
+ .gamma_get = radeon_crtc_fb_gamma_get,
};
int radeonfb_create(struct drm_device *dev,
@@ -146,9 +148,15 @@ int radeonfb_create(struct drm_device *dev,
unsigned long tmp;
bool fb_tiled = false; /* useful for testing */
u32 tiling_flags = 0;
+ int crtc_count;
mode_cmd.width = surface_width;
mode_cmd.height = surface_height;
+
+ /* avivo can't scanout real 24bpp */
+ if ((surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
+ surface_bpp = 32;
+
mode_cmd.bpp = surface_bpp;
/* need to align pitch with crtc limits */
mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8);
@@ -217,7 +225,11 @@ int radeonfb_create(struct drm_device *dev,
rfbdev = info->par;
rfbdev->helper.funcs = &radeon_fb_helper_funcs;
rfbdev->helper.dev = dev;
- ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, 2,
+ if (rdev->flags & RADEON_SINGLE_CRTC)
+ crtc_count = 1;
+ else
+ crtc_count = 2;
+ ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, crtc_count,
RADEONFB_CONN_LIMIT);
if (ret)
goto out_unref;
@@ -234,7 +246,7 @@ int radeonfb_create(struct drm_device *dev,
strcpy(info->fix.id, "radeondrmfb");
- drm_fb_helper_fill_fix(info, fb->pitch);
+ drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
info->flags = FBINFO_DEFAULT;
info->fbops = &radeonfb_ops;
@@ -309,7 +321,7 @@ int radeon_parse_options(char *options)
int radeonfb_probe(struct drm_device *dev)
{
- return drm_fb_helper_single_fb_probe(dev, &radeonfb_create);
+ return drm_fb_helper_single_fb_probe(dev, 32, &radeonfb_create);
}
int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 1841145a7c4..8e0a8759e42 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -83,8 +83,12 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
int radeon_irq_kms_init(struct radeon_device *rdev)
{
int r = 0;
+ int num_crtc = 2;
- r = drm_vblank_init(rdev->ddev, 2);
+ if (rdev->flags & RADEON_SINGLE_CRTC)
+ num_crtc = 1;
+
+ r = drm_vblank_init(rdev->ddev, num_crtc);
if (r) {
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 2b997a15fb1..36410f85d70 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -1053,6 +1053,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
.mode_set_base = radeon_crtc_set_base,
.prepare = radeon_crtc_prepare,
.commit = radeon_crtc_commit,
+ .load_lut = radeon_crtc_load_lut,
};
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index b1547f700d7..6ceb958fd19 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -881,7 +881,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
R420_TV_DAC_DACADJ_MASK |
R420_TV_DAC_RDACPD |
R420_TV_DAC_GDACPD |
- R420_TV_DAC_GDACPD |
+ R420_TV_DAC_BDACPD |
R420_TV_DAC_TVENABLE);
} else {
tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
@@ -889,7 +889,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
RADEON_TV_DAC_DACADJ_MASK |
RADEON_TV_DAC_RDACPD |
RADEON_TV_DAC_GDACPD |
- RADEON_TV_DAC_GDACPD);
+ RADEON_TV_DAC_BDACPD);
}
/* FIXME TV */
@@ -1318,7 +1318,10 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
return;
encoder = &radeon_encoder->base;
- encoder->possible_crtcs = 0x3;
+ if (rdev->flags & RADEON_SINGLE_CRTC)
+ encoder->possible_crtcs = 0x1;
+ else
+ encoder->possible_crtcs = 0x3;
encoder->possible_clones = 0;
radeon_encoder->enc_priv = NULL;
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 570a58729da..e61226817cc 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -407,6 +407,8 @@ extern void
radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on);
extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno);
+extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno);
struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd *mode_cmd,
struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 73af463b7a5..1f056dadc5c 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -400,11 +400,9 @@ void radeon_object_list_add_object(struct radeon_object_list *lobj,
int radeon_object_list_reserve(struct list_head *head)
{
struct radeon_object_list *lobj;
- struct list_head *i;
int r;
- list_for_each(i, head) {
- lobj = list_entry(i, struct radeon_object_list, list);
+ list_for_each_entry(lobj, head, list){
if (!lobj->robj->pin_count) {
r = radeon_object_reserve(lobj->robj, true);
if (unlikely(r != 0)) {
@@ -420,13 +418,10 @@ int radeon_object_list_reserve(struct list_head *head)
void radeon_object_list_unreserve(struct list_head *head)
{
struct radeon_object_list *lobj;
- struct list_head *i;
- list_for_each(i, head) {
- lobj = list_entry(i, struct radeon_object_list, list);
+ list_for_each_entry(lobj, head, list) {
if (!lobj->robj->pin_count) {
radeon_object_unreserve(lobj->robj);
- } else {
}
}
}
@@ -436,7 +431,6 @@ int radeon_object_list_validate(struct list_head *head, void *fence)
struct radeon_object_list *lobj;
struct radeon_object *robj;
struct radeon_fence *old_fence = NULL;
- struct list_head *i;
int r;
r = radeon_object_list_reserve(head);
@@ -444,8 +438,7 @@ int radeon_object_list_validate(struct list_head *head, void *fence)
radeon_object_list_unreserve(head);
return r;
}
- list_for_each(i, head) {
- lobj = list_entry(i, struct radeon_object_list, list);
+ list_for_each_entry(lobj, head, list) {
robj = lobj->robj;
if (!robj->pin_count) {
if (lobj->wdomain) {
@@ -482,10 +475,8 @@ void radeon_object_list_unvalidate(struct list_head *head)
{
struct radeon_object_list *lobj;
struct radeon_fence *old_fence = NULL;
- struct list_head *i;
- list_for_each(i, head) {
- lobj = list_entry(i, struct radeon_object_list, list);
+ list_for_each_entry(lobj, head, list) {
old_fence = (struct radeon_fence *)lobj->robj->tobj.sync_obj;
lobj->robj->tobj.sync_obj = NULL;
if (old_fence) {
diff --git a/drivers/gpu/drm/radeon/rs100d.h b/drivers/gpu/drm/radeon/rs100d.h
new file mode 100644
index 00000000000..48a913a06cf
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs100d.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ */
+#ifndef __RS100D_H__
+#define __RS100D_H__
+
+/* Registers */
+#define R_00015C_NB_TOM 0x00015C
+#define S_00015C_MC_FB_START(x) (((x) & 0xFFFF) << 0)
+#define G_00015C_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
+#define C_00015C_MC_FB_START 0xFFFF0000
+#define S_00015C_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
+#define G_00015C_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
+#define C_00015C_MC_FB_TOP 0x0000FFFF
+
+#endif
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index a3fbdad938c..a769c296f6a 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -27,27 +27,12 @@
*/
#include <linux/seq_file.h>
#include <drm/drmP.h>
-#include "radeon_reg.h"
#include "radeon.h"
+#include "rs400d.h"
-/* rs400,rs480 depends on : */
-void r100_hdp_reset(struct radeon_device *rdev);
-void r100_mc_disable_clients(struct radeon_device *rdev);
-int r300_mc_wait_for_idle(struct radeon_device *rdev);
-void r420_pipes_init(struct radeon_device *rdev);
+/* This files gather functions specifics to : rs400,rs480 */
+static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
-/* This files gather functions specifics to :
- * rs400,rs480
- *
- * Some of these functions might be used by newer ASICs.
- */
-void rs400_gpu_init(struct radeon_device *rdev);
-int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
-
-
-/*
- * GART functions.
- */
void rs400_gart_adjust_size(struct radeon_device *rdev)
{
/* Check gart size */
@@ -238,61 +223,6 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
return 0;
}
-
-/*
- * MC functions.
- */
-int rs400_mc_init(struct radeon_device *rdev)
-{
- uint32_t tmp;
- int r;
-
- if (r100_debugfs_rbbm_init(rdev)) {
- DRM_ERROR("Failed to register debugfs file for RBBM !\n");
- }
-
- rs400_gpu_init(rdev);
- rs400_gart_disable(rdev);
- rdev->mc.gtt_location = rdev->mc.mc_vram_size;
- rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
- rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
- r = radeon_mc_setup(rdev);
- if (r) {
- return r;
- }
-
- r100_mc_disable_clients(rdev);
- if (r300_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "Failed to wait MC idle while "
- "programming pipes. Bad things might happen.\n");
- }
-
- tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
- tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
- tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
- WREG32(RADEON_MC_FB_LOCATION, tmp);
- tmp = RREG32(RADEON_HOST_PATH_CNTL) | RADEON_HP_LIN_RD_CACHE_DIS;
- WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
- (void)RREG32(RADEON_HOST_PATH_CNTL);
- WREG32(RADEON_HOST_PATH_CNTL, tmp);
- (void)RREG32(RADEON_HOST_PATH_CNTL);
-
- return 0;
-}
-
-void rs400_mc_fini(struct radeon_device *rdev)
-{
-}
-
-
-/*
- * Global GPU functions
- */
-void rs400_errata(struct radeon_device *rdev)
-{
- rdev->pll_errata = 0;
-}
-
void rs400_gpu_init(struct radeon_device *rdev)
{
/* FIXME: HDP same place on rs400 ? */
@@ -305,10 +235,6 @@ void rs400_gpu_init(struct radeon_device *rdev)
}
}
-
-/*
- * VRAM info.
- */
void rs400_vram_info(struct radeon_device *rdev)
{
rs400_gart_adjust_size(rdev);
@@ -319,10 +245,6 @@ void rs400_vram_info(struct radeon_device *rdev)
r100_vram_init_sizes(rdev);
}
-
-/*
- * Indirect registers accessor
- */
uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)
{
uint32_t r;
@@ -340,10 +262,6 @@ void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
WREG32(RS480_NB_MC_INDEX, 0xff);
}
-
-/*
- * Debugfs info
- */
#if defined(CONFIG_DEBUG_FS)
static int rs400_debugfs_gart_info(struct seq_file *m, void *data)
{
@@ -419,7 +337,7 @@ static struct drm_info_list rs400_gart_info_list[] = {
};
#endif
-int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
+static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
{
#if defined(CONFIG_DEBUG_FS)
return radeon_debugfs_add_files(rdev, rs400_gart_info_list, 1);
@@ -427,3 +345,188 @@ int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
return 0;
#endif
}
+
+static int rs400_mc_init(struct radeon_device *rdev)
+{
+ int r;
+ u32 tmp;
+
+ /* Setup GPU memory space */
+ tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
+ rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
+ rdev->mc.gtt_location = 0xFFFFFFFFUL;
+ r = radeon_mc_setup(rdev);
+ if (r)
+ return r;
+ return 0;
+}
+
+void rs400_mc_program(struct radeon_device *rdev)
+{
+ struct r100_mc_save save;
+
+ /* Stops all mc clients */
+ r100_mc_stop(rdev, &save);
+
+ /* Wait for mc idle */
+ if (r300_mc_wait_for_idle(rdev))
+ dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
+ WREG32(R_000148_MC_FB_LOCATION,
+ S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
+ S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
+
+ r100_mc_resume(rdev, &save);
+}
+
+static int rs400_startup(struct radeon_device *rdev)
+{
+ int r;
+
+ rs400_mc_program(rdev);
+ /* Resume clock */
+ r300_clock_startup(rdev);
+ /* Initialize GPU configuration (# pipes, ...) */
+ rs400_gpu_init(rdev);
+ /* Initialize GART (initialize after TTM so we can allocate
+ * memory through TTM but finalize after TTM) */
+ r = rs400_gart_enable(rdev);
+ if (r)
+ return r;
+ /* Enable IRQ */
+ rdev->irq.sw_int = true;
+ r100_irq_set(rdev);
+ /* 1M ring buffer */
+ r = r100_cp_init(rdev, 1024 * 1024);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+ return r;
+ }
+ r = r100_wb_init(rdev);
+ if (r)
+ dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+ r = r100_ib_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+ return r;
+ }
+ return 0;
+}
+
+int rs400_resume(struct radeon_device *rdev)
+{
+ /* Make sur GART are not working */
+ rs400_gart_disable(rdev);
+ /* Resume clock before doing reset */
+ r300_clock_startup(rdev);
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* post */
+ radeon_combios_asic_init(rdev->ddev);
+ /* Resume clock after posting */
+ r300_clock_startup(rdev);
+ return rs400_startup(rdev);
+}
+
+int rs400_suspend(struct radeon_device *rdev)
+{
+ r100_cp_disable(rdev);
+ r100_wb_disable(rdev);
+ r100_irq_disable(rdev);
+ rs400_gart_disable(rdev);
+ return 0;
+}
+
+void rs400_fini(struct radeon_device *rdev)
+{
+ rs400_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ radeon_gem_fini(rdev);
+ rs400_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_object_fini(rdev);
+ radeon_atombios_fini(rdev);
+ kfree(rdev->bios);
+ rdev->bios = NULL;
+}
+
+int rs400_init(struct radeon_device *rdev)
+{
+ int r;
+
+ /* Disable VGA */
+ r100_vga_render_disable(rdev);
+ /* Initialize scratch registers */
+ radeon_scratch_init(rdev);
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* TODO: disable VGA need to use VGA request */
+ /* BIOS*/
+ if (!radeon_get_bios(rdev)) {
+ if (ASIC_IS_AVIVO(rdev))
+ return -EINVAL;
+ }
+ if (rdev->is_atom_bios) {
+ dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
+ return -EINVAL;
+ } else {
+ r = radeon_combios_init(rdev);
+ if (r)
+ return r;
+ }
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev,
+ "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* check if cards are posted or not */
+ if (!radeon_card_posted(rdev) && rdev->bios) {
+ DRM_INFO("GPU not posted. posting now...\n");
+ radeon_combios_asic_init(rdev->ddev);
+ }
+ /* Initialize clocks */
+ radeon_get_clock_info(rdev->ddev);
+ /* Get vram informations */
+ rs400_vram_info(rdev);
+ /* Initialize memory controller (also test AGP) */
+ r = rs400_mc_init(rdev);
+ if (r)
+ return r;
+ /* Fence driver */
+ r = radeon_fence_driver_init(rdev);
+ if (r)
+ return r;
+ r = radeon_irq_kms_init(rdev);
+ if (r)
+ return r;
+ /* Memory manager */
+ r = radeon_object_init(rdev);
+ if (r)
+ return r;
+ r = rs400_gart_init(rdev);
+ if (r)
+ return r;
+ r300_set_reg_safe(rdev);
+ rdev->accel_working = true;
+ r = rs400_startup(rdev);
+ if (r) {
+ /* Somethings want wront with the accel init stop accel */
+ dev_err(rdev->dev, "Disabling GPU acceleration\n");
+ rs400_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ rs400_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rdev->accel_working = false;
+ }
+ return 0;
+}
diff --git a/drivers/gpu/drm/radeon/rs400d.h b/drivers/gpu/drm/radeon/rs400d.h
new file mode 100644
index 00000000000..6d8bac58ced
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs400d.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ */
+#ifndef __RS400D_H__
+#define __RS400D_H__
+
+/* Registers */
+#define R_000148_MC_FB_LOCATION 0x000148
+#define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0)
+#define G_000148_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
+#define C_000148_MC_FB_START 0xFFFF0000
+#define S_000148_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
+#define G_000148_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
+#define C_000148_MC_FB_TOP 0x0000FFFF
+#define R_00015C_NB_TOM 0x00015C
+#define S_00015C_MC_FB_START(x) (((x) & 0xFFFF) << 0)
+#define G_00015C_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
+#define C_00015C_MC_FB_START 0xFFFF0000
+#define S_00015C_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
+#define G_00015C_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
+#define C_00015C_MC_FB_TOP 0x0000FFFF
+#define R_0007C0_CP_STAT 0x0007C0
+#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
+#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
+#define C_0007C0_MRU_BUSY 0xFFFFFFFE
+#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
+#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
+#define C_0007C0_MWU_BUSY 0xFFFFFFFD
+#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
+#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
+#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
+#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
+#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
+#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
+#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
+#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
+#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
+#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
+#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
+#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
+#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
+#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
+#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
+#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
+#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
+#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
+#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
+#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
+#define C_0007C0_CSI_BUSY 0xFFFFDFFF
+#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
+#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
+#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
+#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
+#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
+#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
+#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
+#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
+#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
+#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
+#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
+#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
+#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
+#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
+#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
+#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
+#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
+#define C_0007C0_CP_BUSY 0x7FFFFFFF
+#define R_000E40_RBBM_STATUS 0x000E40
+#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
+#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
+#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
+#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
+#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
+#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
+#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
+#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
+#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
+#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
+#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
+#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
+#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
+#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
+#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
+#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
+#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
+#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
+#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
+#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
+#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
+#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
+#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
+#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
+#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
+#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
+#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
+#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
+#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
+#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
+#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
+#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
+#define C_000E40_E2_BUSY 0xFFFDFFFF
+#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
+#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
+#define C_000E40_RB2D_BUSY 0xFFFBFFFF
+#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
+#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
+#define C_000E40_RB3D_BUSY 0xFFF7FFFF
+#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
+#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
+#define C_000E40_VAP_BUSY 0xFFEFFFFF
+#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
+#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
+#define C_000E40_RE_BUSY 0xFFDFFFFF
+#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
+#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
+#define C_000E40_TAM_BUSY 0xFFBFFFFF
+#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
+#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
+#define C_000E40_TDM_BUSY 0xFF7FFFFF
+#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
+#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
+#define C_000E40_PB_BUSY 0xFEFFFFFF
+#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
+#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
+#define C_000E40_TIM_BUSY 0xFDFFFFFF
+#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
+#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
+#define C_000E40_GA_BUSY 0xFBFFFFFF
+#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
+#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
+#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
+#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
+#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
+#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
+
+#endif
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 4a4fe1cb131..10dfa78762d 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -25,27 +25,26 @@
* Alex Deucher
* Jerome Glisse
*/
+/* RS600 / Radeon X1250/X1270 integrated GPU
+ *
+ * This file gather function specific to RS600 which is the IGP of
+ * the X1250/X1270 family supporting intel CPU (while RS690/RS740
+ * is the X1250/X1270 supporting AMD CPU). The display engine are
+ * the avivo one, bios is an atombios, 3D block are the one of the
+ * R4XX family. The GART is different from the RS400 one and is very
+ * close to the one of the R600 family (R600 likely being an evolution
+ * of the RS600 GART block).
+ */
#include "drmP.h"
-#include "radeon_reg.h"
#include "radeon.h"
+#include "atom.h"
+#include "rs600d.h"
#include "rs600_reg_safe.h"
-/* rs600 depends on : */
-void r100_hdp_reset(struct radeon_device *rdev);
-int r100_gui_wait_for_idle(struct radeon_device *rdev);
-int r300_mc_wait_for_idle(struct radeon_device *rdev);
-void r420_pipes_init(struct radeon_device *rdev);
-
-/* This files gather functions specifics to :
- * rs600
- *
- * Some of these functions might be used by newer ASICs.
- */
void rs600_gpu_init(struct radeon_device *rdev);
int rs600_mc_wait_for_idle(struct radeon_device *rdev);
-
/*
* GART.
*/
@@ -53,18 +52,18 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
{
uint32_t tmp;
- tmp = RREG32_MC(RS600_MC_PT0_CNTL);
- tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
- WREG32_MC(RS600_MC_PT0_CNTL, tmp);
+ tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
+ tmp &= C_000100_INVALIDATE_ALL_L1_TLBS & C_000100_INVALIDATE_L2_CACHE;
+ WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
- tmp = RREG32_MC(RS600_MC_PT0_CNTL);
- tmp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE;
- WREG32_MC(RS600_MC_PT0_CNTL, tmp);
+ tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
+ tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1);
+ WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
- tmp = RREG32_MC(RS600_MC_PT0_CNTL);
- tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
- WREG32_MC(RS600_MC_PT0_CNTL, tmp);
- tmp = RREG32_MC(RS600_MC_PT0_CNTL);
+ tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
+ tmp &= C_000100_INVALIDATE_ALL_L1_TLBS & C_000100_INVALIDATE_L2_CACHE;
+ WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
+ tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
}
int rs600_gart_init(struct radeon_device *rdev)
@@ -86,7 +85,7 @@ int rs600_gart_init(struct radeon_device *rdev)
int rs600_gart_enable(struct radeon_device *rdev)
{
- uint32_t tmp;
+ u32 tmp;
int r, i;
if (rdev->gart.table.vram.robj == NULL) {
@@ -96,46 +95,50 @@ int rs600_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
+ /* Enable bus master */
+ tmp = RREG32(R_00004C_BUS_CNTL) & C_00004C_BUS_MASTER_DIS;
+ WREG32(R_00004C_BUS_CNTL, tmp);
/* FIXME: setup default page */
- WREG32_MC(RS600_MC_PT0_CNTL,
- (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
- RS600_EFFECTIVE_L2_QUEUE_SIZE(6)));
+ WREG32_MC(R_000100_MC_PT0_CNTL,
+ (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
+ S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
for (i = 0; i < 19; i++) {
- WREG32_MC(RS600_MC_PT0_CLIENT0_CNTL + i,
- (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE |
- RS600_SYSTEM_ACCESS_MODE_IN_SYS |
- RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE |
- RS600_EFFECTIVE_L1_CACHE_SIZE(3) |
- RS600_ENABLE_FRAGMENT_PROCESSING |
- RS600_EFFECTIVE_L1_QUEUE_SIZE(3)));
+ WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i,
+ S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
+ S_00016C_SYSTEM_ACCESS_MODE_MASK(
+ V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) |
+ S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
+ V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) |
+ S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) |
+ S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
+ S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1));
}
/* System context map to GART space */
- WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_location);
- tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
- WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, tmp);
+ WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start);
+ WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end);
/* enable first context */
- WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_location);
- tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
- WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, tmp);
- WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL,
- (RS600_ENABLE_PAGE_TABLE | RS600_PAGE_TABLE_TYPE_FLAT));
+ WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
+ WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
+ WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL,
+ S_000102_ENABLE_PAGE_TABLE(1) |
+ S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
/* disable all other contexts */
for (i = 1; i < 8; i++) {
- WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL + i, 0);
+ WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0);
}
/* setup the page table */
- WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
- rdev->gart.table_addr);
- WREG32_MC(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
+ WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
+ rdev->gart.table_addr);
+ WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
/* enable page tables */
- tmp = RREG32_MC(RS600_MC_PT0_CNTL);
- WREG32_MC(RS600_MC_PT0_CNTL, (tmp | RS600_ENABLE_PT));
- tmp = RREG32_MC(RS600_MC_CNTL1);
- WREG32_MC(RS600_MC_CNTL1, (tmp | RS600_ENABLE_PAGE_TABLES));
+ tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
+ WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1)));
+ tmp = RREG32_MC(R_000009_MC_CNTL1);
+ WREG32_MC(R_000009_MC_CNTL1, (tmp | S_000009_ENABLE_PAGE_TABLES(1)));
rs600_gart_tlb_flush(rdev);
rdev->gart.ready = true;
return 0;
@@ -146,10 +149,9 @@ void rs600_gart_disable(struct radeon_device *rdev)
uint32_t tmp;
/* FIXME: disable out of gart access */
- WREG32_MC(RS600_MC_PT0_CNTL, 0);
- tmp = RREG32_MC(RS600_MC_CNTL1);
- tmp &= ~RS600_ENABLE_PAGE_TABLES;
- WREG32_MC(RS600_MC_CNTL1, tmp);
+ WREG32_MC(R_000100_MC_PT0_CNTL, 0);
+ tmp = RREG32_MC(R_000009_MC_CNTL1);
+ WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES);
if (rdev->gart.table.vram.robj) {
radeon_object_kunmap(rdev->gart.table.vram.robj);
radeon_object_unpin(rdev->gart.table.vram.robj);
@@ -183,129 +185,61 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
return 0;
}
-
-/*
- * MC.
- */
-void rs600_mc_disable_clients(struct radeon_device *rdev)
-{
- unsigned tmp;
-
- if (r100_gui_wait_for_idle(rdev)) {
- printk(KERN_WARNING "Failed to wait GUI idle while "
- "programming pipes. Bad things might happen.\n");
- }
-
- rv515_vga_render_disable(rdev);
-
- tmp = RREG32(AVIVO_D1VGA_CONTROL);
- WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
- tmp = RREG32(AVIVO_D2VGA_CONTROL);
- WREG32(AVIVO_D2VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
-
- tmp = RREG32(AVIVO_D1CRTC_CONTROL);
- WREG32(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
- tmp = RREG32(AVIVO_D2CRTC_CONTROL);
- WREG32(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
-
- /* make sure all previous write got through */
- tmp = RREG32(AVIVO_D2CRTC_CONTROL);
-
- mdelay(1);
-}
-
-int rs600_mc_init(struct radeon_device *rdev)
-{
- uint32_t tmp;
- int r;
-
- if (r100_debugfs_rbbm_init(rdev)) {
- DRM_ERROR("Failed to register debugfs file for RBBM !\n");
- }
-
- rs600_gpu_init(rdev);
- rs600_gart_disable(rdev);
-
- /* Setup GPU memory space */
- rdev->mc.vram_location = 0xFFFFFFFFUL;
- rdev->mc.gtt_location = 0xFFFFFFFFUL;
- r = radeon_mc_setup(rdev);
- if (r) {
- return r;
- }
-
- /* Program GPU memory space */
- /* Enable bus master */
- tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
- WREG32(RADEON_BUS_CNTL, tmp);
- /* FIXME: What does AGP means for such chipset ? */
- WREG32_MC(RS600_MC_AGP_LOCATION, 0x0FFFFFFF);
- /* FIXME: are this AGP reg in indirect MC range ? */
- WREG32_MC(RS600_MC_AGP_BASE, 0);
- WREG32_MC(RS600_MC_AGP_BASE_2, 0);
- rs600_mc_disable_clients(rdev);
- if (rs600_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "Failed to wait MC idle while "
- "programming pipes. Bad things might happen.\n");
- }
- tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
- tmp = REG_SET(RS600_MC_FB_TOP, tmp >> 16);
- tmp |= REG_SET(RS600_MC_FB_START, rdev->mc.vram_location >> 16);
- WREG32_MC(RS600_MC_FB_LOCATION, tmp);
- WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
- return 0;
-}
-
-void rs600_mc_fini(struct radeon_device *rdev)
-{
-}
-
-
-/*
- * Interrupts
- */
int rs600_irq_set(struct radeon_device *rdev)
{
uint32_t tmp = 0;
uint32_t mode_int = 0;
if (rdev->irq.sw_int) {
- tmp |= RADEON_SW_INT_ENABLE;
+ tmp |= S_000040_SW_INT_EN(1);
}
if (rdev->irq.crtc_vblank_int[0]) {
- mode_int |= AVIVO_D1MODE_INT_MASK;
+ mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1);
}
if (rdev->irq.crtc_vblank_int[1]) {
- mode_int |= AVIVO_D2MODE_INT_MASK;
+ mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1);
}
- WREG32(RADEON_GEN_INT_CNTL, tmp);
- WREG32(AVIVO_DxMODE_INT_MASK, mode_int);
+ WREG32(R_000040_GEN_INT_CNTL, tmp);
+ WREG32(R_006540_DxMODE_INT_MASK, mode_int);
return 0;
}
static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int)
{
- uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
- uint32_t irq_mask = RADEON_SW_INT_TEST;
-
- if (irqs & AVIVO_DISPLAY_INT_STATUS) {
- *r500_disp_int = RREG32(AVIVO_DISP_INTERRUPT_STATUS);
- if (*r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) {
- WREG32(AVIVO_D1MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK);
+ uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS);
+ uint32_t irq_mask = ~C_000044_SW_INT;
+
+ if (G_000044_DISPLAY_INT_STAT(irqs)) {
+ *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS);
+ if (G_007EDC_LB_D1_VBLANK_INTERRUPT(*r500_disp_int)) {
+ WREG32(R_006534_D1MODE_VBLANK_STATUS,
+ S_006534_D1MODE_VBLANK_ACK(1));
}
- if (*r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) {
- WREG32(AVIVO_D2MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK);
+ if (G_007EDC_LB_D2_VBLANK_INTERRUPT(*r500_disp_int)) {
+ WREG32(R_006D34_D2MODE_VBLANK_STATUS,
+ S_006D34_D2MODE_VBLANK_ACK(1));
}
} else {
*r500_disp_int = 0;
}
if (irqs) {
- WREG32(RADEON_GEN_INT_STATUS, irqs);
+ WREG32(R_000044_GEN_INT_STATUS, irqs);
}
return irqs & irq_mask;
}
+void rs600_irq_disable(struct radeon_device *rdev)
+{
+ u32 tmp;
+
+ WREG32(R_000040_GEN_INT_CNTL, 0);
+ WREG32(R_006540_DxMODE_INT_MASK, 0);
+ /* Wait and acknowledge irq */
+ mdelay(1);
+ rs600_irq_ack(rdev, &tmp);
+}
+
int rs600_irq_process(struct radeon_device *rdev)
{
uint32_t status;
@@ -317,16 +251,13 @@ int rs600_irq_process(struct radeon_device *rdev)
}
while (status || r500_disp_int) {
/* SW interrupt */
- if (status & RADEON_SW_INT_TEST) {
+ if (G_000040_SW_INT_EN(status))
radeon_fence_process(rdev);
- }
/* Vertical blank interrupts */
- if (r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) {
+ if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int))
drm_handle_vblank(rdev->ddev, 0);
- }
- if (r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) {
+ if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int))
drm_handle_vblank(rdev->ddev, 1);
- }
status = rs600_irq_ack(rdev, &r500_disp_int);
}
return IRQ_HANDLED;
@@ -335,53 +266,34 @@ int rs600_irq_process(struct radeon_device *rdev)
u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc)
{
if (crtc == 0)
- return RREG32(AVIVO_D1CRTC_FRAME_COUNT);
+ return RREG32(R_0060A4_D1CRTC_STATUS_FRAME_COUNT);
else
- return RREG32(AVIVO_D2CRTC_FRAME_COUNT);
+ return RREG32(R_0068A4_D2CRTC_STATUS_FRAME_COUNT);
}
-
-/*
- * Global GPU functions
- */
int rs600_mc_wait_for_idle(struct radeon_device *rdev)
{
unsigned i;
- uint32_t tmp;
for (i = 0; i < rdev->usec_timeout; i++) {
- /* read MC_STATUS */
- tmp = RREG32_MC(RS600_MC_STATUS);
- if (tmp & RS600_MC_STATUS_IDLE) {
+ if (G_000000_MC_IDLE(RREG32_MC(R_000000_MC_STATUS)))
return 0;
- }
- DRM_UDELAY(1);
+ udelay(1);
}
return -1;
}
-void rs600_errata(struct radeon_device *rdev)
-{
- rdev->pll_errata = 0;
-}
-
void rs600_gpu_init(struct radeon_device *rdev)
{
/* FIXME: HDP same place on rs600 ? */
r100_hdp_reset(rdev);
- rv515_vga_render_disable(rdev);
/* FIXME: is this correct ? */
r420_pipes_init(rdev);
- if (rs600_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "Failed to wait MC idle while "
- "programming pipes. Bad things might happen.\n");
- }
+ /* Wait for mc idle */
+ if (rs600_mc_wait_for_idle(rdev))
+ dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
}
-
-/*
- * VRAM info.
- */
void rs600_vram_info(struct radeon_device *rdev)
{
/* FIXME: to do or is these values sane ? */
@@ -394,31 +306,206 @@ void rs600_bandwidth_update(struct radeon_device *rdev)
/* FIXME: implement, should this be like rs690 ? */
}
-
-/*
- * Indirect registers accessor
- */
uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg)
{
- uint32_t r;
-
- WREG32(RS600_MC_INDEX,
- ((reg & RS600_MC_ADDR_MASK) | RS600_MC_IND_CITF_ARB0));
- r = RREG32(RS600_MC_DATA);
- return r;
+ WREG32(R_000070_MC_IND_INDEX, S_000070_MC_IND_ADDR(reg) |
+ S_000070_MC_IND_CITF_ARB0(1));
+ return RREG32(R_000074_MC_IND_DATA);
}
void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{
- WREG32(RS600_MC_INDEX,
- RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 |
- ((reg) & RS600_MC_ADDR_MASK));
- WREG32(RS600_MC_DATA, v);
+ WREG32(R_000070_MC_IND_INDEX, S_000070_MC_IND_ADDR(reg) |
+ S_000070_MC_IND_CITF_ARB0(1) | S_000070_MC_IND_WR_EN(1));
+ WREG32(R_000074_MC_IND_DATA, v);
}
-int rs600_init(struct radeon_device *rdev)
+void rs600_debugfs(struct radeon_device *rdev)
+{
+ if (r100_debugfs_rbbm_init(rdev))
+ DRM_ERROR("Failed to register debugfs file for RBBM !\n");
+}
+
+void rs600_set_safe_registers(struct radeon_device *rdev)
{
rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm;
rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm);
+}
+
+static void rs600_mc_program(struct radeon_device *rdev)
+{
+ struct rv515_mc_save save;
+
+ /* Stops all mc clients */
+ rv515_mc_stop(rdev, &save);
+
+ /* Wait for mc idle */
+ if (rs600_mc_wait_for_idle(rdev))
+ dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
+
+ /* FIXME: What does AGP means for such chipset ? */
+ WREG32_MC(R_000005_MC_AGP_LOCATION, 0x0FFFFFFF);
+ WREG32_MC(R_000006_AGP_BASE, 0);
+ WREG32_MC(R_000007_AGP_BASE_2, 0);
+ /* Program MC */
+ WREG32_MC(R_000004_MC_FB_LOCATION,
+ S_000004_MC_FB_START(rdev->mc.vram_start >> 16) |
+ S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16));
+ WREG32(R_000134_HDP_FB_LOCATION,
+ S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
+
+ rv515_mc_resume(rdev, &save);
+}
+
+static int rs600_startup(struct radeon_device *rdev)
+{
+ int r;
+
+ rs600_mc_program(rdev);
+ /* Resume clock */
+ rv515_clock_startup(rdev);
+ /* Initialize GPU configuration (# pipes, ...) */
+ rs600_gpu_init(rdev);
+ /* Initialize GART (initialize after TTM so we can allocate
+ * memory through TTM but finalize after TTM) */
+ r = rs600_gart_enable(rdev);
+ if (r)
+ return r;
+ /* Enable IRQ */
+ rdev->irq.sw_int = true;
+ rs600_irq_set(rdev);
+ /* 1M ring buffer */
+ r = r100_cp_init(rdev, 1024 * 1024);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+ return r;
+ }
+ r = r100_wb_init(rdev);
+ if (r)
+ dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+ r = r100_ib_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+ return r;
+ }
+ return 0;
+}
+
+int rs600_resume(struct radeon_device *rdev)
+{
+ /* Make sur GART are not working */
+ rs600_gart_disable(rdev);
+ /* Resume clock before doing reset */
+ rv515_clock_startup(rdev);
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* post */
+ atom_asic_init(rdev->mode_info.atom_context);
+ /* Resume clock after posting */
+ rv515_clock_startup(rdev);
+ return rs600_startup(rdev);
+}
+
+int rs600_suspend(struct radeon_device *rdev)
+{
+ r100_cp_disable(rdev);
+ r100_wb_disable(rdev);
+ rs600_irq_disable(rdev);
+ rs600_gart_disable(rdev);
+ return 0;
+}
+
+void rs600_fini(struct radeon_device *rdev)
+{
+ rs600_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ radeon_gem_fini(rdev);
+ rs600_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_object_fini(rdev);
+ radeon_atombios_fini(rdev);
+ kfree(rdev->bios);
+ rdev->bios = NULL;
+}
+
+int rs600_init(struct radeon_device *rdev)
+{
+ int r;
+
+ /* Disable VGA */
+ rv515_vga_render_disable(rdev);
+ /* Initialize scratch registers */
+ radeon_scratch_init(rdev);
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* BIOS */
+ if (!radeon_get_bios(rdev)) {
+ if (ASIC_IS_AVIVO(rdev))
+ return -EINVAL;
+ }
+ if (rdev->is_atom_bios) {
+ r = radeon_atombios_init(rdev);
+ if (r)
+ return r;
+ } else {
+ dev_err(rdev->dev, "Expecting atombios for RS600 GPU\n");
+ return -EINVAL;
+ }
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev,
+ "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* check if cards are posted or not */
+ if (!radeon_card_posted(rdev) && rdev->bios) {
+ DRM_INFO("GPU not posted. posting now...\n");
+ atom_asic_init(rdev->mode_info.atom_context);
+ }
+ /* Initialize clocks */
+ radeon_get_clock_info(rdev->ddev);
+ /* Get vram informations */
+ rs600_vram_info(rdev);
+ /* Initialize memory controller (also test AGP) */
+ r = r420_mc_init(rdev);
+ if (r)
+ return r;
+ rs600_debugfs(rdev);
+ /* Fence driver */
+ r = radeon_fence_driver_init(rdev);
+ if (r)
+ return r;
+ r = radeon_irq_kms_init(rdev);
+ if (r)
+ return r;
+ /* Memory manager */
+ r = radeon_object_init(rdev);
+ if (r)
+ return r;
+ r = rs600_gart_init(rdev);
+ if (r)
+ return r;
+ rs600_set_safe_registers(rdev);
+ rdev->accel_working = true;
+ r = rs600_startup(rdev);
+ if (r) {
+ /* Somethings want wront with the accel init stop accel */
+ dev_err(rdev->dev, "Disabling GPU acceleration\n");
+ rs600_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ rs600_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rdev->accel_working = false;
+ }
return 0;
}
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h
new file mode 100644
index 00000000000..81308924859
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs600d.h
@@ -0,0 +1,470 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ */
+#ifndef __RS600D_H__
+#define __RS600D_H__
+
+/* Registers */
+#define R_000040_GEN_INT_CNTL 0x000040
+#define S_000040_DISPLAY_INT_STATUS(x) (((x) & 0x1) << 0)
+#define G_000040_DISPLAY_INT_STATUS(x) (((x) >> 0) & 0x1)
+#define C_000040_DISPLAY_INT_STATUS 0xFFFFFFFE
+#define S_000040_DMA_VIPH0_INT_EN(x) (((x) & 0x1) << 12)
+#define G_000040_DMA_VIPH0_INT_EN(x) (((x) >> 12) & 0x1)
+#define C_000040_DMA_VIPH0_INT_EN 0xFFFFEFFF
+#define S_000040_CRTC2_VSYNC(x) (((x) & 0x1) << 6)
+#define G_000040_CRTC2_VSYNC(x) (((x) >> 6) & 0x1)
+#define C_000040_CRTC2_VSYNC 0xFFFFFFBF
+#define S_000040_SNAPSHOT2(x) (((x) & 0x1) << 7)
+#define G_000040_SNAPSHOT2(x) (((x) >> 7) & 0x1)
+#define C_000040_SNAPSHOT2 0xFFFFFF7F
+#define S_000040_CRTC2_VBLANK(x) (((x) & 0x1) << 9)
+#define G_000040_CRTC2_VBLANK(x) (((x) >> 9) & 0x1)
+#define C_000040_CRTC2_VBLANK 0xFFFFFDFF
+#define S_000040_FP2_DETECT(x) (((x) & 0x1) << 10)
+#define G_000040_FP2_DETECT(x) (((x) >> 10) & 0x1)
+#define C_000040_FP2_DETECT 0xFFFFFBFF
+#define S_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) & 0x1) << 11)
+#define G_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) >> 11) & 0x1)
+#define C_000040_VSYNC_DIFF_OVER_LIMIT 0xFFFFF7FF
+#define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13)
+#define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1)
+#define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF
+#define S_000040_DMA_VIPH2_INT_EN(x) (((x) & 0x1) << 14)
+#define G_000040_DMA_VIPH2_INT_EN(x) (((x) >> 14) & 0x1)
+#define C_000040_DMA_VIPH2_INT_EN 0xFFFFBFFF
+#define S_000040_DMA_VIPH3_INT_EN(x) (((x) & 0x1) << 15)
+#define G_000040_DMA_VIPH3_INT_EN(x) (((x) >> 15) & 0x1)
+#define C_000040_DMA_VIPH3_INT_EN 0xFFFF7FFF
+#define S_000040_I2C_INT_EN(x) (((x) & 0x1) << 17)
+#define G_000040_I2C_INT_EN(x) (((x) >> 17) & 0x1)
+#define C_000040_I2C_INT_EN 0xFFFDFFFF
+#define S_000040_GUI_IDLE(x) (((x) & 0x1) << 19)
+#define G_000040_GUI_IDLE(x) (((x) >> 19) & 0x1)
+#define C_000040_GUI_IDLE 0xFFF7FFFF
+#define S_000040_VIPH_INT_EN(x) (((x) & 0x1) << 24)
+#define G_000040_VIPH_INT_EN(x) (((x) >> 24) & 0x1)
+#define C_000040_VIPH_INT_EN 0xFEFFFFFF
+#define S_000040_SW_INT_EN(x) (((x) & 0x1) << 25)
+#define G_000040_SW_INT_EN(x) (((x) >> 25) & 0x1)
+#define C_000040_SW_INT_EN 0xFDFFFFFF
+#define S_000040_GEYSERVILLE(x) (((x) & 0x1) << 27)
+#define G_000040_GEYSERVILLE(x) (((x) >> 27) & 0x1)
+#define C_000040_GEYSERVILLE 0xF7FFFFFF
+#define S_000040_HDCP_AUTHORIZED_INT(x) (((x) & 0x1) << 28)
+#define G_000040_HDCP_AUTHORIZED_INT(x) (((x) >> 28) & 0x1)
+#define C_000040_HDCP_AUTHORIZED_INT 0xEFFFFFFF
+#define S_000040_DVI_I2C_INT(x) (((x) & 0x1) << 29)
+#define G_000040_DVI_I2C_INT(x) (((x) >> 29) & 0x1)
+#define C_000040_DVI_I2C_INT 0xDFFFFFFF
+#define S_000040_GUIDMA(x) (((x) & 0x1) << 30)
+#define G_000040_GUIDMA(x) (((x) >> 30) & 0x1)
+#define C_000040_GUIDMA 0xBFFFFFFF
+#define S_000040_VIDDMA(x) (((x) & 0x1) << 31)
+#define G_000040_VIDDMA(x) (((x) >> 31) & 0x1)
+#define C_000040_VIDDMA 0x7FFFFFFF
+#define R_000044_GEN_INT_STATUS 0x000044
+#define S_000044_DISPLAY_INT_STAT(x) (((x) & 0x1) << 0)
+#define G_000044_DISPLAY_INT_STAT(x) (((x) >> 0) & 0x1)
+#define C_000044_DISPLAY_INT_STAT 0xFFFFFFFE
+#define S_000044_VGA_INT_STAT(x) (((x) & 0x1) << 1)
+#define G_000044_VGA_INT_STAT(x) (((x) >> 1) & 0x1)
+#define C_000044_VGA_INT_STAT 0xFFFFFFFD
+#define S_000044_CAP0_INT_ACTIVE(x) (((x) & 0x1) << 8)
+#define G_000044_CAP0_INT_ACTIVE(x) (((x) >> 8) & 0x1)
+#define C_000044_CAP0_INT_ACTIVE 0xFFFFFEFF
+#define S_000044_DMA_VIPH0_INT(x) (((x) & 0x1) << 12)
+#define G_000044_DMA_VIPH0_INT(x) (((x) >> 12) & 0x1)
+#define C_000044_DMA_VIPH0_INT 0xFFFFEFFF
+#define S_000044_DMA_VIPH1_INT(x) (((x) & 0x1) << 13)
+#define G_000044_DMA_VIPH1_INT(x) (((x) >> 13) & 0x1)
+#define C_000044_DMA_VIPH1_INT 0xFFFFDFFF
+#define S_000044_DMA_VIPH2_INT(x) (((x) & 0x1) << 14)
+#define G_000044_DMA_VIPH2_INT(x) (((x) >> 14) & 0x1)
+#define C_000044_DMA_VIPH2_INT 0xFFFFBFFF
+#define S_000044_DMA_VIPH3_INT(x) (((x) & 0x1) << 15)
+#define G_000044_DMA_VIPH3_INT(x) (((x) >> 15) & 0x1)
+#define C_000044_DMA_VIPH3_INT 0xFFFF7FFF
+#define S_000044_MC_PROBE_FAULT_STAT(x) (((x) & 0x1) << 16)
+#define G_000044_MC_PROBE_FAULT_STAT(x) (((x) >> 16) & 0x1)
+#define C_000044_MC_PROBE_FAULT_STAT 0xFFFEFFFF
+#define S_000044_I2C_INT(x) (((x) & 0x1) << 17)
+#define G_000044_I2C_INT(x) (((x) >> 17) & 0x1)
+#define C_000044_I2C_INT 0xFFFDFFFF
+#define S_000044_SCRATCH_INT_STAT(x) (((x) & 0x1) << 18)
+#define G_000044_SCRATCH_INT_STAT(x) (((x) >> 18) & 0x1)
+#define C_000044_SCRATCH_INT_STAT 0xFFFBFFFF
+#define S_000044_GUI_IDLE_STAT(x) (((x) & 0x1) << 19)
+#define G_000044_GUI_IDLE_STAT(x) (((x) >> 19) & 0x1)
+#define C_000044_GUI_IDLE_STAT 0xFFF7FFFF
+#define S_000044_ATI_OVERDRIVE_INT_STAT(x) (((x) & 0x1) << 20)
+#define G_000044_ATI_OVERDRIVE_INT_STAT(x) (((x) >> 20) & 0x1)
+#define C_000044_ATI_OVERDRIVE_INT_STAT 0xFFEFFFFF
+#define S_000044_MC_PROTECTION_FAULT_STAT(x) (((x) & 0x1) << 21)
+#define G_000044_MC_PROTECTION_FAULT_STAT(x) (((x) >> 21) & 0x1)
+#define C_000044_MC_PROTECTION_FAULT_STAT 0xFFDFFFFF
+#define S_000044_RBBM_READ_INT_STAT(x) (((x) & 0x1) << 22)
+#define G_000044_RBBM_READ_INT_STAT(x) (((x) >> 22) & 0x1)
+#define C_000044_RBBM_READ_INT_STAT 0xFFBFFFFF
+#define S_000044_CB_CONTEXT_SWITCH_STAT(x) (((x) & 0x1) << 23)
+#define G_000044_CB_CONTEXT_SWITCH_STAT(x) (((x) >> 23) & 0x1)
+#define C_000044_CB_CONTEXT_SWITCH_STAT 0xFF7FFFFF
+#define S_000044_VIPH_INT(x) (((x) & 0x1) << 24)
+#define G_000044_VIPH_INT(x) (((x) >> 24) & 0x1)
+#define C_000044_VIPH_INT 0xFEFFFFFF
+#define S_000044_SW_INT(x) (((x) & 0x1) << 25)
+#define G_000044_SW_INT(x) (((x) >> 25) & 0x1)
+#define C_000044_SW_INT 0xFDFFFFFF
+#define S_000044_SW_INT_SET(x) (((x) & 0x1) << 26)
+#define G_000044_SW_INT_SET(x) (((x) >> 26) & 0x1)
+#define C_000044_SW_INT_SET 0xFBFFFFFF
+#define S_000044_IDCT_INT_STAT(x) (((x) & 0x1) << 27)
+#define G_000044_IDCT_INT_STAT(x) (((x) >> 27) & 0x1)
+#define C_000044_IDCT_INT_STAT 0xF7FFFFFF
+#define S_000044_GUIDMA_STAT(x) (((x) & 0x1) << 30)
+#define G_000044_GUIDMA_STAT(x) (((x) >> 30) & 0x1)
+#define C_000044_GUIDMA_STAT 0xBFFFFFFF
+#define S_000044_VIDDMA_STAT(x) (((x) & 0x1) << 31)
+#define G_000044_VIDDMA_STAT(x) (((x) >> 31) & 0x1)
+#define C_000044_VIDDMA_STAT 0x7FFFFFFF
+#define R_00004C_BUS_CNTL 0x00004C
+#define S_00004C_BUS_MASTER_DIS(x) (((x) & 0x1) << 14)
+#define G_00004C_BUS_MASTER_DIS(x) (((x) >> 14) & 0x1)
+#define C_00004C_BUS_MASTER_DIS 0xFFFFBFFF
+#define S_00004C_BUS_MSI_REARM(x) (((x) & 0x1) << 20)
+#define G_00004C_BUS_MSI_REARM(x) (((x) >> 20) & 0x1)
+#define C_00004C_BUS_MSI_REARM 0xFFEFFFFF
+#define R_000070_MC_IND_INDEX 0x000070
+#define S_000070_MC_IND_ADDR(x) (((x) & 0xFFFF) << 0)
+#define G_000070_MC_IND_ADDR(x) (((x) >> 0) & 0xFFFF)
+#define C_000070_MC_IND_ADDR 0xFFFF0000
+#define S_000070_MC_IND_SEQ_RBS_0(x) (((x) & 0x1) << 16)
+#define G_000070_MC_IND_SEQ_RBS_0(x) (((x) >> 16) & 0x1)
+#define C_000070_MC_IND_SEQ_RBS_0 0xFFFEFFFF
+#define S_000070_MC_IND_SEQ_RBS_1(x) (((x) & 0x1) << 17)
+#define G_000070_MC_IND_SEQ_RBS_1(x) (((x) >> 17) & 0x1)
+#define C_000070_MC_IND_SEQ_RBS_1 0xFFFDFFFF
+#define S_000070_MC_IND_SEQ_RBS_2(x) (((x) & 0x1) << 18)
+#define G_000070_MC_IND_SEQ_RBS_2(x) (((x) >> 18) & 0x1)
+#define C_000070_MC_IND_SEQ_RBS_2 0xFFFBFFFF
+#define S_000070_MC_IND_SEQ_RBS_3(x) (((x) & 0x1) << 19)
+#define G_000070_MC_IND_SEQ_RBS_3(x) (((x) >> 19) & 0x1)
+#define C_000070_MC_IND_SEQ_RBS_3 0xFFF7FFFF
+#define S_000070_MC_IND_AIC_RBS(x) (((x) & 0x1) << 20)
+#define G_000070_MC_IND_AIC_RBS(x) (((x) >> 20) & 0x1)
+#define C_000070_MC_IND_AIC_RBS 0xFFEFFFFF
+#define S_000070_MC_IND_CITF_ARB0(x) (((x) & 0x1) << 21)
+#define G_000070_MC_IND_CITF_ARB0(x) (((x) >> 21) & 0x1)
+#define C_000070_MC_IND_CITF_ARB0 0xFFDFFFFF
+#define S_000070_MC_IND_CITF_ARB1(x) (((x) & 0x1) << 22)
+#define G_000070_MC_IND_CITF_ARB1(x) (((x) >> 22) & 0x1)
+#define C_000070_MC_IND_CITF_ARB1 0xFFBFFFFF
+#define S_000070_MC_IND_WR_EN(x) (((x) & 0x1) << 23)
+#define G_000070_MC_IND_WR_EN(x) (((x) >> 23) & 0x1)
+#define C_000070_MC_IND_WR_EN 0xFF7FFFFF
+#define S_000070_MC_IND_RD_INV(x) (((x) & 0x1) << 24)
+#define G_000070_MC_IND_RD_INV(x) (((x) >> 24) & 0x1)
+#define C_000070_MC_IND_RD_INV 0xFEFFFFFF
+#define R_000074_MC_IND_DATA 0x000074
+#define S_000074_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_000074_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_000074_MC_IND_DATA 0x00000000
+#define R_000134_HDP_FB_LOCATION 0x000134
+#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0)
+#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF)
+#define C_000134_HDP_FB_START 0xFFFF0000
+#define R_0007C0_CP_STAT 0x0007C0
+#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
+#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
+#define C_0007C0_MRU_BUSY 0xFFFFFFFE
+#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
+#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
+#define C_0007C0_MWU_BUSY 0xFFFFFFFD
+#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
+#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
+#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
+#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
+#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
+#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
+#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
+#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
+#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
+#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
+#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
+#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
+#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
+#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
+#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
+#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
+#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
+#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
+#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
+#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
+#define C_0007C0_CSI_BUSY 0xFFFFDFFF
+#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
+#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
+#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
+#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
+#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
+#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
+#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
+#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
+#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
+#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
+#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
+#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
+#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
+#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
+#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
+#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
+#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
+#define C_0007C0_CP_BUSY 0x7FFFFFFF
+#define R_000E40_RBBM_STATUS 0x000E40
+#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
+#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
+#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
+#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
+#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
+#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
+#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
+#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
+#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
+#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
+#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
+#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
+#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
+#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
+#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
+#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
+#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
+#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
+#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
+#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
+#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
+#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
+#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
+#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
+#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
+#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
+#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
+#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
+#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
+#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
+#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
+#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
+#define C_000E40_E2_BUSY 0xFFFDFFFF
+#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
+#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
+#define C_000E40_RB2D_BUSY 0xFFFBFFFF
+#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
+#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
+#define C_000E40_RB3D_BUSY 0xFFF7FFFF
+#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
+#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
+#define C_000E40_VAP_BUSY 0xFFEFFFFF
+#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
+#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
+#define C_000E40_RE_BUSY 0xFFDFFFFF
+#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
+#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
+#define C_000E40_TAM_BUSY 0xFFBFFFFF
+#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
+#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
+#define C_000E40_TDM_BUSY 0xFF7FFFFF
+#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
+#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
+#define C_000E40_PB_BUSY 0xFEFFFFFF
+#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
+#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
+#define C_000E40_TIM_BUSY 0xFDFFFFFF
+#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
+#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
+#define C_000E40_GA_BUSY 0xFBFFFFFF
+#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
+#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
+#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
+#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
+#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
+#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
+#define R_0060A4_D1CRTC_STATUS_FRAME_COUNT 0x0060A4
+#define S_0060A4_D1CRTC_FRAME_COUNT(x) (((x) & 0xFFFFFF) << 0)
+#define G_0060A4_D1CRTC_FRAME_COUNT(x) (((x) >> 0) & 0xFFFFFF)
+#define C_0060A4_D1CRTC_FRAME_COUNT 0xFF000000
+#define R_006534_D1MODE_VBLANK_STATUS 0x006534
+#define S_006534_D1MODE_VBLANK_OCCURRED(x) (((x) & 0x1) << 0)
+#define G_006534_D1MODE_VBLANK_OCCURRED(x) (((x) >> 0) & 0x1)
+#define C_006534_D1MODE_VBLANK_OCCURRED 0xFFFFFFFE
+#define S_006534_D1MODE_VBLANK_ACK(x) (((x) & 0x1) << 4)
+#define G_006534_D1MODE_VBLANK_ACK(x) (((x) >> 4) & 0x1)
+#define C_006534_D1MODE_VBLANK_ACK 0xFFFFFFEF
+#define S_006534_D1MODE_VBLANK_STAT(x) (((x) & 0x1) << 12)
+#define G_006534_D1MODE_VBLANK_STAT(x) (((x) >> 12) & 0x1)
+#define C_006534_D1MODE_VBLANK_STAT 0xFFFFEFFF
+#define S_006534_D1MODE_VBLANK_INTERRUPT(x) (((x) & 0x1) << 16)
+#define G_006534_D1MODE_VBLANK_INTERRUPT(x) (((x) >> 16) & 0x1)
+#define C_006534_D1MODE_VBLANK_INTERRUPT 0xFFFEFFFF
+#define R_006540_DxMODE_INT_MASK 0x006540
+#define S_006540_D1MODE_VBLANK_INT_MASK(x) (((x) & 0x1) << 0)
+#define G_006540_D1MODE_VBLANK_INT_MASK(x) (((x) >> 0) & 0x1)
+#define C_006540_D1MODE_VBLANK_INT_MASK 0xFFFFFFFE
+#define S_006540_D1MODE_VLINE_INT_MASK(x) (((x) & 0x1) << 4)
+#define G_006540_D1MODE_VLINE_INT_MASK(x) (((x) >> 4) & 0x1)
+#define C_006540_D1MODE_VLINE_INT_MASK 0xFFFFFFEF
+#define S_006540_D2MODE_VBLANK_INT_MASK(x) (((x) & 0x1) << 8)
+#define G_006540_D2MODE_VBLANK_INT_MASK(x) (((x) >> 8) & 0x1)
+#define C_006540_D2MODE_VBLANK_INT_MASK 0xFFFFFEFF
+#define S_006540_D2MODE_VLINE_INT_MASK(x) (((x) & 0x1) << 12)
+#define G_006540_D2MODE_VLINE_INT_MASK(x) (((x) >> 12) & 0x1)
+#define C_006540_D2MODE_VLINE_INT_MASK 0xFFFFEFFF
+#define S_006540_D1MODE_VBLANK_CP_SEL(x) (((x) & 0x1) << 30)
+#define G_006540_D1MODE_VBLANK_CP_SEL(x) (((x) >> 30) & 0x1)
+#define C_006540_D1MODE_VBLANK_CP_SEL 0xBFFFFFFF
+#define S_006540_D2MODE_VBLANK_CP_SEL(x) (((x) & 0x1) << 31)
+#define G_006540_D2MODE_VBLANK_CP_SEL(x) (((x) >> 31) & 0x1)
+#define C_006540_D2MODE_VBLANK_CP_SEL 0x7FFFFFFF
+#define R_0068A4_D2CRTC_STATUS_FRAME_COUNT 0x0068A4
+#define S_0068A4_D2CRTC_FRAME_COUNT(x) (((x) & 0xFFFFFF) << 0)
+#define G_0068A4_D2CRTC_FRAME_COUNT(x) (((x) >> 0) & 0xFFFFFF)
+#define C_0068A4_D2CRTC_FRAME_COUNT 0xFF000000
+#define R_006D34_D2MODE_VBLANK_STATUS 0x006D34
+#define S_006D34_D2MODE_VBLANK_OCCURRED(x) (((x) & 0x1) << 0)
+#define G_006D34_D2MODE_VBLANK_OCCURRED(x) (((x) >> 0) & 0x1)
+#define C_006D34_D2MODE_VBLANK_OCCURRED 0xFFFFFFFE
+#define S_006D34_D2MODE_VBLANK_ACK(x) (((x) & 0x1) << 4)
+#define G_006D34_D2MODE_VBLANK_ACK(x) (((x) >> 4) & 0x1)
+#define C_006D34_D2MODE_VBLANK_ACK 0xFFFFFFEF
+#define S_006D34_D2MODE_VBLANK_STAT(x) (((x) & 0x1) << 12)
+#define G_006D34_D2MODE_VBLANK_STAT(x) (((x) >> 12) & 0x1)
+#define C_006D34_D2MODE_VBLANK_STAT 0xFFFFEFFF
+#define S_006D34_D2MODE_VBLANK_INTERRUPT(x) (((x) & 0x1) << 16)
+#define G_006D34_D2MODE_VBLANK_INTERRUPT(x) (((x) >> 16) & 0x1)
+#define C_006D34_D2MODE_VBLANK_INTERRUPT 0xFFFEFFFF
+#define R_007EDC_DISP_INTERRUPT_STATUS 0x007EDC
+#define S_007EDC_LB_D1_VBLANK_INTERRUPT(x) (((x) & 0x1) << 4)
+#define G_007EDC_LB_D1_VBLANK_INTERRUPT(x) (((x) >> 4) & 0x1)
+#define C_007EDC_LB_D1_VBLANK_INTERRUPT 0xFFFFFFEF
+#define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5)
+#define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1)
+#define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF
+
+
+/* MC registers */
+#define R_000000_MC_STATUS 0x000000
+#define S_000000_MC_IDLE(x) (((x) & 0x1) << 0)
+#define G_000000_MC_IDLE(x) (((x) >> 0) & 0x1)
+#define C_000000_MC_IDLE 0xFFFFFFFE
+#define R_000004_MC_FB_LOCATION 0x000004
+#define S_000004_MC_FB_START(x) (((x) & 0xFFFF) << 0)
+#define G_000004_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
+#define C_000004_MC_FB_START 0xFFFF0000
+#define S_000004_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
+#define G_000004_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
+#define C_000004_MC_FB_TOP 0x0000FFFF
+#define R_000005_MC_AGP_LOCATION 0x000005
+#define S_000005_MC_AGP_START(x) (((x) & 0xFFFF) << 0)
+#define G_000005_MC_AGP_START(x) (((x) >> 0) & 0xFFFF)
+#define C_000005_MC_AGP_START 0xFFFF0000
+#define S_000005_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16)
+#define G_000005_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF)
+#define C_000005_MC_AGP_TOP 0x0000FFFF
+#define R_000006_AGP_BASE 0x000006
+#define S_000006_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_000006_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_000006_AGP_BASE_ADDR 0x00000000
+#define R_000007_AGP_BASE_2 0x000007
+#define S_000007_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0)
+#define G_000007_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF)
+#define C_000007_AGP_BASE_ADDR_2 0xFFFFFFF0
+#define R_000009_MC_CNTL1 0x000009
+#define S_000009_ENABLE_PAGE_TABLES(x) (((x) & 0x1) << 26)
+#define G_000009_ENABLE_PAGE_TABLES(x) (((x) >> 26) & 0x1)
+#define C_000009_ENABLE_PAGE_TABLES 0xFBFFFFFF
+/* FIXME don't know the various field size need feedback from AMD */
+#define R_000100_MC_PT0_CNTL 0x000100
+#define S_000100_ENABLE_PT(x) (((x) & 0x1) << 0)
+#define G_000100_ENABLE_PT(x) (((x) >> 0) & 0x1)
+#define C_000100_ENABLE_PT 0xFFFFFFFE
+#define S_000100_EFFECTIVE_L2_CACHE_SIZE(x) (((x) & 0x7) << 15)
+#define G_000100_EFFECTIVE_L2_CACHE_SIZE(x) (((x) >> 15) & 0x7)
+#define C_000100_EFFECTIVE_L2_CACHE_SIZE 0xFFFC7FFF
+#define S_000100_EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 0x7) << 21)
+#define G_000100_EFFECTIVE_L2_QUEUE_SIZE(x) (((x) >> 21) & 0x7)
+#define C_000100_EFFECTIVE_L2_QUEUE_SIZE 0xFF1FFFFF
+#define S_000100_INVALIDATE_ALL_L1_TLBS(x) (((x) & 0x1) << 28)
+#define G_000100_INVALIDATE_ALL_L1_TLBS(x) (((x) >> 28) & 0x1)
+#define C_000100_INVALIDATE_ALL_L1_TLBS 0xEFFFFFFF
+#define S_000100_INVALIDATE_L2_CACHE(x) (((x) & 0x1) << 29)
+#define G_000100_INVALIDATE_L2_CACHE(x) (((x) >> 29) & 0x1)
+#define C_000100_INVALIDATE_L2_CACHE 0xDFFFFFFF
+#define R_000102_MC_PT0_CONTEXT0_CNTL 0x000102
+#define S_000102_ENABLE_PAGE_TABLE(x) (((x) & 0x1) << 0)
+#define G_000102_ENABLE_PAGE_TABLE(x) (((x) >> 0) & 0x1)
+#define C_000102_ENABLE_PAGE_TABLE 0xFFFFFFFE
+#define S_000102_PAGE_TABLE_DEPTH(x) (((x) & 0x3) << 1)
+#define G_000102_PAGE_TABLE_DEPTH(x) (((x) >> 1) & 0x3)
+#define C_000102_PAGE_TABLE_DEPTH 0xFFFFFFF9
+#define V_000102_PAGE_TABLE_FLAT 0
+/* R600 documentation suggest that this should be a number of pages */
+#define R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x000112
+#define R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x000114
+#define R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x00011C
+#define R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x00012C
+#define R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x00013C
+#define R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x00014C
+#define R_00016C_MC_PT0_CLIENT0_CNTL 0x00016C
+#define S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(x) (((x) & 0x1) << 0)
+#define G_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(x) (((x) >> 0) & 0x1)
+#define C_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE 0xFFFFFFFE
+#define S_00016C_TRANSLATION_MODE_OVERRIDE(x) (((x) & 0x1) << 1)
+#define G_00016C_TRANSLATION_MODE_OVERRIDE(x) (((x) >> 1) & 0x1)
+#define C_00016C_TRANSLATION_MODE_OVERRIDE 0xFFFFFFFD
+#define S_00016C_SYSTEM_ACCESS_MODE_MASK(x) (((x) & 0x3) << 8)
+#define G_00016C_SYSTEM_ACCESS_MODE_MASK(x) (((x) >> 8) & 0x3)
+#define C_00016C_SYSTEM_ACCESS_MODE_MASK 0xFFFFFCFF
+#define V_00016C_SYSTEM_ACCESS_MODE_PA_ONLY 0
+#define V_00016C_SYSTEM_ACCESS_MODE_USE_SYS_MAP 1
+#define V_00016C_SYSTEM_ACCESS_MODE_IN_SYS 2
+#define V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS 3
+#define S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(x) (((x) & 0x1) << 10)
+#define G_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(x) (((x) >> 10) & 0x1)
+#define C_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS 0xFFFFFBFF
+#define V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH 0
+#define V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE 1
+#define S_00016C_EFFECTIVE_L1_CACHE_SIZE(x) (((x) & 0x7) << 11)
+#define G_00016C_EFFECTIVE_L1_CACHE_SIZE(x) (((x) >> 11) & 0x7)
+#define C_00016C_EFFECTIVE_L1_CACHE_SIZE 0xFFFFC7FF
+#define S_00016C_ENABLE_FRAGMENT_PROCESSING(x) (((x) & 0x1) << 14)
+#define G_00016C_ENABLE_FRAGMENT_PROCESSING(x) (((x) >> 14) & 0x1)
+#define C_00016C_ENABLE_FRAGMENT_PROCESSING 0xFFFFBFFF
+#define S_00016C_EFFECTIVE_L1_QUEUE_SIZE(x) (((x) & 0x7) << 15)
+#define G_00016C_EFFECTIVE_L1_QUEUE_SIZE(x) (((x) >> 15) & 0x7)
+#define C_00016C_EFFECTIVE_L1_QUEUE_SIZE 0xFFFC7FFF
+#define S_00016C_INVALIDATE_L1_TLB(x) (((x) & 0x1) << 20)
+#define G_00016C_INVALIDATE_L1_TLB(x) (((x) >> 20) & 0x1)
+#define C_00016C_INVALIDATE_L1_TLB 0xFFEFFFFF
+
+#endif
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 7a0098ddf97..025e3225346 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -26,105 +26,29 @@
* Jerome Glisse
*/
#include "drmP.h"
-#include "radeon_reg.h"
#include "radeon.h"
-#include "rs690r.h"
#include "atom.h"
-#include "atom-bits.h"
-
-/* rs690,rs740 depends on : */
-void r100_hdp_reset(struct radeon_device *rdev);
-int r300_mc_wait_for_idle(struct radeon_device *rdev);
-void r420_pipes_init(struct radeon_device *rdev);
-void rs400_gart_disable(struct radeon_device *rdev);
-int rs400_gart_enable(struct radeon_device *rdev);
-void rs400_gart_adjust_size(struct radeon_device *rdev);
-void rs600_mc_disable_clients(struct radeon_device *rdev);
-
-/* This files gather functions specifics to :
- * rs690,rs740
- *
- * Some of these functions might be used by newer ASICs.
- */
-void rs690_gpu_init(struct radeon_device *rdev);
-int rs690_mc_wait_for_idle(struct radeon_device *rdev);
-
-
-/*
- * MC functions.
- */
-int rs690_mc_init(struct radeon_device *rdev)
-{
- uint32_t tmp;
- int r;
-
- if (r100_debugfs_rbbm_init(rdev)) {
- DRM_ERROR("Failed to register debugfs file for RBBM !\n");
- }
-
- rs690_gpu_init(rdev);
- rs400_gart_disable(rdev);
-
- /* Setup GPU memory space */
- rdev->mc.gtt_location = rdev->mc.mc_vram_size;
- rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
- rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
- rdev->mc.vram_location = 0xFFFFFFFFUL;
- r = radeon_mc_setup(rdev);
- if (r) {
- return r;
- }
-
- /* Program GPU memory space */
- rs600_mc_disable_clients(rdev);
- if (rs690_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "Failed to wait MC idle while "
- "programming pipes. Bad things might happen.\n");
- }
- tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
- tmp = REG_SET(RS690_MC_FB_TOP, tmp >> 16);
- tmp |= REG_SET(RS690_MC_FB_START, rdev->mc.vram_location >> 16);
- WREG32_MC(RS690_MCCFG_FB_LOCATION, tmp);
- /* FIXME: Does this reg exist on RS480,RS740 ? */
- WREG32(0x310, rdev->mc.vram_location);
- WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
- return 0;
-}
-
-void rs690_mc_fini(struct radeon_device *rdev)
-{
-}
-
+#include "rs690d.h"
-/*
- * Global GPU functions
- */
-int rs690_mc_wait_for_idle(struct radeon_device *rdev)
+static int rs690_mc_wait_for_idle(struct radeon_device *rdev)
{
unsigned i;
uint32_t tmp;
for (i = 0; i < rdev->usec_timeout; i++) {
/* read MC_STATUS */
- tmp = RREG32_MC(RS690_MC_STATUS);
- if (tmp & RS690_MC_STATUS_IDLE) {
+ tmp = RREG32_MC(R_000090_MC_SYSTEM_STATUS);
+ if (G_000090_MC_SYSTEM_IDLE(tmp))
return 0;
- }
- DRM_UDELAY(1);
+ udelay(1);
}
return -1;
}
-void rs690_errata(struct radeon_device *rdev)
-{
- rdev->pll_errata = 0;
-}
-
-void rs690_gpu_init(struct radeon_device *rdev)
+static void rs690_gpu_init(struct radeon_device *rdev)
{
/* FIXME: HDP same place on rs690 ? */
r100_hdp_reset(rdev);
- rv515_vga_render_disable(rdev);
/* FIXME: is this correct ? */
r420_pipes_init(rdev);
if (rs690_mc_wait_for_idle(rdev)) {
@@ -133,10 +57,6 @@ void rs690_gpu_init(struct radeon_device *rdev)
}
}
-
-/*
- * VRAM info.
- */
void rs690_pm_info(struct radeon_device *rdev)
{
int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
@@ -250,39 +170,39 @@ void rs690_line_buffer_adjust(struct radeon_device *rdev,
/*
* Line Buffer Setup
* There is a single line buffer shared by both display controllers.
- * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
+ * R_006520_DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
* the display controllers. The paritioning can either be done
* manually or via one of four preset allocations specified in bits 1:0:
* 0 - line buffer is divided in half and shared between crtc
* 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4
* 2 - D1 gets the whole buffer
* 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4
- * Setting bit 2 of DC_LB_MEMORY_SPLIT controls switches to manual
+ * Setting bit 2 of R_006520_DC_LB_MEMORY_SPLIT controls switches to manual
* allocation mode. In manual allocation mode, D1 always starts at 0,
* D1 end/2 is specified in bits 14:4; D2 allocation follows D1.
*/
- tmp = RREG32(DC_LB_MEMORY_SPLIT) & ~DC_LB_MEMORY_SPLIT_MASK;
- tmp &= ~DC_LB_MEMORY_SPLIT_SHIFT_MODE;
+ tmp = RREG32(R_006520_DC_LB_MEMORY_SPLIT) & C_006520_DC_LB_MEMORY_SPLIT;
+ tmp &= ~C_006520_DC_LB_MEMORY_SPLIT_MODE;
/* auto */
if (mode1 && mode2) {
if (mode1->hdisplay > mode2->hdisplay) {
if (mode1->hdisplay > 2560)
- tmp |= DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q;
+ tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q;
else
- tmp |= DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
+ tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
} else if (mode2->hdisplay > mode1->hdisplay) {
if (mode2->hdisplay > 2560)
- tmp |= DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
+ tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
else
- tmp |= DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
+ tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
} else
- tmp |= AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
+ tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
} else if (mode1) {
- tmp |= DC_LB_MEMORY_SPLIT_D1_ONLY;
+ tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_ONLY;
} else if (mode2) {
- tmp |= DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
+ tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
}
- WREG32(DC_LB_MEMORY_SPLIT, tmp);
+ WREG32(R_006520_DC_LB_MEMORY_SPLIT, tmp);
}
struct rs690_watermark {
@@ -487,28 +407,28 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
* option.
*/
if (rdev->disp_priority == 2) {
- tmp = RREG32_MC(MC_INIT_MISC_LAT_TIMER);
- tmp &= ~MC_DISP1R_INIT_LAT_MASK;
- tmp &= ~MC_DISP0R_INIT_LAT_MASK;
- if (mode1)
- tmp |= (1 << MC_DISP1R_INIT_LAT_SHIFT);
+ tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER);
+ tmp &= C_000104_MC_DISP0R_INIT_LAT;
+ tmp &= C_000104_MC_DISP1R_INIT_LAT;
if (mode0)
- tmp |= (1 << MC_DISP0R_INIT_LAT_SHIFT);
- WREG32_MC(MC_INIT_MISC_LAT_TIMER, tmp);
+ tmp |= S_000104_MC_DISP0R_INIT_LAT(1);
+ if (mode1)
+ tmp |= S_000104_MC_DISP1R_INIT_LAT(1);
+ WREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER, tmp);
}
rs690_line_buffer_adjust(rdev, mode0, mode1);
if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))
- WREG32(DCP_CONTROL, 0);
+ WREG32(R_006C9C_DCP_CONTROL, 0);
if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
- WREG32(DCP_CONTROL, 2);
+ WREG32(R_006C9C_DCP_CONTROL, 2);
rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0);
rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1);
tmp = (wm0.lb_request_fifo_depth - 1);
tmp |= (wm1.lb_request_fifo_depth - 1) << 16;
- WREG32(LB_MAX_REQ_OUTSTANDING, tmp);
+ WREG32(R_006D58_LB_MAX_REQ_OUTSTANDING, tmp);
if (mode0 && mode1) {
if (rfixed_trunc(wm0.dbpp) > 64)
@@ -561,10 +481,10 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
priority_mark12.full = 0;
if (wm1.priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1.priority_mark_max.full;
- WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
- WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
- WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
- WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+ WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
+ WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
+ WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
+ WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
} else if (mode0) {
if (rfixed_trunc(wm0.dbpp) > 64)
a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair);
@@ -591,10 +511,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
priority_mark02.full = 0;
if (wm0.priority_mark_max.full > priority_mark02.full)
priority_mark02.full = wm0.priority_mark_max.full;
- WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
- WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
- WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
- WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
+ WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
+ WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
+ WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,
+ S_006D48_D2MODE_PRIORITY_A_OFF(1));
+ WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT,
+ S_006D4C_D2MODE_PRIORITY_B_OFF(1));
} else {
if (rfixed_trunc(wm1.dbpp) > 64)
a.full = rfixed_mul(wm1.dbpp, wm1.num_line_pair);
@@ -621,30 +543,203 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
priority_mark12.full = 0;
if (wm1.priority_mark_max.full > priority_mark12.full)
priority_mark12.full = wm1.priority_mark_max.full;
- WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
- WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
- WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
- WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
+ WREG32(R_006548_D1MODE_PRIORITY_A_CNT,
+ S_006548_D1MODE_PRIORITY_A_OFF(1));
+ WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,
+ S_00654C_D1MODE_PRIORITY_B_OFF(1));
+ WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
+ WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
}
}
-/*
- * Indirect registers accessor
- */
uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)
{
uint32_t r;
- WREG32(RS690_MC_INDEX, (reg & RS690_MC_INDEX_MASK));
- r = RREG32(RS690_MC_DATA);
- WREG32(RS690_MC_INDEX, RS690_MC_INDEX_MASK);
+ WREG32(R_000078_MC_INDEX, S_000078_MC_IND_ADDR(reg));
+ r = RREG32(R_00007C_MC_DATA);
+ WREG32(R_000078_MC_INDEX, ~C_000078_MC_IND_ADDR);
return r;
}
void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{
- WREG32(RS690_MC_INDEX,
- RS690_MC_INDEX_WR_EN | ((reg) & RS690_MC_INDEX_MASK));
- WREG32(RS690_MC_DATA, v);
- WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
+ WREG32(R_000078_MC_INDEX, S_000078_MC_IND_ADDR(reg) |
+ S_000078_MC_IND_WR_EN(1));
+ WREG32(R_00007C_MC_DATA, v);
+ WREG32(R_000078_MC_INDEX, 0x7F);
+}
+
+void rs690_mc_program(struct radeon_device *rdev)
+{
+ struct rv515_mc_save save;
+
+ /* Stops all mc clients */
+ rv515_mc_stop(rdev, &save);
+
+ /* Wait for mc idle */
+ if (rs690_mc_wait_for_idle(rdev))
+ dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
+ /* Program MC, should be a 32bits limited address space */
+ WREG32_MC(R_000100_MCCFG_FB_LOCATION,
+ S_000100_MC_FB_START(rdev->mc.vram_start >> 16) |
+ S_000100_MC_FB_TOP(rdev->mc.vram_end >> 16));
+ WREG32(R_000134_HDP_FB_LOCATION,
+ S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
+
+ rv515_mc_resume(rdev, &save);
+}
+
+static int rs690_startup(struct radeon_device *rdev)
+{
+ int r;
+
+ rs690_mc_program(rdev);
+ /* Resume clock */
+ rv515_clock_startup(rdev);
+ /* Initialize GPU configuration (# pipes, ...) */
+ rs690_gpu_init(rdev);
+ /* Initialize GART (initialize after TTM so we can allocate
+ * memory through TTM but finalize after TTM) */
+ r = rs400_gart_enable(rdev);
+ if (r)
+ return r;
+ /* Enable IRQ */
+ rdev->irq.sw_int = true;
+ rs600_irq_set(rdev);
+ /* 1M ring buffer */
+ r = r100_cp_init(rdev, 1024 * 1024);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+ return r;
+ }
+ r = r100_wb_init(rdev);
+ if (r)
+ dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+ r = r100_ib_init(rdev);
+ if (r) {
+ dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+ return r;
+ }
+ return 0;
+}
+
+int rs690_resume(struct radeon_device *rdev)
+{
+ /* Make sur GART are not working */
+ rs400_gart_disable(rdev);
+ /* Resume clock before doing reset */
+ rv515_clock_startup(rdev);
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* post */
+ atom_asic_init(rdev->mode_info.atom_context);
+ /* Resume clock after posting */
+ rv515_clock_startup(rdev);
+ return rs690_startup(rdev);
+}
+
+int rs690_suspend(struct radeon_device *rdev)
+{
+ r100_cp_disable(rdev);
+ r100_wb_disable(rdev);
+ rs600_irq_disable(rdev);
+ rs400_gart_disable(rdev);
+ return 0;
+}
+
+void rs690_fini(struct radeon_device *rdev)
+{
+ rs690_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ radeon_gem_fini(rdev);
+ rs400_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ radeon_fence_driver_fini(rdev);
+ radeon_object_fini(rdev);
+ radeon_atombios_fini(rdev);
+ kfree(rdev->bios);
+ rdev->bios = NULL;
+}
+
+int rs690_init(struct radeon_device *rdev)
+{
+ int r;
+
+ /* Disable VGA */
+ rv515_vga_render_disable(rdev);
+ /* Initialize scratch registers */
+ radeon_scratch_init(rdev);
+ /* Initialize surface registers */
+ radeon_surface_init(rdev);
+ /* TODO: disable VGA need to use VGA request */
+ /* BIOS*/
+ if (!radeon_get_bios(rdev)) {
+ if (ASIC_IS_AVIVO(rdev))
+ return -EINVAL;
+ }
+ if (rdev->is_atom_bios) {
+ r = radeon_atombios_init(rdev);
+ if (r)
+ return r;
+ } else {
+ dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n");
+ return -EINVAL;
+ }
+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+ if (radeon_gpu_reset(rdev)) {
+ dev_warn(rdev->dev,
+ "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+ RREG32(R_000E40_RBBM_STATUS),
+ RREG32(R_0007C0_CP_STAT));
+ }
+ /* check if cards are posted or not */
+ if (!radeon_card_posted(rdev) && rdev->bios) {
+ DRM_INFO("GPU not posted. posting now...\n");
+ atom_asic_init(rdev->mode_info.atom_context);
+ }
+ /* Initialize clocks */
+ radeon_get_clock_info(rdev->ddev);
+ /* Get vram informations */
+ rs690_vram_info(rdev);
+ /* Initialize memory controller (also test AGP) */
+ r = r420_mc_init(rdev);
+ if (r)
+ return r;
+ rv515_debugfs(rdev);
+ /* Fence driver */
+ r = radeon_fence_driver_init(rdev);
+ if (r)
+ return r;
+ r = radeon_irq_kms_init(rdev);
+ if (r)
+ return r;
+ /* Memory manager */
+ r = radeon_object_init(rdev);
+ if (r)
+ return r;
+ r = rs400_gart_init(rdev);
+ if (r)
+ return r;
+ rs600_set_safe_registers(rdev);
+ rdev->accel_working = true;
+ r = rs690_startup(rdev);
+ if (r) {
+ /* Somethings want wront with the accel init stop accel */
+ dev_err(rdev->dev, "Disabling GPU acceleration\n");
+ rs690_suspend(rdev);
+ r100_cp_fini(rdev);
+ r100_wb_fini(rdev);
+ r100_ib_fini(rdev);
+ rs400_gart_fini(rdev);
+ radeon_irq_kms_fini(rdev);
+ rdev->accel_working = false;
+ }
+ return 0;
}
diff --git a/drivers/gpu/drm/radeon/rs690d.h b/drivers/gpu/drm/radeon/rs690d.h
new file mode 100644
index 00000000000..62d31e7a897
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs690d.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ */
+#ifndef __RS690D_H__
+#define __RS690D_H__
+
+/* Registers */
+#define R_000078_MC_INDEX 0x000078
+#define S_000078_MC_IND_ADDR(x) (((x) & 0x1FF) << 0)
+#define G_000078_MC_IND_ADDR(x) (((x) >> 0) & 0x1FF)
+#define C_000078_MC_IND_ADDR 0xFFFFFE00
+#define S_000078_MC_IND_WR_EN(x) (((x) & 0x1) << 9)
+#define G_000078_MC_IND_WR_EN(x) (((x) >> 9) & 0x1)
+#define C_000078_MC_IND_WR_EN 0xFFFFFDFF
+#define R_00007C_MC_DATA 0x00007C
+#define S_00007C_MC_DATA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00007C_MC_DATA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00007C_MC_DATA 0x00000000
+#define R_0000F8_CONFIG_MEMSIZE 0x0000F8
+#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0000F8_CONFIG_MEMSIZE 0x00000000
+#define R_000134_HDP_FB_LOCATION 0x000134
+#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0)
+#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF)
+#define C_000134_HDP_FB_START 0xFFFF0000
+#define R_0007C0_CP_STAT 0x0007C0
+#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
+#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
+#define C_0007C0_MRU_BUSY 0xFFFFFFFE
+#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
+#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
+#define C_0007C0_MWU_BUSY 0xFFFFFFFD
+#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
+#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
+#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
+#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
+#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
+#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
+#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
+#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
+#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
+#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
+#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
+#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
+#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
+#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
+#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
+#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
+#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
+#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
+#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
+#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
+#define C_0007C0_CSI_BUSY 0xFFFFDFFF
+#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
+#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
+#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
+#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
+#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
+#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
+#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
+#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
+#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
+#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
+#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
+#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
+#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
+#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
+#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
+#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
+#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
+#define C_0007C0_CP_BUSY 0x7FFFFFFF
+#define R_000E40_RBBM_STATUS 0x000E40
+#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
+#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
+#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
+#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
+#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
+#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
+#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
+#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
+#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
+#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
+#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
+#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
+#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
+#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
+#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
+#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
+#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
+#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
+#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
+#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
+#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
+#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
+#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
+#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
+#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
+#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
+#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
+#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
+#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
+#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
+#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
+#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
+#define C_000E40_E2_BUSY 0xFFFDFFFF
+#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
+#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
+#define C_000E40_RB2D_BUSY 0xFFFBFFFF
+#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
+#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
+#define C_000E40_RB3D_BUSY 0xFFF7FFFF
+#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
+#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
+#define C_000E40_VAP_BUSY 0xFFEFFFFF
+#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
+#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
+#define C_000E40_RE_BUSY 0xFFDFFFFF
+#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
+#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
+#define C_000E40_TAM_BUSY 0xFFBFFFFF
+#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
+#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
+#define C_000E40_TDM_BUSY 0xFF7FFFFF
+#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
+#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
+#define C_000E40_PB_BUSY 0xFEFFFFFF
+#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
+#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
+#define C_000E40_TIM_BUSY 0xFDFFFFFF
+#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
+#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
+#define C_000E40_GA_BUSY 0xFBFFFFFF
+#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
+#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
+#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
+#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
+#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
+#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
+#define R_006520_DC_LB_MEMORY_SPLIT 0x006520
+#define S_006520_DC_LB_MEMORY_SPLIT(x) (((x) & 0x3) << 0)
+#define G_006520_DC_LB_MEMORY_SPLIT(x) (((x) >> 0) & 0x3)
+#define C_006520_DC_LB_MEMORY_SPLIT 0xFFFFFFFC
+#define S_006520_DC_LB_MEMORY_SPLIT_MODE(x) (((x) & 0x1) << 2)
+#define G_006520_DC_LB_MEMORY_SPLIT_MODE(x) (((x) >> 2) & 0x1)
+#define C_006520_DC_LB_MEMORY_SPLIT_MODE 0xFFFFFFFB
+#define V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0
+#define V_006520_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1
+#define V_006520_DC_LB_MEMORY_SPLIT_D1_ONLY 2
+#define V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3
+#define S_006520_DC_LB_DISP1_END_ADR(x) (((x) & 0x7FF) << 4)
+#define G_006520_DC_LB_DISP1_END_ADR(x) (((x) >> 4) & 0x7FF)
+#define C_006520_DC_LB_DISP1_END_ADR 0xFFFF800F
+#define R_006548_D1MODE_PRIORITY_A_CNT 0x006548
+#define S_006548_D1MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0)
+#define G_006548_D1MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF)
+#define C_006548_D1MODE_PRIORITY_MARK_A 0xFFFF8000
+#define S_006548_D1MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16)
+#define G_006548_D1MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1)
+#define C_006548_D1MODE_PRIORITY_A_OFF 0xFFFEFFFF
+#define S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24)
+#define G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1)
+#define C_006548_D1MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF
+#define R_00654C_D1MODE_PRIORITY_B_CNT 0x00654C
+#define S_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0)
+#define G_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF)
+#define C_00654C_D1MODE_PRIORITY_MARK_B 0xFFFF8000
+#define S_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16)
+#define G_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1)
+#define C_00654C_D1MODE_PRIORITY_B_OFF 0xFFFEFFFF
+#define S_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20)
+#define G_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1)
+#define C_00654C_D1MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF
+#define S_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24)
+#define G_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1)
+#define C_00654C_D1MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF
+#define R_006C9C_DCP_CONTROL 0x006C9C
+#define R_006D48_D2MODE_PRIORITY_A_CNT 0x006D48
+#define S_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0)
+#define G_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF)
+#define C_006D48_D2MODE_PRIORITY_MARK_A 0xFFFF8000
+#define S_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16)
+#define G_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1)
+#define C_006D48_D2MODE_PRIORITY_A_OFF 0xFFFEFFFF
+#define S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20)
+#define G_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1)
+#define C_006D48_D2MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF
+#define S_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24)
+#define G_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1)
+#define C_006D48_D2MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF
+#define R_006D4C_D2MODE_PRIORITY_B_CNT 0x006D4C
+#define S_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0)
+#define G_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF)
+#define C_006D4C_D2MODE_PRIORITY_MARK_B 0xFFFF8000
+#define S_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16)
+#define G_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1)
+#define C_006D4C_D2MODE_PRIORITY_B_OFF 0xFFFEFFFF
+#define S_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20)
+#define G_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1)
+#define C_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF
+#define S_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24)
+#define G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1)
+#define C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF
+#define R_006D58_LB_MAX_REQ_OUTSTANDING 0x006D58
+#define S_006D58_LB_D1_MAX_REQ_OUTSTANDING(x) (((x) & 0xF) << 0)
+#define G_006D58_LB_D1_MAX_REQ_OUTSTANDING(x) (((x) >> 0) & 0xF)
+#define C_006D58_LB_D1_MAX_REQ_OUTSTANDING 0xFFFFFFF0
+#define S_006D58_LB_D2_MAX_REQ_OUTSTANDING(x) (((x) & 0xF) << 16)
+#define G_006D58_LB_D2_MAX_REQ_OUTSTANDING(x) (((x) >> 16) & 0xF)
+#define C_006D58_LB_D2_MAX_REQ_OUTSTANDING 0xFFF0FFFF
+
+
+#define R_000090_MC_SYSTEM_STATUS 0x000090
+#define S_000090_MC_SYSTEM_IDLE(x) (((x) & 0x1) << 0)
+#define G_000090_MC_SYSTEM_IDLE(x) (((x) >> 0) & 0x1)
+#define C_000090_MC_SYSTEM_IDLE 0xFFFFFFFE
+#define S_000090_MC_SEQUENCER_IDLE(x) (((x) & 0x1) << 1)
+#define G_000090_MC_SEQUENCER_IDLE(x) (((x) >> 1) & 0x1)
+#define C_000090_MC_SEQUENCER_IDLE 0xFFFFFFFD
+#define S_000090_MC_ARBITER_IDLE(x) (((x) & 0x1) << 2)
+#define G_000090_MC_ARBITER_IDLE(x) (((x) >> 2) & 0x1)
+#define C_000090_MC_ARBITER_IDLE 0xFFFFFFFB
+#define S_000090_MC_SELECT_PM(x) (((x) & 0x1) << 3)
+#define G_000090_MC_SELECT_PM(x) (((x) >> 3) & 0x1)
+#define C_000090_MC_SELECT_PM 0xFFFFFFF7
+#define S_000090_RESERVED4(x) (((x) & 0xF) << 4)
+#define G_000090_RESERVED4(x) (((x) >> 4) & 0xF)
+#define C_000090_RESERVED4 0xFFFFFF0F
+#define S_000090_RESERVED8(x) (((x) & 0xF) << 8)
+#define G_000090_RESERVED8(x) (((x) >> 8) & 0xF)
+#define C_000090_RESERVED8 0xFFFFF0FF
+#define S_000090_RESERVED12(x) (((x) & 0xF) << 12)
+#define G_000090_RESERVED12(x) (((x) >> 12) & 0xF)
+#define C_000090_RESERVED12 0xFFFF0FFF
+#define S_000090_MCA_INIT_EXECUTED(x) (((x) & 0x1) << 16)
+#define G_000090_MCA_INIT_EXECUTED(x) (((x) >> 16) & 0x1)
+#define C_000090_MCA_INIT_EXECUTED 0xFFFEFFFF
+#define S_000090_MCA_IDLE(x) (((x) & 0x1) << 17)
+#define G_000090_MCA_IDLE(x) (((x) >> 17) & 0x1)
+#define C_000090_MCA_IDLE 0xFFFDFFFF
+#define S_000090_MCA_SEQ_IDLE(x) (((x) & 0x1) << 18)
+#define G_000090_MCA_SEQ_IDLE(x) (((x) >> 18) & 0x1)
+#define C_000090_MCA_SEQ_IDLE 0xFFFBFFFF
+#define S_000090_MCA_ARB_IDLE(x) (((x) & 0x1) << 19)
+#define G_000090_MCA_ARB_IDLE(x) (((x) >> 19) & 0x1)
+#define C_000090_MCA_ARB_IDLE 0xFFF7FFFF
+#define S_000090_RESERVED20(x) (((x) & 0xFFF) << 20)
+#define G_000090_RESERVED20(x) (((x) >> 20) & 0xFFF)
+#define C_000090_RESERVED20 0x000FFFFF
+#define R_000100_MCCFG_FB_LOCATION 0x000100
+#define S_000100_MC_FB_START(x) (((x) & 0xFFFF) << 0)
+#define G_000100_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
+#define C_000100_MC_FB_START 0xFFFF0000
+#define S_000100_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
+#define G_000100_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
+#define C_000100_MC_FB_TOP 0x0000FFFF
+#define R_000104_MC_INIT_MISC_LAT_TIMER 0x000104
+#define S_000104_MC_CPR_INIT_LAT(x) (((x) & 0xF) << 0)
+#define G_000104_MC_CPR_INIT_LAT(x) (((x) >> 0) & 0xF)
+#define C_000104_MC_CPR_INIT_LAT 0xFFFFFFF0
+#define S_000104_MC_VF_INIT_LAT(x) (((x) & 0xF) << 4)
+#define G_000104_MC_VF_INIT_LAT(x) (((x) >> 4) & 0xF)
+#define C_000104_MC_VF_INIT_LAT 0xFFFFFF0F
+#define S_000104_MC_DISP0R_INIT_LAT(x) (((x) & 0xF) << 8)
+#define G_000104_MC_DISP0R_INIT_LAT(x) (((x) >> 8) & 0xF)
+#define C_000104_MC_DISP0R_INIT_LAT 0xFFFFF0FF
+#define S_000104_MC_DISP1R_INIT_LAT(x) (((x) & 0xF) << 12)
+#define G_000104_MC_DISP1R_INIT_LAT(x) (((x) >> 12) & 0xF)
+#define C_000104_MC_DISP1R_INIT_LAT 0xFFFF0FFF
+#define S_000104_MC_FIXED_INIT_LAT(x) (((x) & 0xF) << 16)
+#define G_000104_MC_FIXED_INIT_LAT(x) (((x) >> 16) & 0xF)
+#define C_000104_MC_FIXED_INIT_LAT 0xFFF0FFFF
+#define S_000104_MC_E2R_INIT_LAT(x) (((x) & 0xF) << 20)
+#define G_000104_MC_E2R_INIT_LAT(x) (((x) >> 20) & 0xF)
+#define C_000104_MC_E2R_INIT_LAT 0xFF0FFFFF
+#define S_000104_SAME_PAGE_PRIO(x) (((x) & 0xF) << 24)
+#define G_000104_SAME_PAGE_PRIO(x) (((x) >> 24) & 0xF)
+#define C_000104_SAME_PAGE_PRIO 0xF0FFFFFF
+#define S_000104_MC_GLOBW_INIT_LAT(x) (((x) & 0xF) << 28)
+#define G_000104_MC_GLOBW_INIT_LAT(x) (((x) >> 28) & 0xF)
+#define C_000104_MC_GLOBW_INIT_LAT 0x0FFFFFFF
+
+#endif
diff --git a/drivers/gpu/drm/radeon/rs690r.h b/drivers/gpu/drm/radeon/rs690r.h
deleted file mode 100644
index c0d9faa2175..00000000000
--- a/drivers/gpu/drm/radeon/rs690r.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2008 Advanced Micro Devices, Inc.
- * Copyright 2008 Red Hat Inc.
- * Copyright 2009 Jerome Glisse.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Dave Airlie
- * Alex Deucher
- * Jerome Glisse
- */
-#ifndef RS690R_H
-#define RS690R_H
-
-/* RS690/RS740 registers */
-#define MC_INDEX 0x0078
-# define MC_INDEX_MASK 0x1FF
-# define MC_INDEX_WR_EN (1 << 9)
-# define MC_INDEX_WR_ACK 0x7F
-#define MC_DATA 0x007C
-#define HDP_FB_LOCATION 0x0134
-#define DC_LB_MEMORY_SPLIT 0x6520
-#define DC_LB_MEMORY_SPLIT_MASK 0x00000003
-#define DC_LB_MEMORY_SPLIT_SHIFT 0
-#define DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0
-#define DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1
-#define DC_LB_MEMORY_SPLIT_D1_ONLY 2
-#define DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3
-#define DC_LB_MEMORY_SPLIT_SHIFT_MODE (1 << 2)
-#define DC_LB_DISP1_END_ADR_SHIFT 4
-#define DC_LB_DISP1_END_ADR_MASK 0x00007FF0
-#define D1MODE_PRIORITY_A_CNT 0x6548
-#define MODE_PRIORITY_MARK_MASK 0x00007FFF
-#define MODE_PRIORITY_OFF (1 << 16)
-#define MODE_PRIORITY_ALWAYS_ON (1 << 20)
-#define MODE_PRIORITY_FORCE_MASK (1 << 24)
-#define D1MODE_PRIORITY_B_CNT 0x654C
-#define LB_MAX_REQ_OUTSTANDING 0x6D58
-#define LB_D1_MAX_REQ_OUTSTANDING_MASK 0x0000000F
-#define LB_D1_MAX_REQ_OUTSTANDING_SHIFT 0
-#define LB_D2_MAX_REQ_OUTSTANDING_MASK 0x000F0000
-#define LB_D2_MAX_REQ_OUTSTANDING_SHIFT 16
-#define DCP_CONTROL 0x6C9C
-#define D2MODE_PRIORITY_A_CNT 0x6D48
-#define D2MODE_PRIORITY_B_CNT 0x6D4C
-
-/* MC indirect registers */
-#define MC_STATUS_IDLE (1 << 0)
-#define MC_MISC_CNTL 0x18
-#define DISABLE_GTW (1 << 1)
-#define GART_INDEX_REG_EN (1 << 12)
-#define BLOCK_GFX_D3_EN (1 << 14)
-#define GART_FEATURE_ID 0x2B
-#define HANG_EN (1 << 11)
-#define TLB_ENABLE (1 << 18)
-#define P2P_ENABLE (1 << 19)
-#define GTW_LAC_EN (1 << 25)
-#define LEVEL2_GART (0 << 30)
-#define LEVEL1_GART (1 << 30)
-#define PDC_EN (1 << 31)
-#define GART_BASE 0x2C
-#define GART_CACHE_CNTRL 0x2E
-# define GART_CACHE_INVALIDATE (1 << 0)
-#define MC_STATUS 0x90
-#define MCCFG_FB_LOCATION 0x100
-#define MC_FB_START_MASK 0x0000FFFF
-#define MC_FB_START_SHIFT 0
-#define MC_FB_TOP_MASK 0xFFFF0000
-#define MC_FB_TOP_SHIFT 16
-#define MCCFG_AGP_LOCATION 0x101
-#define MC_AGP_START_MASK 0x0000FFFF
-#define MC_AGP_START_SHIFT 0
-#define MC_AGP_TOP_MASK 0xFFFF0000
-#define MC_AGP_TOP_SHIFT 16
-#define MCCFG_AGP_BASE 0x102
-#define MCCFG_AGP_BASE_2 0x103
-#define MC_INIT_MISC_LAT_TIMER 0x104
-#define MC_DISP0R_INIT_LAT_SHIFT 8
-#define MC_DISP0R_INIT_LAT_MASK 0x00000F00
-#define MC_DISP1R_INIT_LAT_SHIFT 12
-#define MC_DISP1R_INIT_LAT_MASK 0x0000F000
-
-#endif
diff --git a/drivers/gpu/drm/radeon/rv200d.h b/drivers/gpu/drm/radeon/rv200d.h
new file mode 100644
index 00000000000..c5b398330c2
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv200d.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ */
+#ifndef __RV200D_H__
+#define __RV200D_H__
+
+#define R_00015C_AGP_BASE_2 0x00015C
+#define S_00015C_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0)
+#define G_00015C_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF)
+#define C_00015C_AGP_BASE_ADDR_2 0xFFFFFFF0
+
+#endif
diff --git a/drivers/gpu/drm/radeon/rv250d.h b/drivers/gpu/drm/radeon/rv250d.h
new file mode 100644
index 00000000000..e5a70b06fe1
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv250d.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ */
+#ifndef __RV250D_H__
+#define __RV250D_H__
+
+#define R_00000D_SCLK_CNTL_M6 0x00000D
+#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
+#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7)
+#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8
+#define S_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 3)
+#define G_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) >> 3) & 0x1)
+#define C_00000D_CP_MAX_DYN_STOP_LAT 0xFFFFFFF7
+#define S_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 4)
+#define G_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) >> 4) & 0x1)
+#define C_00000D_HDP_MAX_DYN_STOP_LAT 0xFFFFFFEF
+#define S_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 5)
+#define G_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) >> 5) & 0x1)
+#define C_00000D_TV_MAX_DYN_STOP_LAT 0xFFFFFFDF
+#define S_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 6)
+#define G_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) >> 6) & 0x1)
+#define C_00000D_E2_MAX_DYN_STOP_LAT 0xFFFFFFBF
+#define S_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 7)
+#define G_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) >> 7) & 0x1)
+#define C_00000D_SE_MAX_DYN_STOP_LAT 0xFFFFFF7F
+#define S_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 8)
+#define G_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 8) & 0x1)
+#define C_00000D_IDCT_MAX_DYN_STOP_LAT 0xFFFFFEFF
+#define S_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 9)
+#define G_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) >> 9) & 0x1)
+#define C_00000D_VIP_MAX_DYN_STOP_LAT 0xFFFFFDFF
+#define S_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 10)
+#define G_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) >> 10) & 0x1)
+#define C_00000D_RE_MAX_DYN_STOP_LAT 0xFFFFFBFF
+#define S_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 11)
+#define G_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) >> 11) & 0x1)
+#define C_00000D_PB_MAX_DYN_STOP_LAT 0xFFFFF7FF
+#define S_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 12)
+#define G_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) >> 12) & 0x1)
+#define C_00000D_TAM_MAX_DYN_STOP_LAT 0xFFFFEFFF
+#define S_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 13)
+#define G_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) >> 13) & 0x1)
+#define C_00000D_TDM_MAX_DYN_STOP_LAT 0xFFFFDFFF
+#define S_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 14)
+#define G_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) >> 14) & 0x1)
+#define C_00000D_RB_MAX_DYN_STOP_LAT 0xFFFFBFFF
+#define S_00000D_FORCE_DISP2(x) (((x) & 0x1) << 15)
+#define G_00000D_FORCE_DISP2(x) (((x) >> 15) & 0x1)
+#define C_00000D_FORCE_DISP2 0xFFFF7FFF
+#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16)
+#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1)
+#define C_00000D_FORCE_CP 0xFFFEFFFF
+#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17)
+#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1)
+#define C_00000D_FORCE_HDP 0xFFFDFFFF
+#define S_00000D_FORCE_DISP1(x) (((x) & 0x1) << 18)
+#define G_00000D_FORCE_DISP1(x) (((x) >> 18) & 0x1)
+#define C_00000D_FORCE_DISP1 0xFFFBFFFF
+#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19)
+#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1)
+#define C_00000D_FORCE_TOP 0xFFF7FFFF
+#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
+#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
+#define C_00000D_FORCE_E2 0xFFEFFFFF
+#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21)
+#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1)
+#define C_00000D_FORCE_SE 0xFFDFFFFF
+#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
+#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
+#define C_00000D_FORCE_IDCT 0xFFBFFFFF
+#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23)
+#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1)
+#define C_00000D_FORCE_VIP 0xFF7FFFFF
+#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
+#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
+#define C_00000D_FORCE_RE 0xFEFFFFFF
+#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25)
+#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1)
+#define C_00000D_FORCE_PB 0xFDFFFFFF
+#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26)
+#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1)
+#define C_00000D_FORCE_TAM 0xFBFFFFFF
+#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27)
+#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1)
+#define C_00000D_FORCE_TDM 0xF7FFFFFF
+#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28)
+#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
+#define C_00000D_FORCE_RB 0xEFFFFFFF
+#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29)
+#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1)
+#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF
+#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30)
+#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1)
+#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF
+#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31)
+#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1)
+#define C_00000D_FORCE_OV0 0x7FFFFFFF
+
+#endif
diff --git a/drivers/gpu/drm/radeon/rv350d.h b/drivers/gpu/drm/radeon/rv350d.h
new file mode 100644
index 00000000000..c75c5ed9e65
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv350d.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ */
+#ifndef __RV350D_H__
+#define __RV350D_H__
+
+/* RV350, RV380 registers */
+/* #define R_00000D_SCLK_CNTL 0x00000D */
+#define S_00000D_FORCE_VAP(x) (((x) & 0x1) << 21)
+#define G_00000D_FORCE_VAP(x) (((x) >> 21) & 0x1)
+#define C_00000D_FORCE_VAP 0xFFDFFFFF
+#define S_00000D_FORCE_SR(x) (((x) & 0x1) << 25)
+#define G_00000D_FORCE_SR(x) (((x) >> 25) & 0x1)
+#define C_00000D_FORCE_SR 0xFDFFFFFF
+#define S_00000D_FORCE_PX(x) (((x) & 0x1) << 26)
+#define G_00000D_FORCE_PX(x) (((x) >> 26) & 0x1)
+#define C_00000D_FORCE_PX 0xFBFFFFFF
+#define S_00000D_FORCE_TX(x) (((x) & 0x1) << 27)
+#define G_00000D_FORCE_TX(x) (((x) >> 27) & 0x1)
+#define C_00000D_FORCE_TX 0xF7FFFFFF
+#define S_00000D_FORCE_US(x) (((x) & 0x1) << 28)
+#define G_00000D_FORCE_US(x) (((x) >> 28) & 0x1)
+#define C_00000D_FORCE_US 0xEFFFFFFF
+#define S_00000D_FORCE_SU(x) (((x) & 0x1) << 30)
+#define G_00000D_FORCE_SU(x) (((x) >> 30) & 0x1)
+#define C_00000D_FORCE_SU 0xBFFFFFFF
+
+#endif
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index e53b5ca7a25..41a34c23e6d 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -478,7 +478,7 @@ static int rv515_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
rdev->irq.sw_int = true;
- r100_irq_set(rdev);
+ rs600_irq_set(rdev);
/* 1M ring buffer */
r = r100_cp_init(rdev, 1024 * 1024);
if (r) {
@@ -520,7 +520,7 @@ int rv515_suspend(struct radeon_device *rdev)
{
r100_cp_disable(rdev);
r100_wb_disable(rdev);
- r100_irq_disable(rdev);
+ rs600_irq_disable(rdev);
if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev);
return 0;
@@ -553,7 +553,6 @@ int rv515_init(struct radeon_device *rdev)
{
int r;
- rdev->new_init_path = true;
/* Initialize scratch registers */
radeon_scratch_init(rdev);
/* Initialize surface registers */
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index e0b97d16139..595ac638039 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -75,7 +75,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
- WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12);
+ WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
@@ -126,17 +126,36 @@ void rv770_pcie_gart_fini(struct radeon_device *rdev)
}
-/*
- * MC
- */
-static void rv770_mc_resume(struct radeon_device *rdev)
+void rv770_agp_enable(struct radeon_device *rdev)
{
- u32 d1vga_control, d2vga_control;
- u32 vga_render_control, vga_hdp_control;
- u32 d1crtc_control, d2crtc_control;
- u32 new_d1grph_primary, new_d1grph_secondary;
- u32 new_d2grph_primary, new_d2grph_secondary;
- u64 old_vram_start;
+ u32 tmp;
+ int i;
+
+ /* Setup L2 cache */
+ WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
+ ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+ EFFECTIVE_L2_QUEUE_SIZE(7));
+ WREG32(VM_L2_CNTL2, 0);
+ WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
+ /* Setup TLB control */
+ tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
+ SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+ SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
+ EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
+ WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
+ WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
+ WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
+ WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
+ WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
+ WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
+ WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
+ for (i = 0; i < 7; i++)
+ WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+}
+
+static void rv770_mc_program(struct radeon_device *rdev)
+{
+ struct rv515_mc_save save;
u32 tmp;
int i, j;
@@ -150,53 +169,42 @@ static void rv770_mc_resume(struct radeon_device *rdev)
}
WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
- d1vga_control = RREG32(D1VGA_CONTROL);
- d2vga_control = RREG32(D2VGA_CONTROL);
- vga_render_control = RREG32(VGA_RENDER_CONTROL);
- vga_hdp_control = RREG32(VGA_HDP_CONTROL);
- d1crtc_control = RREG32(D1CRTC_CONTROL);
- d2crtc_control = RREG32(D2CRTC_CONTROL);
- old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
- new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
- new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
- new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
- new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
- new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
- new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
- new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
- new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
-
- /* Stop all video */
- WREG32(D1VGA_CONTROL, 0);
- WREG32(D2VGA_CONTROL, 0);
- WREG32(VGA_RENDER_CONTROL, 0);
- WREG32(D1CRTC_UPDATE_LOCK, 1);
- WREG32(D2CRTC_UPDATE_LOCK, 1);
- WREG32(D1CRTC_CONTROL, 0);
- WREG32(D2CRTC_CONTROL, 0);
- WREG32(D1CRTC_UPDATE_LOCK, 0);
- WREG32(D2CRTC_UPDATE_LOCK, 0);
-
- mdelay(1);
+ rv515_mc_stop(rdev, &save);
if (r600_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "[drm] MC not idle !\n");
+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
}
-
/* Lockout access through VGA aperture*/
WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
-
/* Update configuration */
- WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
- WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
+ if (rdev->flags & RADEON_IS_AGP) {
+ if (rdev->mc.vram_start < rdev->mc.gtt_start) {
+ /* VRAM before AGP */
+ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+ rdev->mc.vram_start >> 12);
+ WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+ rdev->mc.gtt_end >> 12);
+ } else {
+ /* VRAM after AGP */
+ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+ rdev->mc.gtt_start >> 12);
+ WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+ rdev->mc.vram_end >> 12);
+ }
+ } else {
+ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+ rdev->mc.vram_start >> 12);
+ WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+ rdev->mc.vram_end >> 12);
+ }
WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
- tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16;
+ tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
WREG32(MC_VM_FB_LOCATION, tmp);
WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
WREG32(HDP_NONSURFACE_INFO, (2 << 7));
WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
if (rdev->flags & RADEON_IS_AGP) {
- WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16);
+ WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
} else {
@@ -204,31 +212,10 @@ static void rv770_mc_resume(struct radeon_device *rdev)
WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
}
- WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
- WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
- WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
- WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
- WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
-
- /* Unlock host access */
- WREG32(VGA_HDP_CONTROL, vga_hdp_control);
-
- mdelay(1);
if (r600_mc_wait_for_idle(rdev)) {
- printk(KERN_WARNING "[drm] MC not idle !\n");
+ dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
}
-
- /* Restore video state */
- WREG32(D1CRTC_UPDATE_LOCK, 1);
- WREG32(D2CRTC_UPDATE_LOCK, 1);
- WREG32(D1CRTC_CONTROL, d1crtc_control);
- WREG32(D2CRTC_CONTROL, d2crtc_control);
- WREG32(D1CRTC_UPDATE_LOCK, 0);
- WREG32(D2CRTC_UPDATE_LOCK, 0);
- WREG32(D1VGA_CONTROL, d1vga_control);
- WREG32(D2VGA_CONTROL, d2vga_control);
- WREG32(VGA_RENDER_CONTROL, vga_render_control);
-
+ rv515_mc_resume(rdev, &save);
/* we need to own VRAM, so turn off the VGA renderer here
* to stop it overwriting our objects */
rv515_vga_render_disable(rdev);
@@ -840,9 +827,9 @@ int rv770_mc_init(struct radeon_device *rdev)
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
}
rdev->mc.vram_start = rdev->mc.vram_location;
- rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+ rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
rdev->mc.gtt_start = rdev->mc.gtt_location;
- rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size;
+ rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
/* FIXME: we should enforce default clock in case GPU is not in
* default setup
*/
@@ -861,11 +848,14 @@ static int rv770_startup(struct radeon_device *rdev)
{
int r;
- radeon_gpu_reset(rdev);
- rv770_mc_resume(rdev);
- r = rv770_pcie_gart_enable(rdev);
- if (r)
- return r;
+ rv770_mc_program(rdev);
+ if (rdev->flags & RADEON_IS_AGP) {
+ rv770_agp_enable(rdev);
+ } else {
+ r = rv770_pcie_gart_enable(rdev);
+ if (r)
+ return r;
+ }
rv770_gpu_init(rdev);
r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
@@ -884,9 +874,8 @@ static int rv770_startup(struct radeon_device *rdev)
r = r600_cp_resume(rdev);
if (r)
return r;
- r = r600_wb_init(rdev);
- if (r)
- return r;
+ /* write back buffer are not vital so don't worry about failure */
+ r600_wb_enable(rdev);
return 0;
}
@@ -894,15 +883,12 @@ int rv770_resume(struct radeon_device *rdev)
{
int r;
- if (radeon_gpu_reset(rdev)) {
- /* FIXME: what do we want to do here ? */
- }
+ /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
+ * posting will perform necessary task to bring back GPU into good
+ * shape.
+ */
/* post card */
- if (rdev->is_atom_bios) {
- atom_asic_init(rdev->mode_info.atom_context);
- } else {
- radeon_combios_asic_init(rdev->ddev);
- }
+ atom_asic_init(rdev->mode_info.atom_context);
/* Initialize clocks */
r = radeon_clocks_init(rdev);
if (r) {
@@ -915,7 +901,7 @@ int rv770_resume(struct radeon_device *rdev)
return r;
}
- r = radeon_ib_test(rdev);
+ r = r600_ib_test(rdev);
if (r) {
DRM_ERROR("radeon: failled testing IB (%d).\n", r);
return r;
@@ -929,8 +915,8 @@ int rv770_suspend(struct radeon_device *rdev)
/* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev);
rdev->cp.ready = false;
+ r600_wb_disable(rdev);
rv770_pcie_gart_disable(rdev);
-
/* unpin shaders bo */
radeon_object_unpin(rdev->r600_blit.shader_obj);
return 0;
@@ -946,7 +932,6 @@ int rv770_init(struct radeon_device *rdev)
{
int r;
- rdev->new_init_path = true;
r = radeon_dummy_page_init(rdev);
if (r)
return r;
@@ -960,8 +945,10 @@ int rv770_init(struct radeon_device *rdev)
return -EINVAL;
}
/* Must be an ATOMBIOS */
- if (!rdev->is_atom_bios)
+ if (!rdev->is_atom_bios) {
+ dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
return -EINVAL;
+ }
r = radeon_atombios_init(rdev);
if (r)
return r;
@@ -983,15 +970,8 @@ int rv770_init(struct radeon_device *rdev)
if (r)
return r;
r = rv770_mc_init(rdev);
- if (r) {
- if (rdev->flags & RADEON_IS_AGP) {
- /* Retry with disabling AGP */
- rv770_fini(rdev);
- rdev->flags &= ~RADEON_IS_AGP;
- return rv770_init(rdev);
- }
+ if (r)
return r;
- }
/* Memory manager */
r = radeon_object_init(rdev);
if (r)
@@ -1020,12 +1000,10 @@ int rv770_init(struct radeon_device *rdev)
r = rv770_startup(rdev);
if (r) {
- if (rdev->flags & RADEON_IS_AGP) {
- /* Retry with disabling AGP */
- rv770_fini(rdev);
- rdev->flags &= ~RADEON_IS_AGP;
- return rv770_init(rdev);
- }
+ rv770_suspend(rdev);
+ r600_wb_fini(rdev);
+ radeon_ring_fini(rdev);
+ rv770_pcie_gart_fini(rdev);
rdev->accel_working = false;
}
if (rdev->accel_working) {
@@ -1034,7 +1012,7 @@ int rv770_init(struct radeon_device *rdev)
DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
rdev->accel_working = false;
}
- r = radeon_ib_test(rdev);
+ r = r600_ib_test(rdev);
if (r) {
DRM_ERROR("radeon: failled testing IB (%d).\n", r);
rdev->accel_working = false;
@@ -1049,20 +1027,15 @@ void rv770_fini(struct radeon_device *rdev)
r600_blit_fini(rdev);
radeon_ring_fini(rdev);
+ r600_wb_fini(rdev);
rv770_pcie_gart_fini(rdev);
radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_clocks_fini(rdev);
-#if __OS_HAS_AGP
if (rdev->flags & RADEON_IS_AGP)
radeon_agp_fini(rdev);
-#endif
radeon_object_fini(rdev);
- if (rdev->is_atom_bios) {
- radeon_atombios_fini(rdev);
- } else {
- radeon_combios_fini(rdev);
- }
+ radeon_atombios_fini(rdev);
kfree(rdev->bios);
rdev->bios = NULL;
radeon_dummy_page_fini(rdev);
diff --git a/drivers/gpu/drm/ttm/ttm_global.c b/drivers/gpu/drm/ttm/ttm_global.c
index 541744d00d3..b17007178a3 100644
--- a/drivers/gpu/drm/ttm/ttm_global.c
+++ b/drivers/gpu/drm/ttm/ttm_global.c
@@ -82,8 +82,8 @@ int ttm_global_item_ref(struct ttm_global_reference *ref)
if (unlikely(ret != 0))
goto out_err;
- ++item->refcount;
}
+ ++item->refcount;
ref->object = item->object;
object = item->object;
mutex_unlock(&item->mutex);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 0c6639ea03d..ba05275e510 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -30,6 +30,7 @@
#include <linux/major.h>
#include <linux/hid.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/hidraw.h>
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index ea955edde87..2a7a85a6dc3 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -915,7 +915,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp,
return ret;
}
-static struct file_operations watchdog_fops = {
+static const struct file_operations watchdog_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.open = watchdog_open,
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
index ecd739534f6..82b16808a27 100644
--- a/drivers/hwmon/lis3lv02d_spi.c
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -83,7 +83,8 @@ static int __devexit lis302dl_spi_remove(struct spi_device *spi)
struct lis3lv02d *lis3 = spi_get_drvdata(spi);
lis3lv02d_joystick_disable();
lis3lv02d_poweroff(lis3);
- return 0;
+
+ return lis3lv02d_remove_fs(&lis3_dev);
}
#ifdef CONFIG_PM
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index 6c9a04136e0..00d975eb5b8 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -20,11 +20,6 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(ltc4215);
-
/* Here are names of the chip's registers (a.k.a. commands) */
enum ltc4215_cmd {
LTC4215_CONTROL = 0x00, /* rw */
@@ -246,9 +241,13 @@ static const struct attribute_group ltc4215_group = {
static int ltc4215_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct i2c_adapter *adapter = client->adapter;
struct ltc4215_data *data;
int ret;
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
@@ -294,56 +293,20 @@ static int ltc4215_remove(struct i2c_client *client)
return 0;
}
-static int ltc4215_detect(struct i2c_client *client,
- int kind,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- if (kind < 0) { /* probed detection - check the chip type */
- s32 v; /* 8 bits from the chip, or -ERRNO */
-
- /*
- * Register 0x01 bit b7 is reserved, expect 0
- * Register 0x03 bit b6 and b7 are reserved, expect 0
- */
- v = i2c_smbus_read_byte_data(client, LTC4215_ALERT);
- if (v < 0 || (v & (1 << 7)) != 0)
- return -ENODEV;
-
- v = i2c_smbus_read_byte_data(client, LTC4215_FAULT);
- if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0)
- return -ENODEV;
- }
-
- strlcpy(info->type, "ltc4215", I2C_NAME_SIZE);
- dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n",
- kind < 0 ? "probed" : "forced",
- client->addr);
-
- return 0;
-}
-
static const struct i2c_device_id ltc4215_id[] = {
- { "ltc4215", ltc4215 },
+ { "ltc4215", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc4215_id);
/* This is the driver that will be inserted */
static struct i2c_driver ltc4215_driver = {
- .class = I2C_CLASS_HWMON,
.driver = {
.name = "ltc4215",
},
.probe = ltc4215_probe,
.remove = ltc4215_remove,
.id_table = ltc4215_id,
- .detect = ltc4215_detect,
- .address_data = &addr_data,
};
static int __init ltc4215_init(void)
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index e3896433361..65c232a9d0c 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -22,15 +22,6 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
-/* Valid addresses are 0x20 - 0x3f
- *
- * For now, we do not probe, since some of these addresses
- * are known to be unfriendly to probing */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(ltc4245);
-
/* Here are names of the chip's registers (a.k.a. commands) */
enum ltc4245_cmd {
LTC4245_STATUS = 0x00, /* readonly */
@@ -369,9 +360,13 @@ static const struct attribute_group ltc4245_group = {
static int ltc4245_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct i2c_adapter *adapter = client->adapter;
struct ltc4245_data *data;
int ret;
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
@@ -418,136 +413,20 @@ static int ltc4245_remove(struct i2c_client *client)
return 0;
}
-/* Check that some bits in a control register appear at all possible
- * locations without changing value
- *
- * @client: the i2c client to use
- * @reg: the register to read
- * @bits: the bits to check (0xff checks all bits,
- * 0x03 checks only the last two bits)
- *
- * return -ERRNO if the register read failed
- * return -ENODEV if the register value doesn't stay constant at all
- * possible addresses
- *
- * return 0 for success
- */
-static int ltc4245_check_control_reg(struct i2c_client *client, u8 reg, u8 bits)
-{
- int i;
- s32 v, voff1, voff2;
-
- /* Read register and check for error */
- v = i2c_smbus_read_byte_data(client, reg);
- if (v < 0)
- return v;
-
- v &= bits;
-
- for (i = 0x00; i < 0xff; i += 0x20) {
-
- voff1 = i2c_smbus_read_byte_data(client, reg + i);
- if (voff1 < 0)
- return voff1;
-
- voff2 = i2c_smbus_read_byte_data(client, reg + i + 0x08);
- if (voff2 < 0)
- return voff2;
-
- voff1 &= bits;
- voff2 &= bits;
-
- if (v != voff1 || v != voff2)
- return -ENODEV;
- }
-
- return 0;
-}
-
-static int ltc4245_detect(struct i2c_client *client,
- int kind,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- if (kind < 0) { /* probed detection - check the chip type */
- s32 v; /* 8 bits from the chip, or -ERRNO */
-
- /* Chip registers 0x00-0x07 are control registers
- * Chip registers 0x10-0x1f are data registers
- *
- * Address bits b7-b5 are ignored. This makes the chip "repeat"
- * in steps of 0x20. Any control registers should appear with
- * the same values across all duplicated addresses.
- *
- * Register 0x02 bit b2 is reserved, expect 0
- * Register 0x07 bits b7 to b4 are reserved, expect 0
- *
- * Registers 0x01, 0x02 are control registers and should not
- * change on their own.
- *
- * Register 0x06 bits b6 and b7 are control bits, and should
- * not change on their own.
- *
- * Register 0x07 bits b3 to b0 are control bits, and should
- * not change on their own.
- */
-
- /* read register 0x02 reserved bit, expect 0 */
- v = i2c_smbus_read_byte_data(client, LTC4245_CONTROL);
- if (v < 0 || (v & 0x04) != 0)
- return -ENODEV;
-
- /* read register 0x07 reserved bits, expect 0 */
- v = i2c_smbus_read_byte_data(client, LTC4245_ADCADR);
- if (v < 0 || (v & 0xf0) != 0)
- return -ENODEV;
-
- /* check that the alert register appears at all locations */
- if (ltc4245_check_control_reg(client, LTC4245_ALERT, 0xff))
- return -ENODEV;
-
- /* check that the control register appears at all locations */
- if (ltc4245_check_control_reg(client, LTC4245_CONTROL, 0xff))
- return -ENODEV;
-
- /* check that register 0x06 bits b6 and b7 stay constant */
- if (ltc4245_check_control_reg(client, LTC4245_GPIO, 0xc0))
- return -ENODEV;
-
- /* check that register 0x07 bits b3-b0 stay constant */
- if (ltc4245_check_control_reg(client, LTC4245_ADCADR, 0x0f))
- return -ENODEV;
- }
-
- strlcpy(info->type, "ltc4245", I2C_NAME_SIZE);
- dev_info(&adapter->dev, "ltc4245 %s at address 0x%02x\n",
- kind < 0 ? "probed" : "forced",
- client->addr);
-
- return 0;
-}
-
static const struct i2c_device_id ltc4245_id[] = {
- { "ltc4245", ltc4245 },
+ { "ltc4245", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc4245_id);
/* This is the driver that will be inserted */
static struct i2c_driver ltc4245_driver = {
- .class = I2C_CLASS_HWMON,
.driver = {
.name = "ltc4245",
},
.probe = ltc4245_probe,
.remove = ltc4245_remove,
.id_table = ltc4245_id,
- .detect = ltc4245_detect,
- .address_data = &addr_data,
};
static int __init ltc4245_init(void)
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index f7d6fe9c49b..8f0b90ef8c7 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -364,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
amd756_driver.name);
if (error)
- return error;
+ return -ENODEV;
if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index a7c59908c45..5b4ad86ca16 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -376,8 +376,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
smbus->size = pci_resource_len(dev, 0);
error = acpi_check_resource_conflict(&dev->resource[0]);
- if (error)
+ if (error) {
+ error = -ENODEV;
goto out_kfree;
+ }
if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
error = -EBUSY;
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 9d2c5adf5d4..55edcfe5b85 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -732,8 +732,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
}
err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
- if (err)
+ if (err) {
+ err = -ENODEV;
goto exit;
+ }
err = pci_request_region(dev, SMBBAR, i801_driver.name);
if (err) {
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
index 9f6b8e0f863..dba6eb053e2 100644
--- a/drivers/i2c/busses/i2c-isch.c
+++ b/drivers/i2c/busses/i2c-isch.c
@@ -281,7 +281,7 @@ static int __devinit sch_probe(struct pci_dev *dev,
return -ENODEV;
}
if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
- return -EBUSY;
+ return -ENODEV;
if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
sch_smba);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index a782c7a08f9..d26a972aaca 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -169,7 +169,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
}
if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
- return -EBUSY;
+ return -ENODEV;
if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
@@ -260,7 +260,7 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
- return -EBUSY;
+ return -ENODEV;
if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index 8295885b2fd..1649963b00d 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -280,7 +280,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]);
if (retval)
- return retval;
+ return -ENODEV;
/* Everything is happy, let's grab the memory and set things up. */
if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 54d810a4d00..e4b1543015a 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -365,7 +365,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
found:
error = acpi_check_region(vt596_smba, 8, vt596_driver.name);
if (error)
- return error;
+ return -ENODEV;
if (!request_region(vt596_smba, 8, vt596_driver.name)) {
dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 28d09a5d845..017c09540c2 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -273,14 +273,8 @@ static const struct ide_proc_devset ide_generic_settings[] = {
static void proc_ide_settings_warn(void)
{
- static int warned;
-
- if (warned)
- return;
-
- printk(KERN_WARNING "Warning: /proc/ide/hd?/settings interface is "
+ printk_once(KERN_WARNING "Warning: /proc/ide/hd?/settings interface is "
"obsolete, and will be removed soon!\n");
- warned = 1;
}
static int ide_settings_proc_show(struct seq_file *m, void *v)
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index afca22beaad..3b88eba04c9 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -2,7 +2,7 @@
* Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
* Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2009 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*
@@ -281,11 +281,13 @@ static void config_drive_art_rwp(ide_drive_t *drive)
pci_read_config_byte(dev, 0x4b, &reg4bh);
+ rw_prefetch = reg4bh & ~(0x11 << drive->dn);
+
if (drive->media == ide_disk)
- rw_prefetch = 0x11 << drive->dn;
+ rw_prefetch |= 0x11 << drive->dn;
- if ((reg4bh & (0x11 << drive->dn)) != rw_prefetch)
- pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
+ if (reg4bh != rw_prefetch)
+ pci_write_config_byte(dev, 0x4b, rw_prefetch);
}
static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 5be1bd4fc7e..bd07803e918 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -393,7 +393,7 @@ static int addr_resolve_local(struct sockaddr *src_in,
for_each_netdev(&init_net, dev)
if (ipv6_chk_addr(&init_net,
- &((struct sockaddr_in6 *) addr)->sin6_addr,
+ &((struct sockaddr_in6 *) dst_in)->sin6_addr,
dev, 1))
break;
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 55d093a36ae..625fec5a741 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -362,7 +362,9 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
* In either case, must tell the provider to reject.
*/
cm_id_priv->state = IW_CM_STATE_DESTROYING;
+ spin_unlock_irqrestore(&cm_id_priv->lock, flags);
cm_id->device->iwcm->reject(cm_id, NULL, 0);
+ spin_lock_irqsave(&cm_id_priv->lock, flags);
break;
case IW_CM_STATE_CONN_SENT:
case IW_CM_STATE_DESTROYING:
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 51bd9669cb1..f504c9b00c1 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -38,6 +38,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/poll.h>
+#include <linux/sched.h>
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/cdev.h>
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 8c46f225709..7de02969ed7 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -44,6 +44,7 @@
#include <linux/mutex.h>
#include <linux/kref.h>
#include <linux/compat.h>
+#include <linux/sched.h>
#include <linux/semaphore.h>
#include <asm/uaccess.h>
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index d3fff9e008a..aec0fbdfe7f 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -40,6 +40,7 @@
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/poll.h>
+#include <linux/sched.h>
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/cdev.h>
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 6895523779d..03cfaecc3bb 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -1199,11 +1199,14 @@ static int iwch_query_port(struct ib_device *ibdev,
props->state = IB_PORT_DOWN;
else {
inetdev = in_dev_get(netdev);
- if (inetdev->ifa_list)
- props->state = IB_PORT_ACTIVE;
- else
+ if (inetdev) {
+ if (inetdev->ifa_list)
+ props->state = IB_PORT_ACTIVE;
+ else
+ props->state = IB_PORT_INIT;
+ in_dev_put(inetdev);
+ } else
props->state = IB_PORT_INIT;
- in_dev_put(inetdev);
}
props->port_cap_flags =
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1148140d08a..dee6706038a 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -13,6 +13,7 @@
#define EVDEV_BUFFER_SIZE 64
#include <linux/poll.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/input/input.c b/drivers/input/input.c
index e828aab7dac..c6f88ebb40c 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -17,6 +17,7 @@
#include <linux/random.h>
#include <linux/major.h>
#include <linux/proc_fs.h>
+#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/poll.h>
#include <linux/device.h>
@@ -1273,6 +1274,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
} \
} while (0)
+#ifdef CONFIG_PM
static void input_dev_reset(struct input_dev *dev, bool activate)
{
if (!dev->event)
@@ -1287,7 +1289,6 @@ static void input_dev_reset(struct input_dev *dev, bool activate)
}
}
-#ifdef CONFIG_PM
static int input_dev_suspend(struct device *dev)
{
struct input_dev *input_dev = to_input_dev(dev);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 901b2525993..b1bd6dd3228 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -18,6 +18,7 @@
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/major.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 2388cf578a6..79e3edcced1 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -143,6 +143,7 @@ static const struct xpad_device {
{ 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
{ 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
@@ -209,6 +210,7 @@ static struct usb_device_id xpad_table [] = {
XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
+ XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */
{ }
};
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index c806fbf1e17..3b9f588fc74 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -106,8 +106,8 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
struct input_dev *input;
int err;
- if (!pdata || !pdata->steps) {
- dev_err(&pdev->dev, "invalid platform data\n");
+ if (!pdata) {
+ dev_err(&pdev->dev, "missing platform data\n");
return -ENOENT;
}
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index c4f42311fde..b064419b90a 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -230,7 +230,7 @@ out_err:
return err;
}
-static int bbc_remove(struct of_device *op)
+static int __devexit bbc_remove(struct of_device *op)
{
struct sparcspkr_state *state = dev_get_drvdata(&op->dev);
struct input_dev *input_dev = state->input_dev;
@@ -308,7 +308,7 @@ out_err:
return err;
}
-static int grover_remove(struct of_device *op)
+static int __devexit grover_remove(struct of_device *op)
{
struct sparcspkr_state *state = dev_get_drvdata(&op->dev);
struct grover_beep_info *info = &state->u.grover;
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index c5a49aba418..d3f57245420 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -30,6 +30,7 @@
* - first public version
*/
#include <linux/poll.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 11fd038a078..a932179c4c9 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -936,6 +936,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
},
{
.callback = dmi_matched,
+ .ident = "Medion MD 42200",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"),
+ },
+ .driver_data = keymap_fs_amilo_pro_v2000
+ },
+ {
+ .callback = dmi_matched,
.ident = "Medion MD 96500",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 966b8868f79..a13d80f7da1 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -13,6 +13,7 @@
#define MOUSEDEV_MINORS 32
#define MOUSEDEV_MIX 31
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/poll.h>
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index c4b3fbd1a80..aa533ceffe3 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -4,7 +4,7 @@
config SERIO
tristate "Serial I/O support" if EMBEDDED || !X86
default y
- ---help---
+ help
Say Yes here if you have any input device that uses serial I/O to
communicate with the system. This includes the
* standard AT keyboard and PS/2 mouse *
@@ -22,7 +22,7 @@ config SERIO_I8042
tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
default y
depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K && !BLACKFIN
- ---help---
+ help
i8042 is the chip over which the standard AT keyboard and PS/2
mouse are connected to the computer. If you use these devices,
you'll need to say Y here.
@@ -35,7 +35,7 @@ config SERIO_I8042
config SERIO_SERPORT
tristate "Serial port line discipline"
default y
- ---help---
+ help
Say Y here if you plan to use an input device (mouse, joystick,
tablet, 6dof) that communicates over the RS232 serial (COM) port.
@@ -49,7 +49,7 @@ config SERIO_SERPORT
config SERIO_CT82C710
tristate "ct82c710 Aux port controller"
depends on X86
- ---help---
+ help
Say Y here if you have a Texas Instruments TravelMate notebook
equipped with the ct82c710 chip and want to use a mouse connected
to the "QuickPort".
@@ -66,7 +66,7 @@ config SERIO_Q40KBD
config SERIO_PARKBD
tristate "Parallel port keyboard adapter"
depends on PARPORT
- ---help---
+ help
Say Y here if you built a simple parallel port adapter to attach
an additional AT keyboard, XT keyboard or PS/2 mouse.
@@ -124,7 +124,7 @@ config HP_SDC
tristate "HP System Device Controller i8042 Support"
depends on (GSC || HP300) && SERIO
default y
- ---help---
+ help
This option enables support for the "System Device
Controller", an i8042 carrying microcode to manage a
few miscellaneous devices on some Hewlett Packard systems.
@@ -168,6 +168,7 @@ config SERIO_MACEPS2
config SERIO_LIBPS2
tristate "PS/2 driver library" if EMBEDDED
+ depends on SERIO_I8042 || SERIO_I8042=n
help
Say Y here if you are using a driver for device connected
to a PS/2 port, such as PS/2 mouse or standard AT keyboard.
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index bc56e52b945..a31578170cc 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -609,6 +609,8 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
str = i8042_read_status();
if (str & I8042_STR_OBF) {
data = i8042_read_data();
+ dbg("%02x <- i8042 (aux_test_irq, %s)",
+ data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
if (i8042_irq_being_tested &&
data == 0xa5 && (str & I8042_STR_AUXDATA))
complete(&i8042_aux_irq_delivered);
@@ -750,6 +752,7 @@ static int __init i8042_check_aux(void)
* AUX IRQ was never delivered so we need to flush the controller to
* get rid of the byte we put there; otherwise keyboard may not work.
*/
+ dbg(" -- i8042 (aux irq test timeout)");
i8042_flush();
retval = -1;
}
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index f06332c9e21..c21e6d3a884 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -645,7 +645,7 @@ static int __devinit ad7879_probe(struct spi_device *spi)
kfree(ts);
}
- return 0;
+ return error;
}
static int __devexit ad7879_remove(struct spi_device *spi)
@@ -732,7 +732,7 @@ static int __devinit ad7879_probe(struct i2c_client *client,
kfree(ts);
}
- return 0;
+ return error;
}
static int __devexit ad7879_remove(struct i2c_client *client)
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 2d8352419c0..65bf91e16a4 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -603,7 +603,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
- if (info == 0) {
+ if ((info & 0xff00) == 0) {
mutex_lock(&cdev->ncci_list_mtx);
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
mutex_unlock(&cdev->ncci_list_mtx);
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 650120261ab..3e6d17f42a9 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -40,7 +40,7 @@ static int debugmode = 0;
MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
-module_param(debugmode, uint, 0);
+module_param(debugmode, uint, S_IRUGO|S_IWUSR);
/* -------- type definitions ----------------------------------------- */
@@ -671,8 +671,8 @@ static void n0(capidrv_contr * card, capidrv_ncci * ncci)
NULL, /* Useruserdata */ /* $$$$ */
NULL /* Facilitydataarray */
);
- send_message(card, &cmsg);
plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ);
+ send_message(card, &cmsg);
cmd.command = ISDN_STAT_BHUP;
cmd.driver = card->myid;
@@ -924,8 +924,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
*/
capi_cmsg_answer(cmsg);
cmsg->Reject = 1; /* ignore */
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+ send_message(card, cmsg);
printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n",
card->contrnr,
cmd.parm.setup.phone,
@@ -974,8 +974,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
case 2: /* Call will be rejected. */
capi_cmsg_answer(cmsg);
cmsg->Reject = 2; /* reject call, normal call clearing */
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+ send_message(card, cmsg);
break;
default:
@@ -983,8 +983,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
capi_cmsg_answer(cmsg);
cmsg->Reject = 8; /* reject call,
destination out of order */
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+ send_message(card, cmsg);
break;
}
return;
@@ -1020,8 +1020,8 @@ static void handle_plci(_cmsg * cmsg)
card->bchans[plcip->chan].disconnecting = 1;
plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND);
capi_cmsg_answer(cmsg);
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP);
+ send_message(card, cmsg);
break;
case CAPI_DISCONNECT_CONF: /* plci */
@@ -1078,8 +1078,8 @@ static void handle_plci(_cmsg * cmsg)
if (card->bchans[plcip->chan].incoming) {
capi_cmsg_answer(cmsg);
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
+ send_message(card, cmsg);
} else {
capidrv_ncci *nccip;
capi_cmsg_answer(cmsg);
@@ -1098,13 +1098,14 @@ static void handle_plci(_cmsg * cmsg)
NULL /* NCPI */
);
nccip->msgid = cmsg->Messagenumber;
+ plci_change_state(card, plcip,
+ EV_PLCI_CONNECT_ACTIVE_IND);
+ ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
send_message(card, cmsg);
cmd.command = ISDN_STAT_DCONN;
cmd.driver = card->myid;
cmd.arg = plcip->chan;
card->interface.statcallb(&cmd);
- plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
- ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
}
break;
@@ -1193,8 +1194,8 @@ static void handle_ncci(_cmsg * cmsg)
goto notfound;
capi_cmsg_answer(cmsg);
- send_message(card, cmsg);
ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND);
+ send_message(card, cmsg);
cmd.command = ISDN_STAT_BCONN;
cmd.driver = card->myid;
@@ -1222,8 +1223,8 @@ static void handle_ncci(_cmsg * cmsg)
0, /* Reject */
NULL /* NCPI */
);
- send_message(card, cmsg);
ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP);
+ send_message(card, cmsg);
break;
}
printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr);
@@ -1299,8 +1300,8 @@ static void handle_ncci(_cmsg * cmsg)
card->bchans[nccip->chan].disconnecting = 1;
ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND);
capi_cmsg_answer(cmsg);
- send_message(card, cmsg);
ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP);
+ send_message(card, cmsg);
break;
case CAPI_DISCONNECT_B3_CONF: /* ncci */
@@ -2014,8 +2015,8 @@ static void send_listen(capidrv_contr *card)
card->cipmask,
card->cipmask2,
NULL, NULL);
- send_message(card, &cmdcmsg);
listen_change_state(card, EV_LISTEN_REQ);
+ send_message(card, &cmdcmsg);
}
static void listentimerfunc(unsigned long x)
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 8b256a617c8..3697c409bec 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -16,6 +16,7 @@
#else
#include <linux/fs.h>
#endif
+#include <linux/sched.h>
#include <linux/isdnif.h>
#include <net/net_namespace.h>
#include "isdn_divert.h"
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index 234cc5d5331..44a58e6f8f6 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -334,7 +334,14 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
return startbytes - numbytes;
}
-/* process a block of data received from the device
+/**
+ * gigaset_m10x_input() - process a block of data received from the device
+ * @inbuf: received data and device descriptor structure.
+ *
+ * Called by hardware module {ser,usb}_gigaset with a block of received
+ * bytes. Separates the bytes received over the serial data channel into
+ * user data and command replies (locked/unlocked) according to the
+ * current state of the interface.
*/
void gigaset_m10x_input(struct inbuf_t *inbuf)
{
@@ -543,16 +550,17 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
return iraw_skb;
}
-/* gigaset_send_skb
- * called by common.c to queue an skb for sending
- * and start transmission if necessary
- * parameters:
- * B Channel control structure
- * skb
+/**
+ * gigaset_m10x_send_skb() - queue an skb for sending
+ * @bcs: B channel descriptor structure.
+ * @skb: data to send.
+ *
+ * Called by i4l.c to encode and queue an skb for sending, and start
+ * transmission if necessary.
+ *
* Return value:
- * number of bytes accepted for sending
- * (skb->len if ok, 0 if out of buffer space)
- * or error code (< 0, eg. -EINVAL)
+ * number of bytes accepted for sending (skb->len) if ok,
+ * error code < 0 (eg. -ENOMEM) on error
*/
int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
{
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 781c4041f7b..5ed1d99eb9f 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -134,6 +134,7 @@ struct bas_cardstate {
#define BS_ATRDPEND 0x040 /* urb_cmd_in in use */
#define BS_ATWRPEND 0x080 /* urb_cmd_out in use */
#define BS_SUSPEND 0x100 /* USB port suspended */
+#define BS_RESETTING 0x200 /* waiting for HD_RESET_INTERRUPT_PIPE_ACK */
static struct gigaset_driver *driver = NULL;
@@ -319,6 +320,21 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
return -EINVAL;
}
+/* set/clear bits in base connection state, return previous state
+ */
+static inline int update_basstate(struct bas_cardstate *ucs,
+ int set, int clear)
+{
+ unsigned long flags;
+ int state;
+
+ spin_lock_irqsave(&ucs->lock, flags);
+ state = ucs->basstate;
+ ucs->basstate = (state & ~clear) | set;
+ spin_unlock_irqrestore(&ucs->lock, flags);
+ return state;
+}
+
/* error_hangup
* hang up any existing connection because of an unrecoverable error
* This function may be called from any context and takes care of scheduling
@@ -350,12 +366,9 @@ static inline void error_hangup(struct bc_state *bcs)
*/
static inline void error_reset(struct cardstate *cs)
{
- /* close AT command channel to recover (ignore errors) */
- req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
-
- //FIXME try to recover without bothering the user
- dev_err(cs->dev,
- "unrecoverable error - please disconnect Gigaset base to reset\n");
+ /* reset interrupt pipe to recover (ignore errors) */
+ update_basstate(cs->hw.bas, BS_RESETTING, 0);
+ req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT);
}
/* check_pending
@@ -398,8 +411,13 @@ static void check_pending(struct bas_cardstate *ucs)
case HD_DEVICE_INIT_ACK: /* no reply expected */
ucs->pending = 0;
break;
- /* HD_READ_ATMESSAGE, HD_WRITE_ATMESSAGE, HD_RESET_INTERRUPTPIPE
- * are handled separately and should never end up here
+ case HD_RESET_INTERRUPT_PIPE:
+ if (!(ucs->basstate & BS_RESETTING))
+ ucs->pending = 0;
+ break;
+ /*
+ * HD_READ_ATMESSAGE and HD_WRITE_ATMESSAGE are handled separately
+ * and should never end up here
*/
default:
dev_warn(&ucs->interface->dev,
@@ -449,21 +467,6 @@ static void cmd_in_timeout(unsigned long data)
error_reset(cs);
}
-/* set/clear bits in base connection state, return previous state
- */
-inline static int update_basstate(struct bas_cardstate *ucs,
- int set, int clear)
-{
- unsigned long flags;
- int state;
-
- spin_lock_irqsave(&ucs->lock, flags);
- state = ucs->basstate;
- ucs->basstate = (state & ~clear) | set;
- spin_unlock_irqrestore(&ucs->lock, flags);
- return state;
-}
-
/* read_ctrl_callback
* USB completion handler for control pipe input
* called by the USB subsystem in interrupt context
@@ -762,7 +765,8 @@ static void read_int_callback(struct urb *urb)
break;
case HD_RESET_INTERRUPT_PIPE_ACK:
- gig_dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK");
+ update_basstate(ucs, 0, BS_RESETTING);
+ dev_notice(cs->dev, "interrupt pipe reset\n");
break;
case HD_SUSPEND_END:
@@ -1331,28 +1335,24 @@ static void read_iso_tasklet(unsigned long data)
rcvbuf = urb->transfer_buffer;
totleft = urb->actual_length;
for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) {
- if (unlikely(urb->iso_frame_desc[frame].status)) {
+ numbytes = urb->iso_frame_desc[frame].actual_length;
+ if (unlikely(urb->iso_frame_desc[frame].status))
dev_warn(cs->dev,
- "isochronous read: frame %d: %s\n",
- frame,
+ "isochronous read: frame %d[%d]: %s\n",
+ frame, numbytes,
get_usb_statmsg(
urb->iso_frame_desc[frame].status));
- break;
- }
- numbytes = urb->iso_frame_desc[frame].actual_length;
- if (unlikely(numbytes > BAS_MAXFRAME)) {
+ if (unlikely(numbytes > BAS_MAXFRAME))
dev_warn(cs->dev,
"isochronous read: frame %d: "
"numbytes (%d) > BAS_MAXFRAME\n",
frame, numbytes);
- break;
- }
if (unlikely(numbytes > totleft)) {
dev_warn(cs->dev,
"isochronous read: frame %d: "
"numbytes (%d) > totleft (%d)\n",
frame, numbytes, totleft);
- break;
+ numbytes = totleft;
}
offset = urb->iso_frame_desc[frame].offset;
if (unlikely(offset + numbytes > BAS_INBUFSIZE)) {
@@ -1361,7 +1361,7 @@ static void read_iso_tasklet(unsigned long data)
"offset (%d) + numbytes (%d) "
"> BAS_INBUFSIZE\n",
frame, offset, numbytes);
- break;
+ numbytes = BAS_INBUFSIZE - offset;
}
gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs);
totleft -= numbytes;
@@ -1433,6 +1433,7 @@ static void req_timeout(unsigned long data)
case HD_CLOSE_ATCHANNEL:
dev_err(bcs->cs->dev, "timeout closing AT channel\n");
+ error_reset(bcs->cs);
break;
case HD_CLOSE_B2CHANNEL:
@@ -1442,6 +1443,13 @@ static void req_timeout(unsigned long data)
error_reset(bcs->cs);
break;
+ case HD_RESET_INTERRUPT_PIPE:
+ /* error recovery escalation */
+ dev_err(bcs->cs->dev,
+ "reset interrupt pipe timeout, attempting USB reset\n");
+ usb_queue_reset_device(bcs->cs->hw.bas->interface);
+ break;
+
default:
dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n",
pending);
@@ -1934,6 +1942,15 @@ static int gigaset_write_cmd(struct cardstate *cs,
goto notqueued;
}
+ /* translate "+++" escape sequence sent as a single separate command
+ * into "close AT channel" command for error recovery
+ * The next command will reopen the AT channel automatically.
+ */
+ if (len == 3 && !memcmp(buf, "+++", 3)) {
+ rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
+ goto notqueued;
+ }
+
if (len > IF_WRITEBUF)
len = IF_WRITEBUF;
if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index e4141bf8b2f..33dcd8d72b7 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -22,6 +22,12 @@
#define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers"
#define DRIVER_DESC "Driver for Gigaset 307x"
+#ifdef CONFIG_GIGASET_DEBUG
+#define DRIVER_DESC_DEBUG " (debug build)"
+#else
+#define DRIVER_DESC_DEBUG ""
+#endif
+
/* Module parameters */
int gigaset_debuglevel = DEBUG_DEFAULT;
EXPORT_SYMBOL_GPL(gigaset_debuglevel);
@@ -32,6 +38,17 @@ MODULE_PARM_DESC(debug, "debug level");
#define VALID_MINOR 0x01
#define VALID_ID 0x02
+/**
+ * gigaset_dbg_buffer() - dump data in ASCII and hex for debugging
+ * @level: debugging level.
+ * @msg: message prefix.
+ * @len: number of bytes to dump.
+ * @buf: data to dump.
+ *
+ * If the current debugging level includes one of the bits set in @level,
+ * @len bytes starting at @buf are logged to dmesg at KERN_DEBUG prio,
+ * prefixed by the text @msg.
+ */
void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
size_t len, const unsigned char *buf)
{
@@ -274,6 +291,20 @@ static void clear_events(struct cardstate *cs)
spin_unlock_irqrestore(&cs->ev_lock, flags);
}
+/**
+ * gigaset_add_event() - add event to device event queue
+ * @cs: device descriptor structure.
+ * @at_state: connection state structure.
+ * @type: event type.
+ * @ptr: pointer parameter for event.
+ * @parameter: integer parameter for event.
+ * @arg: pointer parameter for event.
+ *
+ * Allocate an event queue entry from the device's event queue, and set it up
+ * with the parameters given.
+ *
+ * Return value: added event
+ */
struct event_t *gigaset_add_event(struct cardstate *cs,
struct at_state_t *at_state, int type,
void *ptr, int parameter, void *arg)
@@ -398,6 +429,15 @@ static void make_invalid(struct cardstate *cs, unsigned mask)
spin_unlock_irqrestore(&drv->lock, flags);
}
+/**
+ * gigaset_freecs() - free all associated ressources of a device
+ * @cs: device descriptor structure.
+ *
+ * Stops all tasklets and timers, unregisters the device from all
+ * subsystems it was registered to, deallocates the device structure
+ * @cs and all structures referenced from it.
+ * Operations on the device should be stopped before calling this.
+ */
void gigaset_freecs(struct cardstate *cs)
{
int i;
@@ -506,7 +546,12 @@ static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs,
inbuf->inputstate = inputstate;
}
-/* append received bytes to inbuf */
+/**
+ * gigaset_fill_inbuf() - append received data to input buffer
+ * @inbuf: buffer structure.
+ * @src: received data.
+ * @numbytes: number of bytes received.
+ */
int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
unsigned numbytes)
{
@@ -606,20 +651,22 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
return NULL;
}
-/* gigaset_initcs
+/**
+ * gigaset_initcs() - initialize device structure
+ * @drv: hardware driver the device belongs to
+ * @channels: number of B channels supported by device
+ * @onechannel: !=0 if B channel data and AT commands share one
+ * communication channel (M10x),
+ * ==0 if B channels have separate communication channels (base)
+ * @ignoreframes: number of frames to ignore after setting up B channel
+ * @cidmode: !=0: start in CallID mode
+ * @modulename: name of driver module for LL registration
+ *
* Allocate and initialize cardstate structure for Gigaset driver
* Calls hardware dependent gigaset_initcshw() function
* Calls B channel initialization function gigaset_initbcs() for each B channel
- * parameters:
- * drv hardware driver the device belongs to
- * channels number of B channels supported by device
- * onechannel !=0: B channel data and AT commands share one
- * communication channel
- * ==0: B channels have separate communication channels
- * ignoreframes number of frames to ignore after setting up B channel
- * cidmode !=0: start in CallID mode
- * modulename name of driver module (used for I4L registration)
- * return value:
+ *
+ * Return value:
* pointer to cardstate structure
*/
struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
@@ -837,6 +884,17 @@ static void cleanup_cs(struct cardstate *cs)
}
+/**
+ * gigaset_start() - start device operations
+ * @cs: device descriptor structure.
+ *
+ * Prepares the device for use by setting up communication parameters,
+ * scheduling an EV_START event to initiate device initialization, and
+ * waiting for completion of the initialization.
+ *
+ * Return value:
+ * 1 - success, 0 - error
+ */
int gigaset_start(struct cardstate *cs)
{
unsigned long flags;
@@ -879,9 +937,15 @@ error:
}
EXPORT_SYMBOL_GPL(gigaset_start);
-/* gigaset_shutdown
- * check if a device is associated to the cardstate structure and stop it
- * return value: 0 if ok, -1 if no device was associated
+/**
+ * gigaset_shutdown() - shut down device operations
+ * @cs: device descriptor structure.
+ *
+ * Deactivates the device by scheduling an EV_SHUTDOWN event and
+ * waiting for completion of the shutdown.
+ *
+ * Return value:
+ * 0 - success, -1 - error (no device associated)
*/
int gigaset_shutdown(struct cardstate *cs)
{
@@ -912,6 +976,13 @@ exit:
}
EXPORT_SYMBOL_GPL(gigaset_shutdown);
+/**
+ * gigaset_stop() - stop device operations
+ * @cs: device descriptor structure.
+ *
+ * Stops operations on the device by scheduling an EV_STOP event and
+ * waiting for completion of the shutdown.
+ */
void gigaset_stop(struct cardstate *cs)
{
mutex_lock(&cs->mutex);
@@ -1020,6 +1091,14 @@ struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty)
return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start);
}
+/**
+ * gigaset_freedriver() - free all associated ressources of a driver
+ * @drv: driver descriptor structure.
+ *
+ * Unregisters the driver from the system and deallocates the driver
+ * structure @drv and all structures referenced from it.
+ * All devices should be shut down before calling this.
+ */
void gigaset_freedriver(struct gigaset_driver *drv)
{
unsigned long flags;
@@ -1035,14 +1114,16 @@ void gigaset_freedriver(struct gigaset_driver *drv)
}
EXPORT_SYMBOL_GPL(gigaset_freedriver);
-/* gigaset_initdriver
+/**
+ * gigaset_initdriver() - initialize driver structure
+ * @minor: First minor number
+ * @minors: Number of minors this driver can handle
+ * @procname: Name of the driver
+ * @devname: Name of the device files (prefix without minor number)
+ *
* Allocate and initialize gigaset_driver structure. Initialize interface.
- * parameters:
- * minor First minor number
- * minors Number of minors this driver can handle
- * procname Name of the driver
- * devname Name of the device files (prefix without minor number)
- * return value:
+ *
+ * Return value:
* Pointer to the gigaset_driver structure on success, NULL on failure.
*/
struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
@@ -1095,6 +1176,13 @@ error:
}
EXPORT_SYMBOL_GPL(gigaset_initdriver);
+/**
+ * gigaset_blockdriver() - block driver
+ * @drv: driver descriptor structure.
+ *
+ * Prevents the driver from attaching new devices, in preparation for
+ * deregistration.
+ */
void gigaset_blockdriver(struct gigaset_driver *drv)
{
drv->blocked = 1;
@@ -1110,7 +1198,7 @@ static int __init gigaset_init_module(void)
if (gigaset_debuglevel == 1)
gigaset_debuglevel = DEBUG_DEFAULT;
- pr_info(DRIVER_DESC "\n");
+ pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
return 0;
}
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 2d91049571a..cc768caa38f 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -207,7 +207,6 @@ struct reply_t gigaset_tab_nocid[] =
/* leave dle mode */
{RSP_INIT, 0, 0,SEQ_DLE0, 201, 5, {0}, "^SDLE=0\r"},
{RSP_OK, 201,201, -1, 202,-1},
- //{RSP_ZDLE, 202,202, 0, 202, 0, {ACT_ERROR}},//DELETE
{RSP_ZDLE, 202,202, 0, 0, 0, {ACT_DLE0}},
{RSP_NODEV, 200,249, -1, 0, 0, {ACT_FAKEDLE0}},
{RSP_ERROR, 200,249, -1, 0, 0, {ACT_FAILDLE0}},
@@ -265,6 +264,7 @@ struct reply_t gigaset_tab_nocid[] =
{EV_SHUTDOWN, -1, -1, -1, -1,-1, {ACT_SHUTDOWN}}, //FIXME
/* misc. */
+ {RSP_ERROR, -1, -1, -1, -1, -1, {ACT_ERROR} },
{RSP_EMPTY, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
{RSP_ZCFGT, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
{RSP_ZCFG, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
@@ -328,10 +328,9 @@ struct reply_t gigaset_tab_cid[] =
{RSP_INIT, -1, -1,SEQ_HUP, 401, 5, {0}, "+VLS=0\r"}, /* hang up */ //-1,-1?
{RSP_OK, 401,401, -1, 402, 5},
{RSP_ZVLS, 402,402, 0, 403, 5},
- {RSP_ZSAU, 403,403,ZSAU_DISCONNECT_REQ, -1,-1, {ACT_DEBUG}}, /* if not remote hup */
- //{RSP_ZSAU, 403,403,ZSAU_NULL, 401, 0, {ACT_ERROR}}, //DELETE//FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
- {RSP_ZSAU, 403,403,ZSAU_NULL, 0, 0, {ACT_DISCONNECT}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
- {RSP_NODEV, 401,403, -1, 0, 0, {ACT_FAKEHUP}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
+ {RSP_ZSAU, 403, 403, ZSAU_DISCONNECT_REQ, -1, -1, {ACT_DEBUG} },
+ {RSP_ZSAU, 403, 403, ZSAU_NULL, 0, 0, {ACT_DISCONNECT} },
+ {RSP_NODEV, 401, 403, -1, 0, 0, {ACT_FAKEHUP} },
{RSP_ERROR, 401,401, -1, 0, 0, {ACT_ABORTHUP}},
{EV_TIMEOUT, 401,403, -1, 0, 0, {ACT_ABORTHUP}},
@@ -474,8 +473,13 @@ static int cid_of_response(char *s)
//FIXME is ;<digit>+ at end of non-CID response really impossible?
}
-/* This function will be called via task queue from the callback handler.
- * We received a modem response and have to handle it..
+/**
+ * gigaset_handle_modem_response() - process received modem response
+ * @cs: device descriptor structure.
+ *
+ * Called by asyncdata/isocdata if a block of data received from the
+ * device must be processed as a modem command response. The data is
+ * already in the cs structure.
*/
void gigaset_handle_modem_response(struct cardstate *cs)
{
@@ -707,6 +711,11 @@ static void disconnect(struct at_state_t **at_state_p)
if (bcs) {
/* B channel assigned: invoke hardware specific handler */
cs->ops->close_bchannel(bcs);
+ /* notify LL */
+ if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
+ bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
+ gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
+ }
} else {
/* no B channel assigned: just deallocate */
spin_lock_irqsave(&cs->lock, flags);
@@ -1429,11 +1438,12 @@ static void do_action(int action, struct cardstate *cs,
cs->gotfwver = -1;
dev_err(cs->dev, "could not read firmware version.\n");
break;
-#ifdef CONFIG_GIGASET_DEBUG
case ACT_ERROR:
- *p_genresp = 1;
- *p_resp_code = RSP_ERROR;
+ gig_dbg(DEBUG_ANY, "%s: ERROR response in ConState %d",
+ __func__, at_state->ConState);
+ cs->cur_at_seq = SEQ_NONE;
break;
+#ifdef CONFIG_GIGASET_DEBUG
case ACT_TEST:
{
static int count = 3; //2; //1;
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 9b22f9cf2f3..654489d836c 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -51,6 +51,12 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
return -ENODEV;
}
bcs = &cs->bcs[channel];
+
+ /* can only handle linear sk_buffs */
+ if (skb_linearize(skb) < 0) {
+ dev_err(cs->dev, "%s: skb_linearize failed\n", __func__);
+ return -ENOMEM;
+ }
len = skb->len;
gig_dbg(DEBUG_LLDATA,
@@ -79,6 +85,14 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
return cs->ops->send_skb(bcs, skb);
}
+/**
+ * gigaset_skb_sent() - acknowledge sending an skb
+ * @bcs: B channel descriptor structure.
+ * @skb: sent data.
+ *
+ * Called by hardware module {bas,ser,usb}_gigaset when the data in a
+ * skb has been successfully sent, for signalling completion to the LL.
+ */
void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
{
unsigned len;
@@ -455,6 +469,15 @@ int gigaset_isdn_setup_accept(struct at_state_t *at_state)
return 0;
}
+/**
+ * gigaset_isdn_icall() - signal incoming call
+ * @at_state: connection state structure.
+ *
+ * Called by main module to notify the LL that an incoming call has been
+ * received. @at_state contains the parameters of the call.
+ *
+ * Return value: call disposition (ICALL_*)
+ */
int gigaset_isdn_icall(struct at_state_t *at_state)
{
struct cardstate *cs = at_state->cs;
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index f33ac27de64..6a8e1384e7b 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -616,6 +616,15 @@ void gigaset_if_free(struct cardstate *cs)
tty_unregister_device(drv->tty, cs->minor_index);
}
+/**
+ * gigaset_if_receive() - pass a received block of data to the tty device
+ * @cs: device descriptor structure.
+ * @buffer: received data.
+ * @len: number of bytes received.
+ *
+ * Called by asyncdata/isocdata if a block of data received from the
+ * device must be sent to userspace through the ttyG* device.
+ */
void gigaset_if_receive(struct cardstate *cs,
unsigned char *buffer, size_t len)
{
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index bed38fcc432..9f3ef7b4248 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -429,7 +429,7 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb,
return -EAGAIN;
}
- dump_bytes(DEBUG_STREAM, "snd data", in, count);
+ dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
/* bitstuff and checksum input data */
fcs = PPP_INITFCS;
@@ -448,7 +448,6 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb,
/* put closing flag and repeat byte for flag idle */
isowbuf_putflag(iwb);
end = isowbuf_donewrite(iwb);
- dump_bytes(DEBUG_STREAM_DUMP, "isowbuf", iwb->data, end + 1);
return end;
}
@@ -482,6 +481,8 @@ static inline int trans_buildframe(struct isowbuf_t *iwb,
}
gig_dbg(DEBUG_STREAM, "put %d bytes", count);
+ dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
+
write = iwb->write;
do {
c = bitrev8(*in++);
@@ -583,7 +584,7 @@ static inline void hdlc_done(struct bc_state *bcs)
procskb->tail -= 2;
gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)",
__func__, procskb->len);
- dump_bytes(DEBUG_STREAM,
+ dump_bytes(DEBUG_STREAM_DUMP,
"rcv data", procskb->data, procskb->len);
bcs->hw.bas->goodbytes += procskb->len;
gigaset_rcv_skb(procskb, bcs->cs, bcs);
@@ -878,6 +879,8 @@ static inline void trans_receive(unsigned char *src, unsigned count,
dobytes--;
}
if (dobytes == 0) {
+ dump_bytes(DEBUG_STREAM_DUMP,
+ "rcv data", skb->data, skb->len);
gigaset_rcv_skb(skb, bcs->cs, bcs);
bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN);
if (!skb) {
@@ -973,16 +976,17 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
/* == data output ========================================================== */
-/* gigaset_send_skb
- * called by common.c to queue an skb for sending
- * and start transmission if necessary
- * parameters:
- * B Channel control structure
- * skb
- * return value:
- * number of bytes accepted for sending
- * (skb->len if ok, 0 if out of buffer space)
- * or error code (< 0, eg. -EINVAL)
+/**
+ * gigaset_isoc_send_skb() - queue an skb for sending
+ * @bcs: B channel descriptor structure.
+ * @skb: data to send.
+ *
+ * Called by i4l.c to queue an skb for sending, and start transmission if
+ * necessary.
+ *
+ * Return value:
+ * number of bytes accepted for sending (skb->len) if ok,
+ * error code < 0 (eg. -ENODEV) on error
*/
int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
{
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index c36f5213745..feb0fa45b66 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -415,7 +415,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
static int data_sock_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int len)
+ char __user *optval, unsigned int len)
{
struct sock *sk = sock->sk;
int err = 0, opt = 0;
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 708a8017c21..adc561eb59d 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -19,9 +19,6 @@
#include <linux/workqueue.h>
#include <linux/leds-pca9532.h>
-static const unsigned short normal_i2c[] = { /*0x60,*/ I2C_CLIENT_END};
-I2C_CLIENT_INSMOD_1(pca9532);
-
#define PCA9532_REG_PSC(i) (0x2+(i)*2)
#define PCA9532_REG_PWM(i) (0x3+(i)*2)
#define PCA9532_REG_LS0 0x6
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index b4d3f7ca554..bd1632388e4 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -508,7 +508,7 @@ static int close(struct inode *inode, struct file *file)
* uses: reading and writing a character device called /dev/lguest. All the
* work happens in the read(), write() and close() routines:
*/
-static struct file_operations lguest_fops = {
+static const struct file_operations lguest_fops = {
.owner = THIS_MODULE,
.release = close,
.write = write,
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index fde377c60cc..556f0feaa4d 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -124,6 +124,8 @@ read_reg(struct thermostat* th, int reg)
return data;
}
+static struct i2c_driver thermostat_driver;
+
static int
attach_thermostat(struct i2c_adapter *adapter)
{
@@ -148,7 +150,7 @@ attach_thermostat(struct i2c_adapter *adapter)
* Let i2c-core delete that device on driver removal.
* This is safe because i2c-core holds the core_lock mutex for us.
*/
- list_add_tail(&client->detected, &client->driver->clients);
+ list_add_tail(&client->detected, &thermostat_driver.clients);
return 0;
}
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index a028598af2d..ea32c7e5a9a 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -286,6 +286,8 @@ struct fcu_fan_table fcu_fans[] = {
},
};
+static struct i2c_driver therm_pm72_driver;
+
/*
* Utility function to create an i2c_client structure and
* attach it to one of u3 adapters
@@ -318,7 +320,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
* Let i2c-core delete that device on driver removal.
* This is safe because i2c-core holds the core_lock mutex for us.
*/
- list_add_tail(&clt->detected, &clt->driver->clients);
+ list_add_tail(&clt->detected, &therm_pm72_driver.clients);
return clt;
}
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 529886c7a82..ed6426a1077 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -115,6 +115,8 @@ static int wf_lm75_probe(struct i2c_client *client,
return rc;
}
+static struct i2c_driver wf_lm75_driver;
+
static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
u8 addr, int ds1775,
const char *loc)
@@ -157,7 +159,7 @@ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
* Let i2c-core delete that device on driver removal.
* This is safe because i2c-core holds the core_lock mutex for us.
*/
- list_add_tail(&client->detected, &client->driver->clients);
+ list_add_tail(&client->detected, &wf_lm75_driver.clients);
return client;
fail:
return NULL;
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index e2a55ecda2b..a67b349319e 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -88,6 +88,8 @@ static int wf_max6690_probe(struct i2c_client *client,
return rc;
}
+static struct i2c_driver wf_max6690_driver;
+
static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
u8 addr, const char *loc)
{
@@ -119,7 +121,7 @@ static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
* Let i2c-core delete that device on driver removal.
* This is safe because i2c-core holds the core_lock mutex for us.
*/
- list_add_tail(&client->detected, &client->driver->clients);
+ list_add_tail(&client->detected, &wf_max6690_driver.clients);
return client;
fail:
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 5da729e58f9..e20330a2895 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -194,6 +194,8 @@ static struct wf_sensor_ops wf_sat_ops = {
.owner = THIS_MODULE,
};
+static struct i2c_driver wf_sat_driver;
+
static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
{
struct i2c_board_info info;
@@ -222,7 +224,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
* Let i2c-core delete that device on driver removal.
* This is safe because i2c-core holds the core_lock mutex for us.
*/
- list_add_tail(&client->detected, &client->driver->clients);
+ list_add_tail(&client->detected, &wf_sat_driver.clients);
}
static int wf_sat_probe(struct i2c_client *client,
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
index ba0edad2d04..54abf9e303b 100644
--- a/drivers/md/dm-log-userspace-transfer.c
+++ b/drivers/md/dm-log-userspace-transfer.c
@@ -129,11 +129,13 @@ static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr)
* This is the connector callback that delivers data
* that was sent from userspace.
*/
-static void cn_ulog_callback(void *data)
+static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
- struct cn_msg *msg = (struct cn_msg *)data;
struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
+ if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
+ return;
+
spin_lock(&receiving_list_lock);
if (msg->len == 0)
fill_pkg(msg, NULL);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 376f1ab48a2..23e76fe0d35 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -130,7 +130,7 @@ struct mapped_device {
/*
* A list of ios that arrived while we were suspended.
*/
- atomic_t pending[2];
+ atomic_t pending;
wait_queue_head_t wait;
struct work_struct work;
struct bio_list deferred;
@@ -453,14 +453,13 @@ static void start_io_acct(struct dm_io *io)
{
struct mapped_device *md = io->md;
int cpu;
- int rw = bio_data_dir(io->bio);
io->start_time = jiffies;
cpu = part_stat_lock();
part_round_stats(cpu, &dm_disk(md)->part0);
part_stat_unlock();
- dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]);
+ dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending);
}
static void end_io_acct(struct dm_io *io)
@@ -480,9 +479,8 @@ static void end_io_acct(struct dm_io *io)
* After this is decremented the bio must not be touched if it is
* a barrier.
*/
- dm_disk(md)->part0.in_flight[rw] = pending =
- atomic_dec_return(&md->pending[rw]);
- pending += atomic_read(&md->pending[rw^0x1]);
+ dm_disk(md)->part0.in_flight = pending =
+ atomic_dec_return(&md->pending);
/* nudge anyone waiting on suspend queue */
if (!pending)
@@ -1787,8 +1785,7 @@ static struct mapped_device *alloc_dev(int minor)
if (!md->disk)
goto bad_disk;
- atomic_set(&md->pending[0], 0);
- atomic_set(&md->pending[1], 0);
+ atomic_set(&md->pending, 0);
init_waitqueue_head(&md->wait);
INIT_WORK(&md->work, dm_wq_work);
init_waitqueue_head(&md->eventq);
@@ -2091,8 +2088,7 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
break;
}
spin_unlock_irqrestore(q->queue_lock, flags);
- } else if (!atomic_read(&md->pending[0]) &&
- !atomic_read(&md->pending[1]))
+ } else if (!atomic_read(&md->pending))
break;
if (interruptible == TASK_INTERRUPTIBLE &&
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 3750ff48cba..c37790ad92d 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -20,6 +20,7 @@
*
*/
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -1203,7 +1204,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
return mask;
}
-static struct file_operations dvb_dvr_fops = {
+static const struct file_operations dvb_dvr_fops = {
.owner = THIS_MODULE,
.read = dvb_dvr_read,
.write = dvb_dvr_write,
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index eef6d361662..91c537bca8a 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -21,6 +21,7 @@
*
*/
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c
index eeb80d0ea3f..853e04b7cb3 100644
--- a/drivers/media/dvb/firewire/firedtv-ci.c
+++ b/drivers/media/dvb/firewire/firedtv-ci.c
@@ -215,7 +215,7 @@ static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait)
return POLLIN;
}
-static struct file_operations fdtv_ca_fops = {
+static const struct file_operations fdtv_ca_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 8b1440136c4..482d0f3be5f 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -38,6 +38,7 @@
#include <linux/videodev2.h> /* V4L2 API defs */
#include <linux/param.h>
#include <linux/pnp.h>
+#include <linux/sched.h>
#include <linux/io.h> /* outb, outb_p */
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 43ab0adf3b6..2377313c041 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -31,6 +31,7 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/ctype.h>
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 5447da16a17..61348102827 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -57,8 +57,6 @@
* The AB3100 is usually assigned address 0x48 (7-bit)
* The chip is defined in the platform i2c_board_data section.
*/
-static unsigned short normal_i2c[] = { 0x48, I2C_CLIENT_END };
-I2C_CLIENT_INSMOD_1(ab3100);
u8 ab3100_get_chip_type(struct ab3100 *ab3100)
{
@@ -966,7 +964,7 @@ static int __exit ab3100_remove(struct i2c_client *client)
}
static const struct i2c_device_id ab3100_id[] = {
- { "ab3100", ab3100 },
+ { "ab3100", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ab3100_id);
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c
index 2afc08006e6..fa294b6d600 100644
--- a/drivers/mfd/ucb1400_core.c
+++ b/drivers/mfd/ucb1400_core.c
@@ -21,6 +21,7 @@
*/
#include <linux/module.h>
+#include <linux/sched.h>
#include <linux/ucb1400.h>
unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c
index 3c0c58eed34..5a6b2bce8ad 100644
--- a/drivers/misc/eeprom/max6875.c
+++ b/drivers/misc/eeprom/max6875.c
@@ -33,12 +33,6 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
-/* Do not scan - the MAX6875 access method will write to some EEPROM chips */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(max6875);
-
/* The MAX6875 can only read/write 16 bytes at a time */
#define SLICE_SIZE 16
#define SLICE_BITS 4
@@ -146,31 +140,21 @@ static struct bin_attribute user_eeprom_attr = {
.read = max6875_read,
};
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int max6875_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info)
+static int max6875_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = client->adapter;
+ struct max6875_data *data;
+ int err;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
| I2C_FUNC_SMBUS_READ_BYTE))
return -ENODEV;
- /* Only check even addresses */
+ /* Only bind to even addresses */
if (client->addr & 1)
return -ENODEV;
- strlcpy(info->type, "max6875", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int max6875_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct max6875_data *data;
- int err;
-
if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
return -ENOMEM;
@@ -222,9 +206,6 @@ static struct i2c_driver max6875_driver = {
.probe = max6875_probe,
.remove = max6875_remove,
.id_table = max6875_id,
-
- .detect = max6875_detect,
- .address_data = &addr_data,
};
static int __init max6875_init(void)
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index fa57b67593a..90a95ce8dc3 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -271,7 +271,7 @@ static unsigned int phantom_poll(struct file *file, poll_table *wait)
return mask;
}
-static struct file_operations phantom_file_ops = {
+static const struct file_operations phantom_file_ops = {
.open = phantom_open,
.release = phantom_release,
.unlocked_ioctl = phantom_ioctl,
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 300e7ba391a..41c8fe2a928 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -53,7 +53,6 @@ struct gru_stats_s gru_stats;
/* Guaranteed user available resources on each node */
static int max_user_cbrs, max_user_dsr_bytes;
-static struct file_operations gru_fops;
static struct miscdevice gru_miscdev;
@@ -426,7 +425,7 @@ static void __exit gru_exit(void)
gru_proc_exit();
}
-static struct file_operations gru_fops = {
+static const struct file_operations gru_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = gru_file_unlocked_ioctl,
.mmap = gru_file_mmap,
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 610dbd1fcc8..96d10f40fb2 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -240,7 +240,7 @@ static int mmc_ext_csd_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations mmc_dbg_ext_csd_fops = {
+static const struct file_operations mmc_dbg_ext_csd_fops = {
.open = mmc_ext_csd_open,
.read = mmc_ext_csd_read,
.release = mmc_ext_csd_release,
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 6636354b48c..f85dcd53650 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -29,6 +29,8 @@ static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
unsigned i, nr_strings;
char **buffer, *string;
+ /* Find all null-terminated (including zero length) strings in
+ the TPLLV1_INFO field. Trailing garbage is ignored. */
buf += 2;
size -= 2;
@@ -39,11 +41,8 @@ static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
if (buf[i] == 0)
nr_strings++;
}
-
- if (nr_strings < 4) {
- printk(KERN_WARNING "SDIO: ignoring broken CISTPL_VERS_1\n");
+ if (nr_strings == 0)
return 0;
- }
size = i;
@@ -98,6 +97,22 @@ static const unsigned char speed_val[16] =
static const unsigned int speed_unit[8] =
{ 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
+/* FUNCE tuples with these types get passed to SDIO drivers */
+static const unsigned char funce_type_whitelist[] = {
+ 4 /* CISTPL_FUNCE_LAN_NODE_ID used in Broadcom cards */
+};
+
+static int cistpl_funce_whitelisted(unsigned char type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(funce_type_whitelist); i++) {
+ if (funce_type_whitelist[i] == type)
+ return 1;
+ }
+ return 0;
+}
+
static int cistpl_funce_common(struct mmc_card *card,
const unsigned char *buf, unsigned size)
{
@@ -120,6 +135,10 @@ static int cistpl_funce_func(struct sdio_func *func,
unsigned vsn;
unsigned min_size;
+ /* let SDIO drivers take care of whitelisted FUNCE tuples */
+ if (cistpl_funce_whitelisted(buf[0]))
+ return -EILSEQ;
+
vsn = func->card->cccr.sdio_vsn;
min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
@@ -154,13 +173,12 @@ static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
else
ret = cistpl_funce_common(card, buf, size);
- if (ret) {
+ if (ret && ret != -EILSEQ) {
printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
"type %u\n", mmc_hostname(card->host), size, buf[0]);
- return ret;
}
- return 0;
+ return ret;
}
typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
@@ -253,21 +271,12 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++)
if (cis_tpl_list[i].code == tpl_code)
break;
- if (i >= ARRAY_SIZE(cis_tpl_list)) {
- /* this tuple is unknown to the core */
- this->next = NULL;
- this->code = tpl_code;
- this->size = tpl_link;
- *prev = this;
- prev = &this->next;
- printk(KERN_DEBUG
- "%s: queuing CIS tuple 0x%02x length %u\n",
- mmc_hostname(card->host), tpl_code, tpl_link);
- } else {
+ if (i < ARRAY_SIZE(cis_tpl_list)) {
const struct cis_tpl *tpl = cis_tpl_list + i;
if (tpl_link < tpl->min_size) {
printk(KERN_ERR
- "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n",
+ "%s: bad CIS tuple 0x%02x"
+ " (length = %u, expected >= %u)\n",
mmc_hostname(card->host),
tpl_code, tpl_link, tpl->min_size);
ret = -EINVAL;
@@ -275,7 +284,30 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
ret = tpl->parse(card, func,
this->data, tpl_link);
}
- kfree(this);
+ /*
+ * We don't need the tuple anymore if it was
+ * successfully parsed by the SDIO core or if it is
+ * not going to be parsed by SDIO drivers.
+ */
+ if (!ret || ret != -EILSEQ)
+ kfree(this);
+ } else {
+ /* unknown tuple */
+ ret = -EILSEQ;
+ }
+
+ if (ret == -EILSEQ) {
+ /* this tuple is unknown to the core or whitelisted */
+ this->next = NULL;
+ this->code = tpl_code;
+ this->size = tpl_link;
+ *prev = this;
+ prev = &this->next;
+ printk(KERN_DEBUG
+ "%s: queuing CIS tuple 0x%02x length %u\n",
+ mmc_hostname(card->host), tpl_code, tpl_link);
+ /* keep on analyzing tuples */
+ ret = 0;
}
ptr += tpl_link;
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 7cb057f3f88..432ae8358c8 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -276,6 +276,47 @@ config MMC_S3C
If unsure, say N.
+config MMC_S3C_HW_SDIO_IRQ
+ bool "Hardware support for SDIO IRQ"
+ depends on MMC_S3C
+ help
+ Enable the hardware support for SDIO interrupts instead of using
+ the generic polling code.
+
+choice
+ prompt "Samsung S3C SD/MMC transfer code"
+ depends on MMC_S3C
+
+config MMC_S3C_PIO
+ bool "Use PIO transfers only"
+ help
+ Use PIO to transfer data between memory and the hardware.
+
+ PIO is slower than DMA as it requires CPU instructions to
+ move the data. This has been the traditional default for
+ the S3C MCI driver.
+
+config MMC_S3C_DMA
+ bool "Use DMA transfers only (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ Use DMA to transfer data between memory and the hardare.
+
+ Currently, the DMA support in this driver seems to not be
+ working properly and needs to be debugged before this
+ option is useful.
+
+config MMC_S3C_PIODMA
+ bool "Support for both PIO and DMA (EXPERIMENTAL)"
+ help
+ Compile both the PIO and DMA transfer routines into the
+ driver and let the platform select at run-time which one
+ is best.
+
+ See notes for the DMA option.
+
+endchoice
+
config MMC_SDRICOH_CS
tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)"
depends on EXPERIMENTAL && PCI && PCMCIA
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 3d1e5329da1..705a5894a6b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -678,7 +678,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
writel(0, host->base + MMCIMASK1);
writel(0xfff, host->base + MMCICLEAR);
-#ifdef CONFIG_GPIOLIB
if (gpio_is_valid(plat->gpio_cd)) {
ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
if (ret == 0)
@@ -697,7 +696,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
else if (ret != -ENOSYS)
goto err_gpio_wp;
}
-#endif
ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
if (ret)
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 8c08cd7efa7..99b74a35102 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -17,6 +17,8 @@
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
#include <linux/cpufreq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/io.h>
@@ -58,8 +60,6 @@ static const int dbgmap_debug = dbg_err | dbg_debug;
dev_dbg(&host->pdev->dev, args); \
} while (0)
-#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
-
static struct s3c2410_dma_client s3cmci_dma_client = {
.name = "s3c-mci",
};
@@ -164,6 +164,40 @@ static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { }
#endif /* CONFIG_MMC_DEBUG */
+/**
+ * s3cmci_host_usedma - return whether the host is using dma or pio
+ * @host: The host state
+ *
+ * Return true if the host is using DMA to transfer data, else false
+ * to use PIO mode. Will return static data depending on the driver
+ * configuration.
+ */
+static inline bool s3cmci_host_usedma(struct s3cmci_host *host)
+{
+#ifdef CONFIG_MMC_S3C_PIO
+ return false;
+#elif defined(CONFIG_MMC_S3C_DMA)
+ return true;
+#else
+ return host->dodma;
+#endif
+}
+
+/**
+ * s3cmci_host_canpio - return true if host has pio code available
+ *
+ * Return true if the driver has been compiled with the PIO support code
+ * available.
+ */
+static inline bool s3cmci_host_canpio(void)
+{
+#ifdef CONFIG_MMC_S3C_PIO
+ return true;
+#else
+ return false;
+#endif
+}
+
static inline u32 enable_imask(struct s3cmci_host *host, u32 imask)
{
u32 newmask;
@@ -190,7 +224,33 @@ static inline u32 disable_imask(struct s3cmci_host *host, u32 imask)
static inline void clear_imask(struct s3cmci_host *host)
{
- writel(0, host->base + host->sdiimsk);
+ u32 mask = readl(host->base + host->sdiimsk);
+
+ /* preserve the SDIO IRQ mask state */
+ mask &= S3C2410_SDIIMSK_SDIOIRQ;
+ writel(mask, host->base + host->sdiimsk);
+}
+
+/**
+ * s3cmci_check_sdio_irq - test whether the SDIO IRQ is being signalled
+ * @host: The host to check.
+ *
+ * Test to see if the SDIO interrupt is being signalled in case the
+ * controller has failed to re-detect a card interrupt. Read GPE8 and
+ * see if it is low and if so, signal a SDIO interrupt.
+ *
+ * This is currently called if a request is finished (we assume that the
+ * bus is now idle) and when the SDIO IRQ is enabled in case the IRQ is
+ * already being indicated.
+*/
+static void s3cmci_check_sdio_irq(struct s3cmci_host *host)
+{
+ if (host->sdio_irqen) {
+ if (gpio_get_value(S3C2410_GPE(8)) == 0) {
+ printk(KERN_DEBUG "%s: signalling irq\n", __func__);
+ mmc_signal_sdio_irq(host->mmc);
+ }
+ }
}
static inline int get_data_buffer(struct s3cmci_host *host,
@@ -238,6 +298,64 @@ static inline u32 fifo_free(struct s3cmci_host *host)
return 63 - fifostat;
}
+/**
+ * s3cmci_enable_irq - enable IRQ, after having disabled it.
+ * @host: The device state.
+ * @more: True if more IRQs are expected from transfer.
+ *
+ * Enable the main IRQ if needed after it has been disabled.
+ *
+ * The IRQ can be one of the following states:
+ * - disabled during IDLE
+ * - disabled whilst processing data
+ * - enabled during transfer
+ * - enabled whilst awaiting SDIO interrupt detection
+ */
+static void s3cmci_enable_irq(struct s3cmci_host *host, bool more)
+{
+ unsigned long flags;
+ bool enable = false;
+
+ local_irq_save(flags);
+
+ host->irq_enabled = more;
+ host->irq_disabled = false;
+
+ enable = more | host->sdio_irqen;
+
+ if (host->irq_state != enable) {
+ host->irq_state = enable;
+
+ if (enable)
+ enable_irq(host->irq);
+ else
+ disable_irq(host->irq);
+ }
+
+ local_irq_restore(flags);
+}
+
+/**
+ *
+ */
+static void s3cmci_disable_irq(struct s3cmci_host *host, bool transfer)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ //printk(KERN_DEBUG "%s: transfer %d\n", __func__, transfer);
+
+ host->irq_disabled = transfer;
+
+ if (transfer && host->irq_state) {
+ host->irq_state = false;
+ disable_irq(host->irq);
+ }
+
+ local_irq_restore(flags);
+}
+
static void do_pio_read(struct s3cmci_host *host)
{
int res;
@@ -374,8 +492,7 @@ static void pio_tasklet(unsigned long data)
{
struct s3cmci_host *host = (struct s3cmci_host *) data;
-
- disable_irq(host->irq);
+ s3cmci_disable_irq(host, true);
if (host->pio_active == XFER_WRITE)
do_pio_write(host);
@@ -395,9 +512,10 @@ static void pio_tasklet(unsigned long data)
host->mrq->data->error = -EINVAL;
}
+ s3cmci_enable_irq(host, false);
finalize_request(host);
} else
- enable_irq(host->irq);
+ s3cmci_enable_irq(host, true);
}
/*
@@ -432,17 +550,27 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
struct s3cmci_host *host = dev_id;
struct mmc_command *cmd;
u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;
- u32 mci_cclear, mci_dclear;
+ u32 mci_cclear = 0, mci_dclear;
unsigned long iflags;
+ mci_dsta = readl(host->base + S3C2410_SDIDSTA);
+ mci_imsk = readl(host->base + host->sdiimsk);
+
+ if (mci_dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {
+ if (mci_imsk & S3C2410_SDIIMSK_SDIOIRQ) {
+ mci_dclear = S3C2410_SDIDSTA_SDIOIRQDETECT;
+ writel(mci_dclear, host->base + S3C2410_SDIDSTA);
+
+ mmc_signal_sdio_irq(host->mmc);
+ return IRQ_HANDLED;
+ }
+ }
+
spin_lock_irqsave(&host->complete_lock, iflags);
mci_csta = readl(host->base + S3C2410_SDICMDSTAT);
- mci_dsta = readl(host->base + S3C2410_SDIDSTA);
mci_dcnt = readl(host->base + S3C2410_SDIDCNT);
mci_fsta = readl(host->base + S3C2410_SDIFSTA);
- mci_imsk = readl(host->base + host->sdiimsk);
- mci_cclear = 0;
mci_dclear = 0;
if ((host->complete_what == COMPLETION_NONE) ||
@@ -466,7 +594,7 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
goto irq_out;
}
- if (!host->dodma) {
+ if (!s3cmci_host_usedma(host)) {
if ((host->pio_active == XFER_WRITE) &&
(mci_fsta & S3C2410_SDIFSTA_TFDET)) {
@@ -673,6 +801,7 @@ static void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch,
dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n",
size, mci_dsta, mci_dcnt);
+ host->dma_complete = 1;
host->complete_what = COMPLETION_FINALIZE;
out:
@@ -683,9 +812,9 @@ out:
fail_request:
host->mrq->data->error = -EINVAL;
host->complete_what = COMPLETION_FINALIZE;
- writel(0, host->base + host->sdiimsk);
- goto out;
+ clear_imask(host);
+ goto out;
}
static void finalize_request(struct s3cmci_host *host)
@@ -702,8 +831,9 @@ static void finalize_request(struct s3cmci_host *host)
if (cmd->data && (cmd->error == 0) &&
(cmd->data->error == 0)) {
- if (host->dodma && (!host->dma_complete)) {
- dbg(host, dbg_dma, "DMA Missing!\n");
+ if (s3cmci_host_usedma(host) && (!host->dma_complete)) {
+ dbg(host, dbg_dma, "DMA Missing (%d)!\n",
+ host->dma_complete);
return;
}
}
@@ -728,7 +858,7 @@ static void finalize_request(struct s3cmci_host *host)
writel(0, host->base + S3C2410_SDICMDARG);
writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
writel(0, host->base + S3C2410_SDICMDCON);
- writel(0, host->base + host->sdiimsk);
+ clear_imask(host);
if (cmd->data && cmd->error)
cmd->data->error = cmd->error;
@@ -754,7 +884,7 @@ static void finalize_request(struct s3cmci_host *host)
/* If we had an error while transfering data we flush the
* DMA channel and the fifo to clear out any garbage. */
if (mrq->data->error != 0) {
- if (host->dodma)
+ if (s3cmci_host_usedma(host))
s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
if (host->is2440) {
@@ -776,6 +906,8 @@ static void finalize_request(struct s3cmci_host *host)
request_done:
host->complete_what = COMPLETION_NONE;
host->mrq = NULL;
+
+ s3cmci_check_sdio_irq(host);
mmc_request_done(host->mmc, mrq);
}
@@ -872,7 +1004,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;
- if (host->dodma)
+ if (s3cmci_host_usedma(host))
dcon |= S3C2410_SDIDCON_DMAEN;
if (host->bus_width == MMC_BUS_WIDTH_4)
@@ -950,7 +1082,7 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
{
int dma_len, i;
- int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
+ int rw = data->flags & MMC_DATA_WRITE;
BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
@@ -958,7 +1090,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
- (rw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
if (dma_len == 0)
return -ENOMEM;
@@ -969,11 +1101,11 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
for (i = 0; i < dma_len; i++) {
int res;
- dbg(host, dbg_dma, "enqueue %i:%u@%u\n", i,
- sg_dma_address(&data->sg[i]),
- sg_dma_len(&data->sg[i]));
+ dbg(host, dbg_dma, "enqueue %i: %08x@%u\n", i,
+ sg_dma_address(&data->sg[i]),
+ sg_dma_len(&data->sg[i]));
- res = s3c2410_dma_enqueue(host->dma, (void *) host,
+ res = s3c2410_dma_enqueue(host->dma, host,
sg_dma_address(&data->sg[i]),
sg_dma_len(&data->sg[i]));
@@ -1018,7 +1150,7 @@ static void s3cmci_send_request(struct mmc_host *mmc)
return;
}
- if (host->dodma)
+ if (s3cmci_host_usedma(host))
res = s3cmci_prepare_dma(host, cmd->data);
else
res = s3cmci_prepare_pio(host, cmd->data);
@@ -1037,7 +1169,7 @@ static void s3cmci_send_request(struct mmc_host *mmc)
s3cmci_send_command(host, cmd);
/* Enable Interrupt */
- enable_irq(host->irq);
+ s3cmci_enable_irq(host, true);
}
static int s3cmci_card_present(struct mmc_host *mmc)
@@ -1049,7 +1181,7 @@ static int s3cmci_card_present(struct mmc_host *mmc)
if (pdata->gpio_detect == 0)
return -ENOSYS;
- ret = s3c2410_gpio_getpin(pdata->gpio_detect) ? 0 : 1;
+ ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
return ret ^ pdata->detect_invert;
}
@@ -1104,12 +1236,12 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
switch (ios->power_mode) {
case MMC_POWER_ON:
case MMC_POWER_UP:
- s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK);
- s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD);
- s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0);
- s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1);
- s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
- s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(5), S3C2410_GPE5_SDCLK);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(6), S3C2410_GPE6_SDCMD);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(7), S3C2410_GPE7_SDDAT0);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(9), S3C2410_GPE9_SDDAT2);
+ s3c2410_gpio_cfgpin(S3C2410_GPE(10), S3C2410_GPE10_SDDAT3);
if (host->pdata->set_power)
host->pdata->set_power(ios->power_mode, ios->vdd);
@@ -1121,8 +1253,7 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_OFF:
default:
- s3c2410_gpio_setpin(S3C2410_GPE5, 0);
- s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPIO_OUTPUT);
+ gpio_direction_output(S3C2410_GPE(5), 0);
if (host->is2440)
mci_con |= S3C2440_SDICON_SDRESET;
@@ -1168,7 +1299,7 @@ static int s3cmci_get_ro(struct mmc_host *mmc)
struct s3c24xx_mci_pdata *pdata = host->pdata;
int ret;
- if (pdata->gpio_wprotect == 0)
+ if (pdata->no_wprotect)
return 0;
ret = s3c2410_gpio_getpin(pdata->gpio_wprotect);
@@ -1179,11 +1310,52 @@ static int s3cmci_get_ro(struct mmc_host *mmc)
return ret;
}
+static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct s3cmci_host *host = mmc_priv(mmc);
+ unsigned long flags;
+ u32 con;
+
+ local_irq_save(flags);
+
+ con = readl(host->base + S3C2410_SDICON);
+ host->sdio_irqen = enable;
+
+ if (enable == host->sdio_irqen)
+ goto same_state;
+
+ if (enable) {
+ con |= S3C2410_SDICON_SDIOIRQ;
+ enable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
+
+ if (!host->irq_state && !host->irq_disabled) {
+ host->irq_state = true;
+ enable_irq(host->irq);
+ }
+ } else {
+ disable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
+ con &= ~S3C2410_SDICON_SDIOIRQ;
+
+ if (!host->irq_enabled && host->irq_state) {
+ disable_irq_nosync(host->irq);
+ host->irq_state = false;
+ }
+ }
+
+ writel(con, host->base + S3C2410_SDICON);
+
+ same_state:
+ local_irq_restore(flags);
+
+ s3cmci_check_sdio_irq(host);
+}
+
static struct mmc_host_ops s3cmci_ops = {
.request = s3cmci_request,
.set_ios = s3cmci_set_ios,
.get_ro = s3cmci_get_ro,
.get_cd = s3cmci_card_present,
+ .enable_sdio_irq = s3cmci_enable_sdio_irq,
};
static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
@@ -1246,11 +1418,140 @@ static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
}
#endif
-static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
+
+#ifdef CONFIG_DEBUG_FS
+
+static int s3cmci_state_show(struct seq_file *seq, void *v)
+{
+ struct s3cmci_host *host = seq->private;
+
+ seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
+ seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
+ seq_printf(seq, "Prescale = %d\n", host->prescaler);
+ seq_printf(seq, "is2440 = %d\n", host->is2440);
+ seq_printf(seq, "IRQ = %d\n", host->irq);
+ seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
+ seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
+ seq_printf(seq, "IRQ state = %d\n", host->irq_state);
+ seq_printf(seq, "CD IRQ = %d\n", host->irq_cd);
+ seq_printf(seq, "Do DMA = %d\n", s3cmci_host_usedma(host));
+ seq_printf(seq, "SDIIMSK at %d\n", host->sdiimsk);
+ seq_printf(seq, "SDIDATA at %d\n", host->sdidata);
+
+ return 0;
+}
+
+static int s3cmci_state_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, s3cmci_state_show, inode->i_private);
+}
+
+static const struct file_operations s3cmci_fops_state = {
+ .owner = THIS_MODULE,
+ .open = s3cmci_state_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+#define DBG_REG(_r) { .addr = S3C2410_SDI##_r, .name = #_r }
+
+struct s3cmci_reg {
+ unsigned short addr;
+ unsigned char *name;
+} debug_regs[] = {
+ DBG_REG(CON),
+ DBG_REG(PRE),
+ DBG_REG(CMDARG),
+ DBG_REG(CMDCON),
+ DBG_REG(CMDSTAT),
+ DBG_REG(RSP0),
+ DBG_REG(RSP1),
+ DBG_REG(RSP2),
+ DBG_REG(RSP3),
+ DBG_REG(TIMER),
+ DBG_REG(BSIZE),
+ DBG_REG(DCON),
+ DBG_REG(DCNT),
+ DBG_REG(DSTA),
+ DBG_REG(FSTA),
+ {}
+};
+
+static int s3cmci_regs_show(struct seq_file *seq, void *v)
+{
+ struct s3cmci_host *host = seq->private;
+ struct s3cmci_reg *rptr = debug_regs;
+
+ for (; rptr->name; rptr++)
+ seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name,
+ readl(host->base + rptr->addr));
+
+ seq_printf(seq, "SDIIMSK\t=0x%08x\n", readl(host->base + host->sdiimsk));
+
+ return 0;
+}
+
+static int s3cmci_regs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, s3cmci_regs_show, inode->i_private);
+}
+
+static const struct file_operations s3cmci_fops_regs = {
+ .owner = THIS_MODULE,
+ .open = s3cmci_regs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void s3cmci_debugfs_attach(struct s3cmci_host *host)
+{
+ struct device *dev = &host->pdev->dev;
+
+ host->debug_root = debugfs_create_dir(dev_name(dev), NULL);
+ if (IS_ERR(host->debug_root)) {
+ dev_err(dev, "failed to create debugfs root\n");
+ return;
+ }
+
+ host->debug_state = debugfs_create_file("state", 0444,
+ host->debug_root, host,
+ &s3cmci_fops_state);
+
+ if (IS_ERR(host->debug_state))
+ dev_err(dev, "failed to create debug state file\n");
+
+ host->debug_regs = debugfs_create_file("regs", 0444,
+ host->debug_root, host,
+ &s3cmci_fops_regs);
+
+ if (IS_ERR(host->debug_regs))
+ dev_err(dev, "failed to create debug regs file\n");
+}
+
+static void s3cmci_debugfs_remove(struct s3cmci_host *host)
+{
+ debugfs_remove(host->debug_regs);
+ debugfs_remove(host->debug_state);
+ debugfs_remove(host->debug_root);
+}
+
+#else
+static inline void s3cmci_debugfs_attach(struct s3cmci_host *host) { }
+static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __devinit s3cmci_probe(struct platform_device *pdev)
{
struct s3cmci_host *host;
struct mmc_host *mmc;
int ret;
+ int is2440;
+ int i;
+
+ is2440 = platform_get_device_id(pdev)->driver_data;
mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
if (!mmc) {
@@ -1258,6 +1559,18 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
goto probe_out;
}
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
+ ret = gpio_request(i, dev_name(&pdev->dev));
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get gpio %d\n", i);
+
+ for (i--; i >= S3C2410_GPE(5); i--)
+ gpio_free(i);
+
+ goto probe_free_host;
+ }
+ }
+
host = mmc_priv(mmc);
host->mmc = mmc;
host->pdev = pdev;
@@ -1282,11 +1595,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
host->clk_div = 2;
}
- host->dodma = 0;
host->complete_what = COMPLETION_NONE;
host->pio_active = XFER_NONE;
- host->dma = S3CMCI_DMA;
+#ifdef CONFIG_MMC_S3C_PIODMA
+ host->dodma = host->pdata->dma;
+#endif
host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!host->mem) {
@@ -1294,19 +1608,19 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
"failed to get io memory region resouce.\n");
ret = -ENOENT;
- goto probe_free_host;
+ goto probe_free_gpio;
}
host->mem = request_mem_region(host->mem->start,
- RESSIZE(host->mem), pdev->name);
+ resource_size(host->mem), pdev->name);
if (!host->mem) {
dev_err(&pdev->dev, "failed to request io memory region.\n");
ret = -ENOENT;
- goto probe_free_host;
+ goto probe_free_gpio;
}
- host->base = ioremap(host->mem->start, RESSIZE(host->mem));
+ host->base = ioremap(host->mem->start, resource_size(host->mem));
if (!host->base) {
dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
ret = -EINVAL;
@@ -1331,31 +1645,60 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
* ensure we don't lock the system with un-serviceable requests. */
disable_irq(host->irq);
+ host->irq_state = false;
- host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
-
- if (host->irq_cd >= 0) {
- if (request_irq(host->irq_cd, s3cmci_irq_cd,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- DRIVER_NAME, host)) {
- dev_err(&pdev->dev, "can't get card detect irq.\n");
- ret = -ENOENT;
+ if (!host->pdata->no_detect) {
+ ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get detect gpio\n");
goto probe_free_irq;
}
- } else {
- dev_warn(&pdev->dev, "host detect has no irq available\n");
- s3c2410_gpio_cfgpin(host->pdata->gpio_detect,
- S3C2410_GPIO_INPUT);
+
+ host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
+
+ if (host->irq_cd >= 0) {
+ if (request_irq(host->irq_cd, s3cmci_irq_cd,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ DRIVER_NAME, host)) {
+ dev_err(&pdev->dev,
+ "can't get card detect irq.\n");
+ ret = -ENOENT;
+ goto probe_free_gpio_cd;
+ }
+ } else {
+ dev_warn(&pdev->dev,
+ "host detect has no irq available\n");
+ gpio_direction_input(host->pdata->gpio_detect);
+ }
+ } else
+ host->irq_cd = -1;
+
+ if (!host->pdata->no_wprotect) {
+ ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to get writeprotect\n");
+ goto probe_free_irq_cd;
+ }
+
+ gpio_direction_input(host->pdata->gpio_wprotect);
}
- if (host->pdata->gpio_wprotect)
- s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect,
- S3C2410_GPIO_INPUT);
+ /* depending on the dma state, get a dma channel to use. */
- if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) {
- dev_err(&pdev->dev, "unable to get DMA channel.\n");
- ret = -EBUSY;
- goto probe_free_irq_cd;
+ if (s3cmci_host_usedma(host)) {
+ host->dma = s3c2410_dma_request(DMACH_SDI, &s3cmci_dma_client,
+ host);
+ if (host->dma < 0) {
+ dev_err(&pdev->dev, "cannot get DMA channel.\n");
+ if (!s3cmci_host_canpio()) {
+ ret = -EBUSY;
+ goto probe_free_gpio_wp;
+ } else {
+ dev_warn(&pdev->dev, "falling back to PIO.\n");
+ host->dodma = 0;
+ }
+ }
}
host->clk = clk_get(&pdev->dev, "sdi");
@@ -1363,7 +1706,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
dev_err(&pdev->dev, "failed to find clock source.\n");
ret = PTR_ERR(host->clk);
host->clk = NULL;
- goto probe_free_host;
+ goto probe_free_dma;
}
ret = clk_enable(host->clk);
@@ -1376,7 +1719,11 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
mmc->ops = &s3cmci_ops;
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+#ifdef CONFIG_MMC_S3C_HW_SDIO_IRQ
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+#else
mmc->caps = MMC_CAP_4_BIT_DATA;
+#endif
mmc->f_min = host->clk_rate / (host->clk_div * 256);
mmc->f_max = host->clk_rate / host->clk_div;
@@ -1408,8 +1755,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
goto free_cpufreq;
}
+ s3cmci_debugfs_attach(host);
+
platform_set_drvdata(pdev, mmc);
- dev_info(&pdev->dev, "initialisation done.\n");
+ dev_info(&pdev->dev, "%s - using %s, %s SDIO IRQ\n", mmc_hostname(mmc),
+ s3cmci_host_usedma(host) ? "dma" : "pio",
+ mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw");
return 0;
@@ -1422,6 +1773,18 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
clk_free:
clk_put(host->clk);
+ probe_free_dma:
+ if (s3cmci_host_usedma(host))
+ s3c2410_dma_free(host->dma, &s3cmci_dma_client);
+
+ probe_free_gpio_wp:
+ if (!host->pdata->no_wprotect)
+ gpio_free(host->pdata->gpio_wprotect);
+
+ probe_free_gpio_cd:
+ if (!host->pdata->no_detect)
+ gpio_free(host->pdata->gpio_detect);
+
probe_free_irq_cd:
if (host->irq_cd >= 0)
free_irq(host->irq_cd, host);
@@ -1433,10 +1796,15 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
iounmap(host->base);
probe_free_mem_region:
- release_mem_region(host->mem->start, RESSIZE(host->mem));
+ release_mem_region(host->mem->start, resource_size(host->mem));
+
+ probe_free_gpio:
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
probe_free_host:
mmc_free_host(mmc);
+
probe_out:
return ret;
}
@@ -1449,6 +1817,7 @@ static void s3cmci_shutdown(struct platform_device *pdev)
if (host->irq_cd >= 0)
free_irq(host->irq_cd, host);
+ s3cmci_debugfs_remove(host);
s3cmci_cpufreq_deregister(host);
mmc_remove_host(mmc);
clk_disable(host->clk);
@@ -1458,104 +1827,102 @@ static int __devexit s3cmci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct s3cmci_host *host = mmc_priv(mmc);
+ struct s3c24xx_mci_pdata *pd = host->pdata;
+ int i;
s3cmci_shutdown(pdev);
clk_put(host->clk);
tasklet_disable(&host->pio_tasklet);
- s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client);
+
+ if (s3cmci_host_usedma(host))
+ s3c2410_dma_free(host->dma, &s3cmci_dma_client);
free_irq(host->irq, host);
+ if (!pd->no_wprotect)
+ gpio_free(pd->gpio_wprotect);
+
+ if (!pd->no_detect)
+ gpio_free(pd->gpio_detect);
+
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
+
+
iounmap(host->base);
- release_mem_region(host->mem->start, RESSIZE(host->mem));
+ release_mem_region(host->mem->start, resource_size(host->mem));
mmc_free_host(mmc);
return 0;
}
-static int __devinit s3cmci_2410_probe(struct platform_device *dev)
-{
- return s3cmci_probe(dev, 0);
-}
+static struct platform_device_id s3cmci_driver_ids[] = {
+ {
+ .name = "s3c2410-sdi",
+ .driver_data = 0,
+ }, {
+ .name = "s3c2412-sdi",
+ .driver_data = 1,
+ }, {
+ .name = "s3c2440-sdi",
+ .driver_data = 1,
+ },
+ { }
+};
-static int __devinit s3cmci_2412_probe(struct platform_device *dev)
-{
- return s3cmci_probe(dev, 1);
-}
+MODULE_DEVICE_TABLE(platform, s3cmci_driver_ids);
-static int __devinit s3cmci_2440_probe(struct platform_device *dev)
-{
- return s3cmci_probe(dev, 1);
-}
#ifdef CONFIG_PM
-static int s3cmci_suspend(struct platform_device *dev, pm_message_t state)
+static int s3cmci_suspend(struct device *dev)
{
- struct mmc_host *mmc = platform_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev));
+ struct pm_message event = { PM_EVENT_SUSPEND };
- return mmc_suspend_host(mmc, state);
+ return mmc_suspend_host(mmc, event);
}
-static int s3cmci_resume(struct platform_device *dev)
+static int s3cmci_resume(struct device *dev)
{
- struct mmc_host *mmc = platform_get_drvdata(dev);
+ struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev));
return mmc_resume_host(mmc);
}
-#else /* CONFIG_PM */
-#define s3cmci_suspend NULL
-#define s3cmci_resume NULL
-#endif /* CONFIG_PM */
-
-
-static struct platform_driver s3cmci_2410_driver = {
- .driver.name = "s3c2410-sdi",
- .driver.owner = THIS_MODULE,
- .probe = s3cmci_2410_probe,
- .remove = __devexit_p(s3cmci_remove),
- .shutdown = s3cmci_shutdown,
+static struct dev_pm_ops s3cmci_pm = {
.suspend = s3cmci_suspend,
.resume = s3cmci_resume,
};
-static struct platform_driver s3cmci_2412_driver = {
- .driver.name = "s3c2412-sdi",
- .driver.owner = THIS_MODULE,
- .probe = s3cmci_2412_probe,
- .remove = __devexit_p(s3cmci_remove),
- .shutdown = s3cmci_shutdown,
- .suspend = s3cmci_suspend,
- .resume = s3cmci_resume,
-};
+#define s3cmci_pm_ops &s3cmci_pm
+#else /* CONFIG_PM */
+#define s3cmci_pm_ops NULL
+#endif /* CONFIG_PM */
-static struct platform_driver s3cmci_2440_driver = {
- .driver.name = "s3c2440-sdi",
- .driver.owner = THIS_MODULE,
- .probe = s3cmci_2440_probe,
+
+static struct platform_driver s3cmci_driver = {
+ .driver = {
+ .name = "s3c-sdi",
+ .owner = THIS_MODULE,
+ .pm = s3cmci_pm_ops,
+ },
+ .id_table = s3cmci_driver_ids,
+ .probe = s3cmci_probe,
.remove = __devexit_p(s3cmci_remove),
.shutdown = s3cmci_shutdown,
- .suspend = s3cmci_suspend,
- .resume = s3cmci_resume,
};
-
static int __init s3cmci_init(void)
{
- platform_driver_register(&s3cmci_2410_driver);
- platform_driver_register(&s3cmci_2412_driver);
- platform_driver_register(&s3cmci_2440_driver);
- return 0;
+ return platform_driver_register(&s3cmci_driver);
}
static void __exit s3cmci_exit(void)
{
- platform_driver_unregister(&s3cmci_2410_driver);
- platform_driver_unregister(&s3cmci_2412_driver);
- platform_driver_unregister(&s3cmci_2440_driver);
+ platform_driver_unregister(&s3cmci_driver);
}
module_init(s3cmci_init);
@@ -1564,6 +1931,3 @@ module_exit(s3cmci_exit);
MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>");
-MODULE_ALIAS("platform:s3c2410-sdi");
-MODULE_ALIAS("platform:s3c2412-sdi");
-MODULE_ALIAS("platform:s3c2440-sdi");
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
index ca1ba3d58cf..c76b53dbeb6 100644
--- a/drivers/mmc/host/s3cmci.h
+++ b/drivers/mmc/host/s3cmci.h
@@ -8,9 +8,6 @@
* published by the Free Software Foundation.
*/
-/* FIXME: DMA Resource management ?! */
-#define S3CMCI_DMA 0
-
enum s3cmci_waitfor {
COMPLETION_NONE,
COMPLETION_FINALIZE,
@@ -42,6 +39,11 @@ struct s3cmci_host {
int dodma;
int dmatogo;
+ bool irq_disabled;
+ bool irq_enabled;
+ bool irq_state;
+ int sdio_irqen;
+
struct mmc_request *mrq;
int cmd_is_stop;
@@ -68,6 +70,12 @@ struct s3cmci_host {
unsigned int ccnt, dcnt;
struct tasklet_struct pio_tasklet;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debug_root;
+ struct dentry *debug_state;
+ struct dentry *debug_regs;
+#endif
+
#ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition;
#endif
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 0acbf4f5be5..8ca17a3e96e 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -32,14 +32,6 @@ struct mtd_blkcore_priv {
spinlock_t queue_lock;
};
-static int blktrans_discard_request(struct request_queue *q,
- struct request *req)
-{
- req->cmd_type = REQ_TYPE_LINUX_BLOCK;
- req->cmd[0] = REQ_LB_OP_DISCARD;
- return 0;
-}
-
static int do_blktrans_request(struct mtd_blktrans_ops *tr,
struct mtd_blktrans_dev *dev,
struct request *req)
@@ -52,10 +44,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
buf = req->buffer;
- if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
- req->cmd[0] == REQ_LB_OP_DISCARD)
- return tr->discard(dev, block, nsect);
-
if (!blk_fs_request(req))
return -EIO;
@@ -63,6 +51,9 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
get_capacity(req->rq_disk))
return -EIO;
+ if (blk_discard_rq(req))
+ return tr->discard(dev, block, nsect);
+
switch(rq_data_dir(req)) {
case READ:
for (; nsect > 0; nsect--, block++, buf += tr->blksize)
@@ -380,8 +371,8 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
tr->blkcore_priv->rq->queuedata = tr;
blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize);
if (tr->discard)
- blk_queue_set_discard(tr->blkcore_priv->rq,
- blktrans_discard_request);
+ queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
+ tr->blkcore_priv->rq);
tr->blkshift = ffs(tr->blksize) - 1;
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index b9eeadf01b7..975e25b19eb 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -805,52 +805,54 @@ static void poll_vortex(struct net_device *dev)
#ifdef CONFIG_PM
-static int vortex_suspend(struct pci_dev *pdev, pm_message_t state)
+static int vortex_suspend(struct device *dev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *ndev = pci_get_drvdata(pdev);
+
+ if (!ndev || !netif_running(ndev))
+ return 0;
+
+ netif_device_detach(ndev);
+ vortex_down(ndev, 1);
- if (dev && netdev_priv(dev)) {
- if (netif_running(dev)) {
- netif_device_detach(dev);
- vortex_down(dev, 1);
- disable_irq(dev->irq);
- }
- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- }
return 0;
}
-static int vortex_resume(struct pci_dev *pdev)
+static int vortex_resume(struct device *dev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct vortex_private *vp = netdev_priv(dev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *ndev = pci_get_drvdata(pdev);
int err;
- if (dev && vp) {
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- err = pci_enable_device(pdev);
- if (err) {
- pr_warning("%s: Could not enable device\n",
- dev->name);
- return err;
- }
- pci_set_master(pdev);
- if (netif_running(dev)) {
- err = vortex_up(dev);
- if (err)
- return err;
- enable_irq(dev->irq);
- netif_device_attach(dev);
- }
- }
+ if (!ndev || !netif_running(ndev))
+ return 0;
+
+ err = vortex_up(ndev);
+ if (err)
+ return err;
+
+ netif_device_attach(ndev);
+
return 0;
}
-#endif /* CONFIG_PM */
+static struct dev_pm_ops vortex_pm_ops = {
+ .suspend = vortex_suspend,
+ .resume = vortex_resume,
+ .freeze = vortex_suspend,
+ .thaw = vortex_resume,
+ .poweroff = vortex_suspend,
+ .restore = vortex_resume,
+};
+
+#define VORTEX_PM_OPS (&vortex_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define VORTEX_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
#ifdef CONFIG_EISA
static struct eisa_device_id vortex_eisa_ids[] = {
@@ -3199,10 +3201,7 @@ static struct pci_driver vortex_driver = {
.probe = vortex_init_one,
.remove = __devexit_p(vortex_remove_one),
.id_table = vortex_pci_tbl,
-#ifdef CONFIG_PM
- .suspend = vortex_suspend,
- .resume = vortex_resume,
-#endif
+ .driver.pm = VORTEX_PM_OPS,
};
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2bea67c134f..712776089b4 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1738,6 +1738,13 @@ config KS8851
help
SPI driver for Micrel KS8851 SPI attached network chip.
+config KS8851_MLL
+ tristate "Micrel KS8851 MLL"
+ depends on HAS_IOMEM
+ help
+ This platform driver is for Micrel KS8851 Address/data bus
+ multiplexed network chip.
+
config VIA_RHINE
tristate "VIA Rhine support"
depends on NET_PCI && PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index ae8cd30f13d..d866b8cf65d 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -89,6 +89,7 @@ obj-$(CONFIG_SKY2) += sky2.o
obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_KS8842) += ks8842.o
obj-$(CONFIG_KS8851) += ks8851.o
+obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index fdf5937233f..04f63c77071 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -721,7 +721,7 @@ static inline void update_rx_stats(struct net_device *dev, u32 status)
ps->rx_errors++;
if (status & RX_MISSED_FRAME)
ps->rx_missed_errors++;
- if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
+ if (status & (RX_OVERLEN | RX_RUNT | RX_LEN_ERROR))
ps->rx_length_errors++;
if (status & RX_CRC_ERROR)
ps->rx_crc_errors++;
@@ -794,8 +794,6 @@ static int au1000_rx(struct net_device *dev)
printk("rx len error\n");
if (status & RX_U_CNTRL_FRAME)
printk("rx u control frame\n");
- if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
}
}
prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index 09d270913c5..ba29dc319b3 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -90,7 +90,7 @@ static int do_mdio_op(struct bcm_enet_priv *priv, unsigned int data)
if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII)
break;
udelay(1);
- } while (limit-- >= 0);
+ } while (limit-- > 0);
return (limit < 0) ? 1 : 0;
}
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 684c6fe24c8..a80da0e14a5 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -258,6 +258,7 @@ struct be_adapter {
bool link_up;
u32 port_num;
bool promiscuous;
+ u32 cap;
};
extern const struct ethtool_ops be_ethtool_ops;
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 3dd76c4170b..89876ade5e3 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1068,7 +1068,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
}
/* Uses mbox */
-int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
+int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_query_fw_cfg *req;
@@ -1088,6 +1088,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
if (!status) {
struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
*port_num = le32_to_cpu(resp->phys_port);
+ *cap = le32_to_cpu(resp->function_cap);
}
spin_unlock(&adapter->mbox_lock);
@@ -1128,7 +1129,6 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter);
- req = embedded_payload(wrb);
sge = nonembedded_sgl(wrb);
be_wrb_hdr_prepare(wrb, cmd->size, false, 1);
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 93e432f3d92..a86f917f85f 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -62,7 +62,7 @@ enum {
MCC_STATUS_QUEUE_FLUSHING = 0x4,
/* The command is completing with a DMA error */
MCC_STATUS_DMA_FAILED = 0x5,
- MCC_STATUS_NOT_SUPPORTED = 0x66
+ MCC_STATUS_NOT_SUPPORTED = 66
};
#define CQE_STATUS_COMPL_MASK 0xFFFF
@@ -760,7 +760,8 @@ extern int be_cmd_set_flow_control(struct be_adapter *adapter,
u32 tx_fc, u32 rx_fc);
extern int be_cmd_get_flow_control(struct be_adapter *adapter,
u32 *tx_fc, u32 *rx_fc);
-extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num);
+extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
+ u32 *port_num, u32 *cap);
extern int be_cmd_reset_function(struct be_adapter *adapter);
extern int be_process_mcc(struct be_adapter *adapter);
extern int be_cmd_write_flashrom(struct be_adapter *adapter,
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 11445df3dbc..cda5bf2fc50 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -358,7 +358,7 @@ const struct ethtool_ops be_ethtool_ops = {
.get_rx_csum = be_get_rx_csum,
.set_rx_csum = be_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_hw_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 409cf059590..6d5e81f7046 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -197,7 +197,7 @@ void netdev_stats_update(struct be_adapter *adapter)
/* no space available in linux */
dev_stats->tx_dropped = 0;
- dev_stats->multicast = port_stats->tx_multicastframes;
+ dev_stats->multicast = port_stats->rx_multicast_frames;
dev_stats->collisions = 0;
/* detailed tx_errors */
@@ -747,9 +747,16 @@ static void be_rx_compl_process(struct be_adapter *adapter,
struct be_eth_rx_compl *rxcp)
{
struct sk_buff *skb;
- u32 vtp, vid;
+ u32 vlanf, vid;
+ u8 vtm;
- vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+ vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+ vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+
+ /* vlanf could be wrongly set in some cards.
+ * ignore if vtm is not set */
+ if ((adapter->cap == 0x400) && !vtm)
+ vlanf = 0;
skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
if (!skb) {
@@ -772,7 +779,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
skb->protocol = eth_type_trans(skb, adapter->netdev);
skb->dev = adapter->netdev;
- if (vtp) {
+ if (vlanf) {
if (!adapter->vlan_grp || adapter->num_vlans == 0) {
kfree_skb(skb);
return;
@@ -797,11 +804,18 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
struct be_eq_obj *eq_obj = &adapter->rx_eq;
u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
u16 i, rxq_idx = 0, vid, j;
+ u8 vtm;
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
+ vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+
+ /* vlanf could be wrongly set in some cards.
+ * ignore if vtm is not set */
+ if ((adapter->cap == 0x400) && !vtm)
+ vlanf = 0;
skb = napi_get_frags(&eq_obj->napi);
if (!skb) {
@@ -1885,8 +1899,8 @@ static void be_netdev_init(struct net_device *netdev)
struct be_adapter *adapter = netdev_priv(netdev);
netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM |
- NETIF_F_IPV6_CSUM | NETIF_F_GRO;
+ NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM |
+ NETIF_F_GRO;
netdev->flags |= IFF_MULTICAST;
@@ -2045,7 +2059,8 @@ static int be_hw_up(struct be_adapter *adapter)
if (status)
return status;
- status = be_cmd_query_fw_cfg(adapter, &adapter->port_num);
+ status = be_cmd_query_fw_cfg(adapter,
+ &adapter->port_num, &adapter->cap);
return status;
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 6044e12ff9f..ff449de6f3c 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1182,6 +1182,7 @@ static ssize_t bonding_store_primary(struct device *d,
": %s: Setting %s as primary slave.\n",
bond->dev->name, slave->dev->name);
bond->primary_slave = slave;
+ strcpy(bond->params.primary, slave->dev->name);
bond_select_active_slave(bond);
goto out;
}
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 211c8e9182f..46c87ec7960 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2733,7 +2733,8 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
cnic_ulp_init(dev);
else if (event == NETDEV_UNREGISTER)
cnic_ulp_exit(dev);
- else if (event == NETDEV_UP) {
+
+ if (event == NETDEV_UP) {
if (cnic_register_netdev(dev) != 0) {
cnic_put(dev);
goto done;
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index a49235739ee..d8b09efdcb5 100644
--- a/drivers/net/cnic_if.h
+++ b/drivers/net/cnic_if.h
@@ -12,8 +12,8 @@
#ifndef CNIC_IF_H
#define CNIC_IF_H
-#define CNIC_MODULE_VERSION "2.0.0"
-#define CNIC_MODULE_RELDATE "May 21, 2009"
+#define CNIC_MODULE_VERSION "2.0.1"
+#define CNIC_MODULE_RELDATE "Oct 01, 2009"
#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index b53b40ba88a..d1e0563a67d 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1803,7 +1803,7 @@ struct e1000_info e1000_82574_info = {
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
.pba = 20,
- .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
+ .max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_bm,
@@ -1820,7 +1820,7 @@ struct e1000_info e1000_82583_info = {
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
.pba = 20,
- .max_hw_frame_size = DEFAULT_JUMBO,
+ .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
.mac_ops = &e82571_mac_ops,
.phy_ops = &e82_phy_ops_bm,
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 16c193a6c95..0687c6aa4e4 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4982,12 +4982,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
goto err_pci_reg;
/* AER (Advanced Error Reporting) hooks */
- err = pci_enable_pcie_error_reporting(pdev);
- if (err) {
- dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
- "0x%x\n", err);
- /* non-fatal, continue */
- }
+ pci_enable_pcie_error_reporting(pdev);
pci_set_master(pdev);
/* PCI config space info */
@@ -5263,7 +5258,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
- int err;
/*
* flush_scheduled work may reschedule our watchdog task, so
@@ -5299,10 +5293,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
free_netdev(netdev);
/* AER disable */
- err = pci_disable_pcie_error_reporting(pdev);
- if (err)
- dev_err(&pdev->dev,
- "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+ pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev);
}
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index b7311bc0025..34d0c69e67f 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -19,6 +19,10 @@
#include <linux/platform_device.h>
#include <net/ethoc.h>
+static int buffer_size = 0x8000; /* 32 KBytes */
+module_param(buffer_size, int, 0);
+MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
+
/* register offsets */
#define MODER 0x00
#define INT_SOURCE 0x04
@@ -167,6 +171,7 @@
* struct ethoc - driver-private device structure
* @iobase: pointer to I/O memory region
* @membase: pointer to buffer memory region
+ * @dma_alloc: dma allocated buffer size
* @num_tx: number of send buffers
* @cur_tx: last send buffer written
* @dty_tx: last buffer actually sent
@@ -185,6 +190,7 @@
struct ethoc {
void __iomem *iobase;
void __iomem *membase;
+ int dma_alloc;
unsigned int num_tx;
unsigned int cur_tx;
@@ -284,7 +290,7 @@ static int ethoc_init_ring(struct ethoc *dev)
dev->cur_rx = 0;
/* setup transmission buffers */
- bd.addr = 0;
+ bd.addr = virt_to_phys(dev->membase);
bd.stat = TX_BD_IRQ | TX_BD_CRC;
for (i = 0; i < dev->num_tx; i++) {
@@ -295,7 +301,6 @@ static int ethoc_init_ring(struct ethoc *dev)
bd.addr += ETHOC_BUFSIZ;
}
- bd.addr = dev->num_tx * ETHOC_BUFSIZ;
bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
for (i = 0; i < dev->num_rx; i++) {
@@ -400,8 +405,12 @@ static int ethoc_rx(struct net_device *dev, int limit)
if (ethoc_update_rx_stats(priv, &bd) == 0) {
int size = bd.stat >> 16;
struct sk_buff *skb = netdev_alloc_skb(dev, size);
+
+ size -= 4; /* strip the CRC */
+ skb_reserve(skb, 2); /* align TCP/IP header */
+
if (likely(skb)) {
- void *src = priv->membase + bd.addr;
+ void *src = phys_to_virt(bd.addr);
memcpy_fromio(skb_put(skb, size), src, size);
skb->protocol = eth_type_trans(skb, dev);
priv->stats.rx_packets++;
@@ -653,9 +662,9 @@ static int ethoc_open(struct net_device *dev)
if (ret)
return ret;
- /* calculate the number of TX/RX buffers */
- num_bd = (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ;
- priv->num_tx = min(min_tx, num_bd / 4);
+ /* calculate the number of TX/RX buffers, maximum 128 supported */
+ num_bd = min(128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
+ priv->num_tx = max(min_tx, num_bd / 4);
priv->num_rx = num_bd - priv->num_tx;
ethoc_write(priv, TX_BD_NUM, priv->num_tx);
@@ -823,7 +832,7 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
else
bd.stat &= ~TX_BD_PAD;
- dest = priv->membase + bd.addr;
+ dest = phys_to_virt(bd.addr);
memcpy_toio(dest, skb->data, skb->len);
bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
@@ -903,22 +912,19 @@ static int ethoc_probe(struct platform_device *pdev)
/* obtain buffer memory space */
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res) {
- dev_err(&pdev->dev, "cannot obtain memory space\n");
- ret = -ENXIO;
- goto free;
- }
-
- mem = devm_request_mem_region(&pdev->dev, res->start,
+ if (res) {
+ mem = devm_request_mem_region(&pdev->dev, res->start,
res->end - res->start + 1, res->name);
- if (!mem) {
- dev_err(&pdev->dev, "cannot request memory space\n");
- ret = -ENXIO;
- goto free;
+ if (!mem) {
+ dev_err(&pdev->dev, "cannot request memory space\n");
+ ret = -ENXIO;
+ goto free;
+ }
+
+ netdev->mem_start = mem->start;
+ netdev->mem_end = mem->end;
}
- netdev->mem_start = mem->start;
- netdev->mem_end = mem->end;
/* obtain device IRQ number */
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -933,6 +939,7 @@ static int ethoc_probe(struct platform_device *pdev)
/* setup driver-private data */
priv = netdev_priv(netdev);
priv->netdev = netdev;
+ priv->dma_alloc = 0;
priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
mmio->end - mmio->start + 1);
@@ -942,12 +949,27 @@ static int ethoc_probe(struct platform_device *pdev)
goto error;
}
- priv->membase = devm_ioremap_nocache(&pdev->dev, netdev->mem_start,
- mem->end - mem->start + 1);
- if (!priv->membase) {
- dev_err(&pdev->dev, "cannot remap memory space\n");
- ret = -ENXIO;
- goto error;
+ if (netdev->mem_end) {
+ priv->membase = devm_ioremap_nocache(&pdev->dev,
+ netdev->mem_start, mem->end - mem->start + 1);
+ if (!priv->membase) {
+ dev_err(&pdev->dev, "cannot remap memory space\n");
+ ret = -ENXIO;
+ goto error;
+ }
+ } else {
+ /* Allocate buffer memory */
+ priv->membase = dma_alloc_coherent(NULL,
+ buffer_size, (void *)&netdev->mem_start,
+ GFP_KERNEL);
+ if (!priv->membase) {
+ dev_err(&pdev->dev, "cannot allocate %dB buffer\n",
+ buffer_size);
+ ret = -ENOMEM;
+ goto error;
+ }
+ netdev->mem_end = netdev->mem_start + buffer_size;
+ priv->dma_alloc = buffer_size;
}
/* Allow the platform setup code to pass in a MAC address. */
@@ -1034,6 +1056,9 @@ free_mdio:
kfree(priv->mdio->irq);
mdiobus_free(priv->mdio);
free:
+ if (priv->dma_alloc)
+ dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
+ netdev->mem_start);
free_netdev(netdev);
out:
return ret;
@@ -1059,7 +1084,9 @@ static int ethoc_remove(struct platform_device *pdev)
kfree(priv->mdio->irq);
mdiobus_free(priv->mdio);
}
-
+ if (priv->dma_alloc)
+ dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
+ netdev->mem_start);
unregister_netdev(netdev);
free_netdev(netdev);
}
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 33b55f72974..db4b7f1603f 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -258,7 +258,7 @@ static void ax_bump(struct mkiss *ax)
}
if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
printk(KERN_INFO
- "mkiss: %s: Switchting to crc-smack\n",
+ "mkiss: %s: Switching to crc-smack\n",
ax->dev->name);
ax->crcmode = CRC_MODE_SMACK;
}
@@ -272,7 +272,7 @@ static void ax_bump(struct mkiss *ax)
}
if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
printk(KERN_INFO
- "mkiss: %s: Switchting to crc-flexnet\n",
+ "mkiss: %s: Switching to crc-flexnet\n",
ax->dev->name);
ax->crcmode = CRC_MODE_FLEX;
}
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 5d6c1530a8c..714c3a4a44e 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1246,12 +1246,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (err)
goto err_pci_reg;
- err = pci_enable_pcie_error_reporting(pdev);
- if (err) {
- dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
- "0x%x\n", err);
- /* non-fatal, continue */
- }
+ pci_enable_pcie_error_reporting(pdev);
pci_set_master(pdev);
pci_save_state(pdev);
@@ -1628,7 +1623,6 @@ static void __devexit igb_remove(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- int err;
/* flush_scheduled work may reschedule our watchdog task, so
* explicitly disable watchdog tasks from being rescheduled */
@@ -1682,10 +1676,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
free_netdev(netdev);
- err = pci_disable_pcie_error_reporting(pdev);
- if (err)
- dev_err(&pdev->dev,
- "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+ pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev);
}
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index e36e951cbc6..aa7286bc436 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -495,7 +495,7 @@ static void veth_take_cap_ack(struct veth_lpar_connection *cnx,
cnx->remote_lp);
} else {
memcpy(&cnx->cap_ack_event, event,
- sizeof(&cnx->cap_ack_event));
+ sizeof(cnx->cap_ack_event));
cnx->state |= VETH_STATE_GOTCAPACK;
veth_kick_statemachine(cnx);
}
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 56b12f3192f..e2d5343f127 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -425,7 +425,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
#endif /* CONFIG_DCB */
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = -IXGBE_ERR_CONFIG;
+ ret_val = IXGBE_ERR_CONFIG;
goto out;
break;
}
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 2ec58dcdb82..34b04924c8a 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -330,6 +330,8 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
switch (hw->device_id) {
case IXGBE_DEV_ID_82599_KX4:
+ case IXGBE_DEV_ID_82599_KX4_MEZZ:
+ case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
case IXGBE_DEV_ID_82599_XAUI_LOM:
/* Default device ID is mezzanine card KX/KX4 */
media_type = ixgbe_media_type_backplane;
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 6621e172df3..40ff120a9ad 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1355,9 +1355,7 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
/**
* ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
* @hw: pointer to hardware structure
- * @addr_list: the list of new addresses
- * @addr_count: number of addresses
- * @next: iterator function to walk the address list
+ * @uc_list: the list of new addresses
*
* The given list replaces any existing list. Clears the secondary addrs from
* receive address registers. Uses unused receive address registers for the
@@ -1663,7 +1661,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
#endif /* CONFIG_DCB */
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = -IXGBE_ERR_CONFIG;
+ ret_val = IXGBE_ERR_CONFIG;
goto out;
break;
}
@@ -1734,75 +1732,140 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
s32 ret_val = 0;
ixgbe_link_speed speed;
u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
+ u32 links2, anlp1_reg, autoc_reg, links;
bool link_up;
/*
* AN should have completed when the cable was plugged in.
* Look for reasons to bail out. Bail out if:
* - FC autoneg is disabled, or if
- * - we don't have multispeed fiber, or if
- * - we're not running at 1G, or if
- * - link is not up, or if
- * - link is up but AN did not complete, or if
- * - link is up and AN completed but timed out
+ * - link is not up.
*
- * Since we're being called from an LSC, link is already know to be up.
+ * Since we're being called from an LSC, link is already known to be up.
* So use link_up_wait_to_complete=false.
*/
hw->mac.ops.check_link(hw, &speed, &link_up, false);
- linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
-
- if (hw->fc.disable_fc_autoneg ||
- !hw->phy.multispeed_fiber ||
- (speed != IXGBE_LINK_SPEED_1GB_FULL) ||
- !link_up ||
- ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
- ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
+
+ if (hw->fc.disable_fc_autoneg || (!link_up)) {
hw->fc.fc_was_autonegged = false;
hw->fc.current_mode = hw->fc.requested_mode;
- hw_dbg(hw, "Autoneg FC was skipped.\n");
goto out;
}
/*
+ * On backplane, bail out if
+ * - backplane autoneg was not completed, or if
+ * - link partner is not AN enabled
+ */
+ if (hw->phy.media_type == ixgbe_media_type_backplane) {
+ links = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
+ if (((links & IXGBE_LINKS_KX_AN_COMP) == 0) ||
+ ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0)) {
+ hw->fc.fc_was_autonegged = false;
+ hw->fc.current_mode = hw->fc.requested_mode;
+ goto out;
+ }
+ }
+
+ /*
+ * On multispeed fiber at 1g, bail out if
+ * - link is up but AN did not complete, or if
+ * - link is up and AN completed but timed out
+ */
+ if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) {
+ linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
+ if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
+ ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
+ hw->fc.fc_was_autonegged = false;
+ hw->fc.current_mode = hw->fc.requested_mode;
+ goto out;
+ }
+ }
+
+ /*
* Read the AN advertisement and LP ability registers and resolve
* local flow control settings accordingly
*/
- pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
- pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
- if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
- (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
+ if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
+ (hw->phy.media_type != ixgbe_media_type_backplane)) {
+ pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+ pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
+ if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
+ /*
+ * Now we need to check if the user selected Rx ONLY
+ * of pause frames. In this case, we had to advertise
+ * FULL flow control because we could not advertise RX
+ * ONLY. Hence, we must now check to see if we need to
+ * turn OFF the TRANSMISSION of PAUSE frames.
+ */
+ if (hw->fc.requested_mode == ixgbe_fc_full) {
+ hw->fc.current_mode = ixgbe_fc_full;
+ hw_dbg(hw, "Flow Control = FULL.\n");
+ } else {
+ hw->fc.current_mode = ixgbe_fc_rx_pause;
+ hw_dbg(hw, "Flow Control=RX PAUSE only\n");
+ }
+ } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+ hw->fc.current_mode = ixgbe_fc_tx_pause;
+ hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
+ } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+ !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+ hw->fc.current_mode = ixgbe_fc_rx_pause;
+ hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+ } else {
+ hw->fc.current_mode = ixgbe_fc_none;
+ hw_dbg(hw, "Flow Control = NONE.\n");
+ }
+ }
+
+ if (hw->phy.media_type == ixgbe_media_type_backplane) {
/*
- * Now we need to check if the user selected Rx ONLY
- * of pause frames. In this case, we had to advertise
- * FULL flow control because we could not advertise RX
- * ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
+ * Read the 10g AN autoc and LP ability registers and resolve
+ * local flow control settings accordingly
*/
- if (hw->fc.requested_mode == ixgbe_fc_full) {
- hw->fc.current_mode = ixgbe_fc_full;
- hw_dbg(hw, "Flow Control = FULL.\n");
- } else {
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
+
+ if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
+ (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE)) {
+ /*
+ * Now we need to check if the user selected Rx ONLY
+ * of pause frames. In this case, we had to advertise
+ * FULL flow control because we could not advertise RX
+ * ONLY. Hence, we must now check to see if we need to
+ * turn OFF the TRANSMISSION of PAUSE frames.
+ */
+ if (hw->fc.requested_mode == ixgbe_fc_full) {
+ hw->fc.current_mode = ixgbe_fc_full;
+ hw_dbg(hw, "Flow Control = FULL.\n");
+ } else {
+ hw->fc.current_mode = ixgbe_fc_rx_pause;
+ hw_dbg(hw, "Flow Control=RX PAUSE only\n");
+ }
+ } else if (!(autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
+ (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) &&
+ (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) &&
+ (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) {
+ hw->fc.current_mode = ixgbe_fc_tx_pause;
+ hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
+ } else if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
+ (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) &&
+ !(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) &&
+ (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) {
hw->fc.current_mode = ixgbe_fc_rx_pause;
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+ } else {
+ hw->fc.current_mode = ixgbe_fc_none;
+ hw_dbg(hw, "Flow Control = NONE.\n");
}
- } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
- (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
- (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
- (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
- hw->fc.current_mode = ixgbe_fc_tx_pause;
- hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
- } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
- (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
- !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
- (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
- hw->fc.current_mode = ixgbe_fc_rx_pause;
- hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
- } else {
- hw->fc.current_mode = ixgbe_fc_none;
- hw_dbg(hw, "Flow Control = NONE.\n");
}
-
/* Record that current_mode is the result of a successful autoneg */
hw->fc.fc_was_autonegged = true;
@@ -1919,7 +1982,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
#endif /* CONFIG_DCB */
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = -IXGBE_ERR_CONFIG;
+ ret_val = IXGBE_ERR_CONFIG;
goto out;
break;
}
@@ -1927,9 +1990,6 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
- /* Enable and restart autoneg to inform the link partner */
- reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
-
/* Disable AN timeout */
if (hw->fc.strict_ieee)
reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
@@ -1937,6 +1997,70 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
+ /*
+ * Set up the 10G flow control advertisement registers so the HW
+ * can do fc autoneg once the cable is plugged in. If we end up
+ * using 1g instead, this is harmless.
+ */
+ reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+ /*
+ * The possible values of fc.requested_mode are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause frames,
+ * but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames but
+ * we do not support receiving pause frames).
+ * 3: Both Rx and Tx flow control (symmetric) are enabled.
+ * other: Invalid.
+ */
+ switch (hw->fc.requested_mode) {
+ case ixgbe_fc_none:
+ /* Flow control completely disabled by software override. */
+ reg &= ~(IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
+ break;
+ case ixgbe_fc_rx_pause:
+ /*
+ * Rx Flow control is enabled and Tx Flow control is
+ * disabled by software override. Since there really
+ * isn't a way to advertise that we are capable of RX
+ * Pause ONLY, we will advertise that we support both
+ * symmetric and asymmetric Rx PAUSE. Later, we will
+ * disable the adapter's ability to send PAUSE frames.
+ */
+ reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
+ break;
+ case ixgbe_fc_tx_pause:
+ /*
+ * Tx Flow control is enabled, and Rx Flow control is
+ * disabled by software override.
+ */
+ reg |= (IXGBE_AUTOC_ASM_PAUSE);
+ reg &= ~(IXGBE_AUTOC_SYM_PAUSE);
+ break;
+ case ixgbe_fc_full:
+ /* Flow control (both Rx and Tx) is enabled by SW override. */
+ reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
+ break;
+#ifdef CONFIG_DCB
+ case ixgbe_fc_pfc:
+ goto out;
+ break;
+#endif /* CONFIG_DCB */
+ default:
+ hw_dbg(hw, "Flow control param set incorrectly\n");
+ ret_val = IXGBE_ERR_CONFIG;
+ goto out;
+ break;
+ }
+ /*
+ * AUTOC restart handles negotiation of 1G and 10G. There is
+ * no need to set the PCS1GCTL register.
+ */
+ reg |= IXGBE_AUTOC_AN_RESTART;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg);
+ hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
+
out:
return ret_val;
}
@@ -2000,7 +2124,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
while (timeout) {
if (ixgbe_get_eeprom_semaphore(hw))
- return -IXGBE_ERR_SWFW_SYNC;
+ return IXGBE_ERR_SWFW_SYNC;
gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
if (!(gssr & (fwmask | swmask)))
@@ -2017,7 +2141,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
if (!timeout) {
hw_dbg(hw, "Driver can't access resource, GSSR timeout.\n");
- return -IXGBE_ERR_SWFW_SYNC;
+ return IXGBE_ERR_SWFW_SYNC;
}
gssr |= swmask;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 53b0a668025..fa314cb005a 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -53,6 +53,10 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
{"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)},
{"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)},
+ {"rx_pkts_nic", IXGBE_STAT(stats.gprc)},
+ {"tx_pkts_nic", IXGBE_STAT(stats.gptc)},
+ {"rx_bytes_nic", IXGBE_STAT(stats.gorc)},
+ {"tx_bytes_nic", IXGBE_STAT(stats.gotc)},
{"lsc_int", IXGBE_STAT(lsc_int)},
{"tx_busy", IXGBE_STAT(tx_busy)},
{"non_eop_descs", IXGBE_STAT(non_eop_descs)},
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index c407bd9de0d..cbb143ca1eb 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -49,7 +49,7 @@ char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
-#define DRV_VERSION "2.0.37-k2"
+#define DRV_VERSION "2.0.44-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
@@ -97,8 +97,12 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4_MEZZ),
+ board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4),
board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE),
+ board_82599 },
/* required last entry */
{0, }
@@ -1885,12 +1889,29 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
adapter->tx_ring[i].head = IXGBE_TDH(j);
adapter->tx_ring[i].tail = IXGBE_TDT(j);
- /* Disable Tx Head Writeback RO bit, since this hoses
+ /*
+ * Disable Tx Head Writeback RO bit, since this hoses
* bookkeeping if things aren't delivered in order.
*/
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
+ break;
+ case ixgbe_mac_82599EB:
+ default:
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j));
+ break;
+ }
txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
+ break;
+ case ixgbe_mac_82599EB:
+ default:
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl);
+ break;
+ }
}
if (hw->mac.type == ixgbe_mac_82599EB) {
/* We enable 8 traffic classes, DCB only */
@@ -4432,10 +4453,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
/* 82598 hardware only has a 32 bit counter in the high register */
if (hw->mac.type == ixgbe_mac_82599EB) {
+ u64 tmp;
adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
- IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
+ tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */
+ adapter->stats.gorc += (tmp << 32);
adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
- IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */
+ tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */
+ adapter->stats.gotc += (tmp << 32);
adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
@@ -5071,7 +5095,6 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
/* Right now, we support IPv4 only */
struct ixgbe_atr_input atr_input;
struct tcphdr *th;
- struct udphdr *uh;
struct iphdr *iph = ip_hdr(skb);
struct ethhdr *eth = (struct ethhdr *)skb->data;
u16 vlan_id, src_port, dst_port, flex_bytes;
@@ -5085,12 +5108,6 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
dst_port = th->dest;
l4type |= IXGBE_ATR_L4TYPE_TCP;
/* l4type IPv4 type is 0, no need to assign */
- } else if(iph->protocol == IPPROTO_UDP) {
- uh = udp_hdr(skb);
- src_port = uh->source;
- dst_port = uh->dest;
- l4type |= IXGBE_ATR_L4TYPE_UDP;
- /* l4type IPv4 type is 0, no need to assign */
} else {
/* Unsupported L4 header, just bail here */
return;
@@ -5494,12 +5511,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
goto err_pci_reg;
}
- err = pci_enable_pcie_error_reporting(pdev);
- if (err) {
- dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
- "0x%x\n", err);
- /* non-fatal, continue */
- }
+ pci_enable_pcie_error_reporting(pdev);
pci_set_master(pdev);
pci_save_state(pdev);
@@ -5808,7 +5820,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- int err;
set_bit(__IXGBE_DOWN, &adapter->state);
/* clear the module not found bit to make sure the worker won't
@@ -5859,10 +5870,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
free_netdev(netdev);
- err = pci_disable_pcie_error_reporting(pdev);
- if (err)
- dev_err(&pdev->dev,
- "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+ pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev);
}
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 8761d7899f7..ef4bdd58e01 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -49,9 +49,11 @@
#define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1
#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
#define IXGBE_DEV_ID_82599_KX4 0x10F7
+#define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514
#define IXGBE_DEV_ID_82599_CX4 0x10F9
#define IXGBE_DEV_ID_82599_SFP 0x10FB
#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
+#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -1336,6 +1338,8 @@
#define IXGBE_AUTOC_KX4_SUPP 0x80000000
#define IXGBE_AUTOC_KX_SUPP 0x40000000
#define IXGBE_AUTOC_PAUSE 0x30000000
+#define IXGBE_AUTOC_ASM_PAUSE 0x20000000
+#define IXGBE_AUTOC_SYM_PAUSE 0x10000000
#define IXGBE_AUTOC_RF 0x08000000
#define IXGBE_AUTOC_PD_TMR 0x06000000
#define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000
@@ -1404,6 +1408,8 @@
#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
+#define IXGBE_LINKS2_AN_SUPPORTED 0x00000040
+
/* PCS1GLSTA Bit Masks */
#define IXGBE_PCS1GLSTA_LINK_OK 1
#define IXGBE_PCS1GLSTA_SYNK_OK 0x10
@@ -1424,6 +1430,11 @@
#define IXGBE_PCS1GLCTL_AN_ENABLE 0x10000
#define IXGBE_PCS1GLCTL_AN_RESTART 0x20000
+/* ANLP1 Bit Masks */
+#define IXGBE_ANLP1_PAUSE 0x0C00
+#define IXGBE_ANLP1_SYM_PAUSE 0x0400
+#define IXGBE_ANLP1_ASM_PAUSE 0x0800
+
/* SW Semaphore Register bitmasks */
#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
new file mode 100644
index 00000000000..0be14d702be
--- /dev/null
+++ b/drivers/net/ks8851_mll.c
@@ -0,0 +1,1697 @@
+/**
+ * drivers/net/ks8851_mll.c
+ * Copyright (c) 2009 Micrel Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/**
+ * Supports:
+ * KS8851 16bit MLL chip from Micrel Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/cache.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#define DRV_NAME "ks8851_mll"
+
+static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
+#define MAX_RECV_FRAMES 32
+#define MAX_BUF_SIZE 2048
+#define TX_BUF_SIZE 2000
+#define RX_BUF_SIZE 2000
+
+#define KS_CCR 0x08
+#define CCR_EEPROM (1 << 9)
+#define CCR_SPI (1 << 8)
+#define CCR_8BIT (1 << 7)
+#define CCR_16BIT (1 << 6)
+#define CCR_32BIT (1 << 5)
+#define CCR_SHARED (1 << 4)
+#define CCR_32PIN (1 << 0)
+
+/* MAC address registers */
+#define KS_MARL 0x10
+#define KS_MARM 0x12
+#define KS_MARH 0x14
+
+#define KS_OBCR 0x20
+#define OBCR_ODS_16MA (1 << 6)
+
+#define KS_EEPCR 0x22
+#define EEPCR_EESA (1 << 4)
+#define EEPCR_EESB (1 << 3)
+#define EEPCR_EEDO (1 << 2)
+#define EEPCR_EESCK (1 << 1)
+#define EEPCR_EECS (1 << 0)
+
+#define KS_MBIR 0x24
+#define MBIR_TXMBF (1 << 12)
+#define MBIR_TXMBFA (1 << 11)
+#define MBIR_RXMBF (1 << 4)
+#define MBIR_RXMBFA (1 << 3)
+
+#define KS_GRR 0x26
+#define GRR_QMU (1 << 1)
+#define GRR_GSR (1 << 0)
+
+#define KS_WFCR 0x2A
+#define WFCR_MPRXE (1 << 7)
+#define WFCR_WF3E (1 << 3)
+#define WFCR_WF2E (1 << 2)
+#define WFCR_WF1E (1 << 1)
+#define WFCR_WF0E (1 << 0)
+
+#define KS_WF0CRC0 0x30
+#define KS_WF0CRC1 0x32
+#define KS_WF0BM0 0x34
+#define KS_WF0BM1 0x36
+#define KS_WF0BM2 0x38
+#define KS_WF0BM3 0x3A
+
+#define KS_WF1CRC0 0x40
+#define KS_WF1CRC1 0x42
+#define KS_WF1BM0 0x44
+#define KS_WF1BM1 0x46
+#define KS_WF1BM2 0x48
+#define KS_WF1BM3 0x4A
+
+#define KS_WF2CRC0 0x50
+#define KS_WF2CRC1 0x52
+#define KS_WF2BM0 0x54
+#define KS_WF2BM1 0x56
+#define KS_WF2BM2 0x58
+#define KS_WF2BM3 0x5A
+
+#define KS_WF3CRC0 0x60
+#define KS_WF3CRC1 0x62
+#define KS_WF3BM0 0x64
+#define KS_WF3BM1 0x66
+#define KS_WF3BM2 0x68
+#define KS_WF3BM3 0x6A
+
+#define KS_TXCR 0x70
+#define TXCR_TCGICMP (1 << 8)
+#define TXCR_TCGUDP (1 << 7)
+#define TXCR_TCGTCP (1 << 6)
+#define TXCR_TCGIP (1 << 5)
+#define TXCR_FTXQ (1 << 4)
+#define TXCR_TXFCE (1 << 3)
+#define TXCR_TXPE (1 << 2)
+#define TXCR_TXCRC (1 << 1)
+#define TXCR_TXE (1 << 0)
+
+#define KS_TXSR 0x72
+#define TXSR_TXLC (1 << 13)
+#define TXSR_TXMC (1 << 12)
+#define TXSR_TXFID_MASK (0x3f << 0)
+#define TXSR_TXFID_SHIFT (0)
+#define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f)
+
+
+#define KS_RXCR1 0x74
+#define RXCR1_FRXQ (1 << 15)
+#define RXCR1_RXUDPFCC (1 << 14)
+#define RXCR1_RXTCPFCC (1 << 13)
+#define RXCR1_RXIPFCC (1 << 12)
+#define RXCR1_RXPAFMA (1 << 11)
+#define RXCR1_RXFCE (1 << 10)
+#define RXCR1_RXEFE (1 << 9)
+#define RXCR1_RXMAFMA (1 << 8)
+#define RXCR1_RXBE (1 << 7)
+#define RXCR1_RXME (1 << 6)
+#define RXCR1_RXUE (1 << 5)
+#define RXCR1_RXAE (1 << 4)
+#define RXCR1_RXINVF (1 << 1)
+#define RXCR1_RXE (1 << 0)
+#define RXCR1_FILTER_MASK (RXCR1_RXINVF | RXCR1_RXAE | \
+ RXCR1_RXMAFMA | RXCR1_RXPAFMA)
+
+#define KS_RXCR2 0x76
+#define RXCR2_SRDBL_MASK (0x7 << 5)
+#define RXCR2_SRDBL_SHIFT (5)
+#define RXCR2_SRDBL_4B (0x0 << 5)
+#define RXCR2_SRDBL_8B (0x1 << 5)
+#define RXCR2_SRDBL_16B (0x2 << 5)
+#define RXCR2_SRDBL_32B (0x3 << 5)
+/* #define RXCR2_SRDBL_FRAME (0x4 << 5) */
+#define RXCR2_IUFFP (1 << 4)
+#define RXCR2_RXIUFCEZ (1 << 3)
+#define RXCR2_UDPLFE (1 << 2)
+#define RXCR2_RXICMPFCC (1 << 1)
+#define RXCR2_RXSAF (1 << 0)
+
+#define KS_TXMIR 0x78
+
+#define KS_RXFHSR 0x7C
+#define RXFSHR_RXFV (1 << 15)
+#define RXFSHR_RXICMPFCS (1 << 13)
+#define RXFSHR_RXIPFCS (1 << 12)
+#define RXFSHR_RXTCPFCS (1 << 11)
+#define RXFSHR_RXUDPFCS (1 << 10)
+#define RXFSHR_RXBF (1 << 7)
+#define RXFSHR_RXMF (1 << 6)
+#define RXFSHR_RXUF (1 << 5)
+#define RXFSHR_RXMR (1 << 4)
+#define RXFSHR_RXFT (1 << 3)
+#define RXFSHR_RXFTL (1 << 2)
+#define RXFSHR_RXRF (1 << 1)
+#define RXFSHR_RXCE (1 << 0)
+#define RXFSHR_ERR (RXFSHR_RXCE | RXFSHR_RXRF |\
+ RXFSHR_RXFTL | RXFSHR_RXMR |\
+ RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS |\
+ RXFSHR_RXTCPFCS)
+#define KS_RXFHBCR 0x7E
+#define RXFHBCR_CNT_MASK 0x0FFF
+
+#define KS_TXQCR 0x80
+#define TXQCR_AETFE (1 << 2)
+#define TXQCR_TXQMAM (1 << 1)
+#define TXQCR_METFE (1 << 0)
+
+#define KS_RXQCR 0x82
+#define RXQCR_RXDTTS (1 << 12)
+#define RXQCR_RXDBCTS (1 << 11)
+#define RXQCR_RXFCTS (1 << 10)
+#define RXQCR_RXIPHTOE (1 << 9)
+#define RXQCR_RXDTTE (1 << 7)
+#define RXQCR_RXDBCTE (1 << 6)
+#define RXQCR_RXFCTE (1 << 5)
+#define RXQCR_ADRFE (1 << 4)
+#define RXQCR_SDA (1 << 3)
+#define RXQCR_RRXEF (1 << 0)
+#define RXQCR_CMD_CNTL (RXQCR_RXFCTE|RXQCR_ADRFE)
+
+#define KS_TXFDPR 0x84
+#define TXFDPR_TXFPAI (1 << 14)
+#define TXFDPR_TXFP_MASK (0x7ff << 0)
+#define TXFDPR_TXFP_SHIFT (0)
+
+#define KS_RXFDPR 0x86
+#define RXFDPR_RXFPAI (1 << 14)
+
+#define KS_RXDTTR 0x8C
+#define KS_RXDBCTR 0x8E
+
+#define KS_IER 0x90
+#define KS_ISR 0x92
+#define IRQ_LCI (1 << 15)
+#define IRQ_TXI (1 << 14)
+#define IRQ_RXI (1 << 13)
+#define IRQ_RXOI (1 << 11)
+#define IRQ_TXPSI (1 << 9)
+#define IRQ_RXPSI (1 << 8)
+#define IRQ_TXSAI (1 << 6)
+#define IRQ_RXWFDI (1 << 5)
+#define IRQ_RXMPDI (1 << 4)
+#define IRQ_LDI (1 << 3)
+#define IRQ_EDI (1 << 2)
+#define IRQ_SPIBEI (1 << 1)
+#define IRQ_DEDI (1 << 0)
+
+#define KS_RXFCTR 0x9C
+#define RXFCTR_THRESHOLD_MASK 0x00FF
+
+#define KS_RXFC 0x9D
+#define RXFCTR_RXFC_MASK (0xff << 8)
+#define RXFCTR_RXFC_SHIFT (8)
+#define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff)
+#define RXFCTR_RXFCT_MASK (0xff << 0)
+#define RXFCTR_RXFCT_SHIFT (0)
+
+#define KS_TXNTFSR 0x9E
+
+#define KS_MAHTR0 0xA0
+#define KS_MAHTR1 0xA2
+#define KS_MAHTR2 0xA4
+#define KS_MAHTR3 0xA6
+
+#define KS_FCLWR 0xB0
+#define KS_FCHWR 0xB2
+#define KS_FCOWR 0xB4
+
+#define KS_CIDER 0xC0
+#define CIDER_ID 0x8870
+#define CIDER_REV_MASK (0x7 << 1)
+#define CIDER_REV_SHIFT (1)
+#define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7)
+
+#define KS_CGCR 0xC6
+#define KS_IACR 0xC8
+#define IACR_RDEN (1 << 12)
+#define IACR_TSEL_MASK (0x3 << 10)
+#define IACR_TSEL_SHIFT (10)
+#define IACR_TSEL_MIB (0x3 << 10)
+#define IACR_ADDR_MASK (0x1f << 0)
+#define IACR_ADDR_SHIFT (0)
+
+#define KS_IADLR 0xD0
+#define KS_IAHDR 0xD2
+
+#define KS_PMECR 0xD4
+#define PMECR_PME_DELAY (1 << 14)
+#define PMECR_PME_POL (1 << 12)
+#define PMECR_WOL_WAKEUP (1 << 11)
+#define PMECR_WOL_MAGICPKT (1 << 10)
+#define PMECR_WOL_LINKUP (1 << 9)
+#define PMECR_WOL_ENERGY (1 << 8)
+#define PMECR_AUTO_WAKE_EN (1 << 7)
+#define PMECR_WAKEUP_NORMAL (1 << 6)
+#define PMECR_WKEVT_MASK (0xf << 2)
+#define PMECR_WKEVT_SHIFT (2)
+#define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf)
+#define PMECR_WKEVT_ENERGY (0x1 << 2)
+#define PMECR_WKEVT_LINK (0x2 << 2)
+#define PMECR_WKEVT_MAGICPKT (0x4 << 2)
+#define PMECR_WKEVT_FRAME (0x8 << 2)
+#define PMECR_PM_MASK (0x3 << 0)
+#define PMECR_PM_SHIFT (0)
+#define PMECR_PM_NORMAL (0x0 << 0)
+#define PMECR_PM_ENERGY (0x1 << 0)
+#define PMECR_PM_SOFTDOWN (0x2 << 0)
+#define PMECR_PM_POWERSAVE (0x3 << 0)
+
+/* Standard MII PHY data */
+#define KS_P1MBCR 0xE4
+#define P1MBCR_FORCE_FDX (1 << 8)
+
+#define KS_P1MBSR 0xE6
+#define P1MBSR_AN_COMPLETE (1 << 5)
+#define P1MBSR_AN_CAPABLE (1 << 3)
+#define P1MBSR_LINK_UP (1 << 2)
+
+#define KS_PHY1ILR 0xE8
+#define KS_PHY1IHR 0xEA
+#define KS_P1ANAR 0xEC
+#define KS_P1ANLPR 0xEE
+
+#define KS_P1SCLMD 0xF4
+#define P1SCLMD_LEDOFF (1 << 15)
+#define P1SCLMD_TXIDS (1 << 14)
+#define P1SCLMD_RESTARTAN (1 << 13)
+#define P1SCLMD_DISAUTOMDIX (1 << 10)
+#define P1SCLMD_FORCEMDIX (1 << 9)
+#define P1SCLMD_AUTONEGEN (1 << 7)
+#define P1SCLMD_FORCE100 (1 << 6)
+#define P1SCLMD_FORCEFDX (1 << 5)
+#define P1SCLMD_ADV_FLOW (1 << 4)
+#define P1SCLMD_ADV_100BT_FDX (1 << 3)
+#define P1SCLMD_ADV_100BT_HDX (1 << 2)
+#define P1SCLMD_ADV_10BT_FDX (1 << 1)
+#define P1SCLMD_ADV_10BT_HDX (1 << 0)
+
+#define KS_P1CR 0xF6
+#define P1CR_HP_MDIX (1 << 15)
+#define P1CR_REV_POL (1 << 13)
+#define P1CR_OP_100M (1 << 10)
+#define P1CR_OP_FDX (1 << 9)
+#define P1CR_OP_MDI (1 << 7)
+#define P1CR_AN_DONE (1 << 6)
+#define P1CR_LINK_GOOD (1 << 5)
+#define P1CR_PNTR_FLOW (1 << 4)
+#define P1CR_PNTR_100BT_FDX (1 << 3)
+#define P1CR_PNTR_100BT_HDX (1 << 2)
+#define P1CR_PNTR_10BT_FDX (1 << 1)
+#define P1CR_PNTR_10BT_HDX (1 << 0)
+
+/* TX Frame control */
+
+#define TXFR_TXIC (1 << 15)
+#define TXFR_TXFID_MASK (0x3f << 0)
+#define TXFR_TXFID_SHIFT (0)
+
+#define KS_P1SR 0xF8
+#define P1SR_HP_MDIX (1 << 15)
+#define P1SR_REV_POL (1 << 13)
+#define P1SR_OP_100M (1 << 10)
+#define P1SR_OP_FDX (1 << 9)
+#define P1SR_OP_MDI (1 << 7)
+#define P1SR_AN_DONE (1 << 6)
+#define P1SR_LINK_GOOD (1 << 5)
+#define P1SR_PNTR_FLOW (1 << 4)
+#define P1SR_PNTR_100BT_FDX (1 << 3)
+#define P1SR_PNTR_100BT_HDX (1 << 2)
+#define P1SR_PNTR_10BT_FDX (1 << 1)
+#define P1SR_PNTR_10BT_HDX (1 << 0)
+
+#define ENUM_BUS_NONE 0
+#define ENUM_BUS_8BIT 1
+#define ENUM_BUS_16BIT 2
+#define ENUM_BUS_32BIT 3
+
+#define MAX_MCAST_LST 32
+#define HW_MCAST_SIZE 8
+#define MAC_ADDR_LEN 6
+
+/**
+ * union ks_tx_hdr - tx header data
+ * @txb: The header as bytes
+ * @txw: The header as 16bit, little-endian words
+ *
+ * A dual representation of the tx header data to allow
+ * access to individual bytes, and to allow 16bit accesses
+ * with 16bit alignment.
+ */
+union ks_tx_hdr {
+ u8 txb[4];
+ __le16 txw[2];
+};
+
+/**
+ * struct ks_net - KS8851 driver private data
+ * @net_device : The network device we're bound to
+ * @hw_addr : start address of data register.
+ * @hw_addr_cmd : start address of command register.
+ * @txh : temporaly buffer to save status/length.
+ * @lock : Lock to ensure that the device is not accessed when busy.
+ * @pdev : Pointer to platform device.
+ * @mii : The MII state information for the mii calls.
+ * @frame_head_info : frame header information for multi-pkt rx.
+ * @statelock : Lock on this structure for tx list.
+ * @msg_enable : The message flags controlling driver output (see ethtool).
+ * @frame_cnt : number of frames received.
+ * @bus_width : i/o bus width.
+ * @irq : irq number assigned to this device.
+ * @rc_rxqcr : Cached copy of KS_RXQCR.
+ * @rc_txcr : Cached copy of KS_TXCR.
+ * @rc_ier : Cached copy of KS_IER.
+ * @sharedbus : Multipex(addr and data bus) mode indicator.
+ * @cmd_reg_cache : command register cached.
+ * @cmd_reg_cache_int : command register cached. Used in the irq handler.
+ * @promiscuous : promiscuous mode indicator.
+ * @all_mcast : mutlicast indicator.
+ * @mcast_lst_size : size of multicast list.
+ * @mcast_lst : multicast list.
+ * @mcast_bits : multicast enabed.
+ * @mac_addr : MAC address assigned to this device.
+ * @fid : frame id.
+ * @extra_byte : number of extra byte prepended rx pkt.
+ * @enabled : indicator this device works.
+ *
+ * The @lock ensures that the chip is protected when certain operations are
+ * in progress. When the read or write packet transfer is in progress, most
+ * of the chip registers are not accessible until the transfer is finished and
+ * the DMA has been de-asserted.
+ *
+ * The @statelock is used to protect information in the structure which may
+ * need to be accessed via several sources, such as the network driver layer
+ * or one of the work queues.
+ *
+ */
+
+/* Receive multiplex framer header info */
+struct type_frame_head {
+ u16 sts; /* Frame status */
+ u16 len; /* Byte count */
+};
+
+struct ks_net {
+ struct net_device *netdev;
+ void __iomem *hw_addr;
+ void __iomem *hw_addr_cmd;
+ union ks_tx_hdr txh ____cacheline_aligned;
+ struct mutex lock; /* spinlock to be interrupt safe */
+ struct platform_device *pdev;
+ struct mii_if_info mii;
+ struct type_frame_head *frame_head_info;
+ spinlock_t statelock;
+ u32 msg_enable;
+ u32 frame_cnt;
+ int bus_width;
+ int irq;
+
+ u16 rc_rxqcr;
+ u16 rc_txcr;
+ u16 rc_ier;
+ u16 sharedbus;
+ u16 cmd_reg_cache;
+ u16 cmd_reg_cache_int;
+ u16 promiscuous;
+ u16 all_mcast;
+ u16 mcast_lst_size;
+ u8 mcast_lst[MAX_MCAST_LST][MAC_ADDR_LEN];
+ u8 mcast_bits[HW_MCAST_SIZE];
+ u8 mac_addr[6];
+ u8 fid;
+ u8 extra_byte;
+ u8 enabled;
+};
+
+static int msg_enable;
+
+#define ks_info(_ks, _msg...) dev_info(&(_ks)->pdev->dev, _msg)
+#define ks_warn(_ks, _msg...) dev_warn(&(_ks)->pdev->dev, _msg)
+#define ks_dbg(_ks, _msg...) dev_dbg(&(_ks)->pdev->dev, _msg)
+#define ks_err(_ks, _msg...) dev_err(&(_ks)->pdev->dev, _msg)
+
+#define BE3 0x8000 /* Byte Enable 3 */
+#define BE2 0x4000 /* Byte Enable 2 */
+#define BE1 0x2000 /* Byte Enable 1 */
+#define BE0 0x1000 /* Byte Enable 0 */
+
+/**
+ * register read/write calls.
+ *
+ * All these calls issue transactions to access the chip's registers. They
+ * all require that the necessary lock is held to prevent accesses when the
+ * chip is busy transfering packet data (RX/TX FIFO accesses).
+ */
+
+/**
+ * ks_rdreg8 - read 8 bit register from device
+ * @ks : The chip information
+ * @offset: The register address
+ *
+ * Read a 8bit register from the chip, returning the result
+ */
+static u8 ks_rdreg8(struct ks_net *ks, int offset)
+{
+ u16 data;
+ u8 shift_bit = offset & 0x03;
+ u8 shift_data = (offset & 1) << 3;
+ ks->cmd_reg_cache = (u16) offset | (u16)(BE0 << shift_bit);
+ iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+ data = ioread16(ks->hw_addr);
+ return (u8)(data >> shift_data);
+}
+
+/**
+ * ks_rdreg16 - read 16 bit register from device
+ * @ks : The chip information
+ * @offset: The register address
+ *
+ * Read a 16bit register from the chip, returning the result
+ */
+
+static u16 ks_rdreg16(struct ks_net *ks, int offset)
+{
+ ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02));
+ iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+ return ioread16(ks->hw_addr);
+}
+
+/**
+ * ks_wrreg8 - write 8bit register value to chip
+ * @ks: The chip information
+ * @offset: The register address
+ * @value: The value to write
+ *
+ */
+static void ks_wrreg8(struct ks_net *ks, int offset, u8 value)
+{
+ u8 shift_bit = (offset & 0x03);
+ u16 value_write = (u16)(value << ((offset & 1) << 3));
+ ks->cmd_reg_cache = (u16)offset | (BE0 << shift_bit);
+ iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+ iowrite16(value_write, ks->hw_addr);
+}
+
+/**
+ * ks_wrreg16 - write 16bit register value to chip
+ * @ks: The chip information
+ * @offset: The register address
+ * @value: The value to write
+ *
+ */
+
+static void ks_wrreg16(struct ks_net *ks, int offset, u16 value)
+{
+ ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02));
+ iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+ iowrite16(value, ks->hw_addr);
+}
+
+/**
+ * ks_inblk - read a block of data from QMU. This is called after sudo DMA mode enabled.
+ * @ks: The chip state
+ * @wptr: buffer address to save data
+ * @len: length in byte to read
+ *
+ */
+static inline void ks_inblk(struct ks_net *ks, u16 *wptr, u32 len)
+{
+ len >>= 1;
+ while (len--)
+ *wptr++ = (u16)ioread16(ks->hw_addr);
+}
+
+/**
+ * ks_outblk - write data to QMU. This is called after sudo DMA mode enabled.
+ * @ks: The chip information
+ * @wptr: buffer address
+ * @len: length in byte to write
+ *
+ */
+static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
+{
+ len >>= 1;
+ while (len--)
+ iowrite16(*wptr++, ks->hw_addr);
+}
+
+/**
+ * ks_tx_fifo_space - return the available hardware buffer size.
+ * @ks: The chip information
+ *
+ */
+static inline u16 ks_tx_fifo_space(struct ks_net *ks)
+{
+ return ks_rdreg16(ks, KS_TXMIR) & 0x1fff;
+}
+
+/**
+ * ks_save_cmd_reg - save the command register from the cache.
+ * @ks: The chip information
+ *
+ */
+static inline void ks_save_cmd_reg(struct ks_net *ks)
+{
+ /*ks8851 MLL has a bug to read back the command register.
+ * So rely on software to save the content of command register.
+ */
+ ks->cmd_reg_cache_int = ks->cmd_reg_cache;
+}
+
+/**
+ * ks_restore_cmd_reg - restore the command register from the cache and
+ * write to hardware register.
+ * @ks: The chip information
+ *
+ */
+static inline void ks_restore_cmd_reg(struct ks_net *ks)
+{
+ ks->cmd_reg_cache = ks->cmd_reg_cache_int;
+ iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
+}
+
+/**
+ * ks_set_powermode - set power mode of the device
+ * @ks: The chip information
+ * @pwrmode: The power mode value to write to KS_PMECR.
+ *
+ * Change the power mode of the chip.
+ */
+static void ks_set_powermode(struct ks_net *ks, unsigned pwrmode)
+{
+ unsigned pmecr;
+
+ if (netif_msg_hw(ks))
+ ks_dbg(ks, "setting power mode %d\n", pwrmode);
+
+ ks_rdreg16(ks, KS_GRR);
+ pmecr = ks_rdreg16(ks, KS_PMECR);
+ pmecr &= ~PMECR_PM_MASK;
+ pmecr |= pwrmode;
+
+ ks_wrreg16(ks, KS_PMECR, pmecr);
+}
+
+/**
+ * ks_read_config - read chip configuration of bus width.
+ * @ks: The chip information
+ *
+ */
+static void ks_read_config(struct ks_net *ks)
+{
+ u16 reg_data = 0;
+
+ /* Regardless of bus width, 8 bit read should always work.*/
+ reg_data = ks_rdreg8(ks, KS_CCR) & 0x00FF;
+ reg_data |= ks_rdreg8(ks, KS_CCR+1) << 8;
+
+ /* addr/data bus are multiplexed */
+ ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED;
+
+ /* There are garbage data when reading data from QMU,
+ depending on bus-width.
+ */
+
+ if (reg_data & CCR_8BIT) {
+ ks->bus_width = ENUM_BUS_8BIT;
+ ks->extra_byte = 1;
+ } else if (reg_data & CCR_16BIT) {
+ ks->bus_width = ENUM_BUS_16BIT;
+ ks->extra_byte = 2;
+ } else {
+ ks->bus_width = ENUM_BUS_32BIT;
+ ks->extra_byte = 4;
+ }
+}
+
+/**
+ * ks_soft_reset - issue one of the soft reset to the device
+ * @ks: The device state.
+ * @op: The bit(s) to set in the GRR
+ *
+ * Issue the relevant soft-reset command to the device's GRR register
+ * specified by @op.
+ *
+ * Note, the delays are in there as a caution to ensure that the reset
+ * has time to take effect and then complete. Since the datasheet does
+ * not currently specify the exact sequence, we have chosen something
+ * that seems to work with our device.
+ */
+static void ks_soft_reset(struct ks_net *ks, unsigned op)
+{
+ /* Disable interrupt first */
+ ks_wrreg16(ks, KS_IER, 0x0000);
+ ks_wrreg16(ks, KS_GRR, op);
+ mdelay(10); /* wait a short time to effect reset */
+ ks_wrreg16(ks, KS_GRR, 0);
+ mdelay(1); /* wait for condition to clear */
+}
+
+
+/**
+ * ks_read_qmu - read 1 pkt data from the QMU.
+ * @ks: The chip information
+ * @buf: buffer address to save 1 pkt
+ * @len: Pkt length
+ * Here is the sequence to read 1 pkt:
+ * 1. set sudo DMA mode
+ * 2. read prepend data
+ * 3. read pkt data
+ * 4. reset sudo DMA Mode
+ */
+static inline void ks_read_qmu(struct ks_net *ks, u16 *buf, u32 len)
+{
+ u32 r = ks->extra_byte & 0x1 ;
+ u32 w = ks->extra_byte - r;
+
+ /* 1. set sudo DMA mode */
+ ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);
+ ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+
+ /* 2. read prepend data */
+ /**
+ * read 4 + extra bytes and discard them.
+ * extra bytes for dummy, 2 for status, 2 for len
+ */
+
+ /* use likely(r) for 8 bit access for performance */
+ if (unlikely(r))
+ ioread8(ks->hw_addr);
+ ks_inblk(ks, buf, w + 2 + 2);
+
+ /* 3. read pkt data */
+ ks_inblk(ks, buf, ALIGN(len, 4));
+
+ /* 4. reset sudo DMA Mode */
+ ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr);
+}
+
+/**
+ * ks_rcv - read multiple pkts data from the QMU.
+ * @ks: The chip information
+ * @netdev: The network device being opened.
+ *
+ * Read all of header information before reading pkt content.
+ * It is not allowed only port of pkts in QMU after issuing
+ * interrupt ack.
+ */
+static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
+{
+ u32 i;
+ struct type_frame_head *frame_hdr = ks->frame_head_info;
+ struct sk_buff *skb;
+
+ ks->frame_cnt = ks_rdreg16(ks, KS_RXFCTR) >> 8;
+
+ /* read all header information */
+ for (i = 0; i < ks->frame_cnt; i++) {
+ /* Checking Received packet status */
+ frame_hdr->sts = ks_rdreg16(ks, KS_RXFHSR);
+ /* Get packet len from hardware */
+ frame_hdr->len = ks_rdreg16(ks, KS_RXFHBCR);
+ frame_hdr++;
+ }
+
+ frame_hdr = ks->frame_head_info;
+ while (ks->frame_cnt--) {
+ skb = dev_alloc_skb(frame_hdr->len + 16);
+ if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) &&
+ (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
+ skb_reserve(skb, 2);
+ /* read data block including CRC 4 bytes */
+ ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4);
+ skb_put(skb, frame_hdr->len);
+ skb->dev = netdev;
+ skb->protocol = eth_type_trans(skb, netdev);
+ netif_rx(skb);
+ } else {
+ printk(KERN_ERR "%s: err:skb alloc\n", __func__);
+ ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
+ if (skb)
+ dev_kfree_skb_irq(skb);
+ }
+ frame_hdr++;
+ }
+}
+
+/**
+ * ks_update_link_status - link status update.
+ * @netdev: The network device being opened.
+ * @ks: The chip information
+ *
+ */
+
+static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks)
+{
+ /* check the status of the link */
+ u32 link_up_status;
+ if (ks_rdreg16(ks, KS_P1SR) & P1SR_LINK_GOOD) {
+ netif_carrier_on(netdev);
+ link_up_status = true;
+ } else {
+ netif_carrier_off(netdev);
+ link_up_status = false;
+ }
+ if (netif_msg_link(ks))
+ ks_dbg(ks, "%s: %s\n",
+ __func__, link_up_status ? "UP" : "DOWN");
+}
+
+/**
+ * ks_irq - device interrupt handler
+ * @irq: Interrupt number passed from the IRQ hnalder.
+ * @pw: The private word passed to register_irq(), our struct ks_net.
+ *
+ * This is the handler invoked to find out what happened
+ *
+ * Read the interrupt status, work out what needs to be done and then clear
+ * any of the interrupts that are not needed.
+ */
+
+static irqreturn_t ks_irq(int irq, void *pw)
+{
+ struct ks_net *ks = pw;
+ struct net_device *netdev = ks->netdev;
+ u16 status;
+
+ /*this should be the first in IRQ handler */
+ ks_save_cmd_reg(ks);
+
+ status = ks_rdreg16(ks, KS_ISR);
+ if (unlikely(!status)) {
+ ks_restore_cmd_reg(ks);
+ return IRQ_NONE;
+ }
+
+ ks_wrreg16(ks, KS_ISR, status);
+
+ if (likely(status & IRQ_RXI))
+ ks_rcv(ks, netdev);
+
+ if (unlikely(status & IRQ_LCI))
+ ks_update_link_status(netdev, ks);
+
+ if (unlikely(status & IRQ_TXI))
+ netif_wake_queue(netdev);
+
+ if (unlikely(status & IRQ_LDI)) {
+
+ u16 pmecr = ks_rdreg16(ks, KS_PMECR);
+ pmecr &= ~PMECR_WKEVT_MASK;
+ ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
+ }
+
+ /* this should be the last in IRQ handler*/
+ ks_restore_cmd_reg(ks);
+ return IRQ_HANDLED;
+}
+
+
+/**
+ * ks_net_open - open network device
+ * @netdev: The network device being opened.
+ *
+ * Called when the network device is marked active, such as a user executing
+ * 'ifconfig up' on the device.
+ */
+static int ks_net_open(struct net_device *netdev)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ int err;
+
+#define KS_INT_FLAGS (IRQF_DISABLED|IRQF_TRIGGER_LOW)
+ /* lock the card, even if we may not actually do anything
+ * else at the moment.
+ */
+
+ if (netif_msg_ifup(ks))
+ ks_dbg(ks, "%s - entry\n", __func__);
+
+ /* reset the HW */
+ err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks);
+
+ if (err) {
+ printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
+ ks->irq, err);
+ return err;
+ }
+
+ if (netif_msg_ifup(ks))
+ ks_dbg(ks, "network device %s up\n", netdev->name);
+
+ return 0;
+}
+
+/**
+ * ks_net_stop - close network device
+ * @netdev: The device being closed.
+ *
+ * Called to close down a network device which has been active. Cancell any
+ * work, shutdown the RX and TX process and then place the chip into a low
+ * power state whilst it is not being used.
+ */
+static int ks_net_stop(struct net_device *netdev)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+
+ if (netif_msg_ifdown(ks))
+ ks_info(ks, "%s: shutting down\n", netdev->name);
+
+ netif_stop_queue(netdev);
+
+ kfree(ks->frame_head_info);
+
+ mutex_lock(&ks->lock);
+
+ /* turn off the IRQs and ack any outstanding */
+ ks_wrreg16(ks, KS_IER, 0x0000);
+ ks_wrreg16(ks, KS_ISR, 0xffff);
+
+ /* shutdown RX process */
+ ks_wrreg16(ks, KS_RXCR1, 0x0000);
+
+ /* shutdown TX process */
+ ks_wrreg16(ks, KS_TXCR, 0x0000);
+
+ /* set powermode to soft power down to save power */
+ ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
+ free_irq(ks->irq, netdev);
+ mutex_unlock(&ks->lock);
+ return 0;
+}
+
+
+/**
+ * ks_write_qmu - write 1 pkt data to the QMU.
+ * @ks: The chip information
+ * @pdata: buffer address to save 1 pkt
+ * @len: Pkt length in byte
+ * Here is the sequence to write 1 pkt:
+ * 1. set sudo DMA mode
+ * 2. write status/length
+ * 3. write pkt data
+ * 4. reset sudo DMA Mode
+ * 5. reset sudo DMA mode
+ * 6. Wait until pkt is out
+ */
+static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
+{
+ unsigned fid = ks->fid;
+
+ fid = ks->fid;
+ ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK;
+
+ /* reduce the tx interrupt occurrances. */
+ if (!fid)
+ fid |= TXFR_TXIC; /* irq on completion */
+
+ /* start header at txb[0] to align txw entries */
+ ks->txh.txw[0] = cpu_to_le16(fid);
+ ks->txh.txw[1] = cpu_to_le16(len);
+
+ /* 1. set sudo-DMA mode */
+ ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+ /* 2. write status/lenth info */
+ ks_outblk(ks, ks->txh.txw, 4);
+ /* 3. write pkt data */
+ ks_outblk(ks, (u16 *)pdata, ALIGN(len, 4));
+ /* 4. reset sudo-DMA mode */
+ ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr);
+ /* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */
+ ks_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
+ /* 6. wait until TXQCR_METFE is auto-cleared */
+ while (ks_rdreg16(ks, KS_TXQCR) & TXQCR_METFE)
+ ;
+}
+
+static void ks_disable_int(struct ks_net *ks)
+{
+ ks_wrreg16(ks, KS_IER, 0x0000);
+} /* ks_disable_int */
+
+static void ks_enable_int(struct ks_net *ks)
+{
+ ks_wrreg16(ks, KS_IER, ks->rc_ier);
+} /* ks_enable_int */
+
+/**
+ * ks_start_xmit - transmit packet
+ * @skb : The buffer to transmit
+ * @netdev : The device used to transmit the packet.
+ *
+ * Called by the network layer to transmit the @skb.
+ * spin_lock_irqsave is required because tx and rx should be mutual exclusive.
+ * So while tx is in-progress, prevent IRQ interrupt from happenning.
+ */
+static int ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ int retv = NETDEV_TX_OK;
+ struct ks_net *ks = netdev_priv(netdev);
+
+ disable_irq(netdev->irq);
+ ks_disable_int(ks);
+ spin_lock(&ks->statelock);
+
+ /* Extra space are required:
+ * 4 byte for alignment, 4 for status/length, 4 for CRC
+ */
+
+ if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) {
+ ks_write_qmu(ks, skb->data, skb->len);
+ dev_kfree_skb(skb);
+ } else
+ retv = NETDEV_TX_BUSY;
+ spin_unlock(&ks->statelock);
+ ks_enable_int(ks);
+ enable_irq(netdev->irq);
+ return retv;
+}
+
+/**
+ * ks_start_rx - ready to serve pkts
+ * @ks : The chip information
+ *
+ */
+static void ks_start_rx(struct ks_net *ks)
+{
+ u16 cntl;
+
+ /* Enables QMU Receive (RXCR1). */
+ cntl = ks_rdreg16(ks, KS_RXCR1);
+ cntl |= RXCR1_RXE ;
+ ks_wrreg16(ks, KS_RXCR1, cntl);
+} /* ks_start_rx */
+
+/**
+ * ks_stop_rx - stop to serve pkts
+ * @ks : The chip information
+ *
+ */
+static void ks_stop_rx(struct ks_net *ks)
+{
+ u16 cntl;
+
+ /* Disables QMU Receive (RXCR1). */
+ cntl = ks_rdreg16(ks, KS_RXCR1);
+ cntl &= ~RXCR1_RXE ;
+ ks_wrreg16(ks, KS_RXCR1, cntl);
+
+} /* ks_stop_rx */
+
+static unsigned long const ethernet_polynomial = 0x04c11db7U;
+
+static unsigned long ether_gen_crc(int length, u8 *data)
+{
+ long crc = -1;
+ while (--length >= 0) {
+ u8 current_octet = *data++;
+ int bit;
+
+ for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+ crc = (crc << 1) ^
+ ((crc < 0) ^ (current_octet & 1) ?
+ ethernet_polynomial : 0);
+ }
+ }
+ return (unsigned long)crc;
+} /* ether_gen_crc */
+
+/**
+* ks_set_grpaddr - set multicast information
+* @ks : The chip information
+*/
+
+static void ks_set_grpaddr(struct ks_net *ks)
+{
+ u8 i;
+ u32 index, position, value;
+
+ memset(ks->mcast_bits, 0, sizeof(u8) * HW_MCAST_SIZE);
+
+ for (i = 0; i < ks->mcast_lst_size; i++) {
+ position = (ether_gen_crc(6, ks->mcast_lst[i]) >> 26) & 0x3f;
+ index = position >> 3;
+ value = 1 << (position & 7);
+ ks->mcast_bits[index] |= (u8)value;
+ }
+
+ for (i = 0; i < HW_MCAST_SIZE; i++) {
+ if (i & 1) {
+ ks_wrreg16(ks, (u16)((KS_MAHTR0 + i) & ~1),
+ (ks->mcast_bits[i] << 8) |
+ ks->mcast_bits[i - 1]);
+ }
+ }
+} /* ks_set_grpaddr */
+
+/*
+* ks_clear_mcast - clear multicast information
+*
+* @ks : The chip information
+* This routine removes all mcast addresses set in the hardware.
+*/
+
+static void ks_clear_mcast(struct ks_net *ks)
+{
+ u16 i, mcast_size;
+ for (i = 0; i < HW_MCAST_SIZE; i++)
+ ks->mcast_bits[i] = 0;
+
+ mcast_size = HW_MCAST_SIZE >> 2;
+ for (i = 0; i < mcast_size; i++)
+ ks_wrreg16(ks, KS_MAHTR0 + (2*i), 0);
+}
+
+static void ks_set_promis(struct ks_net *ks, u16 promiscuous_mode)
+{
+ u16 cntl;
+ ks->promiscuous = promiscuous_mode;
+ ks_stop_rx(ks); /* Stop receiving for reconfiguration */
+ cntl = ks_rdreg16(ks, KS_RXCR1);
+
+ cntl &= ~RXCR1_FILTER_MASK;
+ if (promiscuous_mode)
+ /* Enable Promiscuous mode */
+ cntl |= RXCR1_RXAE | RXCR1_RXINVF;
+ else
+ /* Disable Promiscuous mode (default normal mode) */
+ cntl |= RXCR1_RXPAFMA;
+
+ ks_wrreg16(ks, KS_RXCR1, cntl);
+
+ if (ks->enabled)
+ ks_start_rx(ks);
+
+} /* ks_set_promis */
+
+static void ks_set_mcast(struct ks_net *ks, u16 mcast)
+{
+ u16 cntl;
+
+ ks->all_mcast = mcast;
+ ks_stop_rx(ks); /* Stop receiving for reconfiguration */
+ cntl = ks_rdreg16(ks, KS_RXCR1);
+ cntl &= ~RXCR1_FILTER_MASK;
+ if (mcast)
+ /* Enable "Perfect with Multicast address passed mode" */
+ cntl |= (RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA);
+ else
+ /**
+ * Disable "Perfect with Multicast address passed
+ * mode" (normal mode).
+ */
+ cntl |= RXCR1_RXPAFMA;
+
+ ks_wrreg16(ks, KS_RXCR1, cntl);
+
+ if (ks->enabled)
+ ks_start_rx(ks);
+} /* ks_set_mcast */
+
+static void ks_set_rx_mode(struct net_device *netdev)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ struct dev_mc_list *ptr;
+
+ /* Turn on/off promiscuous mode. */
+ if ((netdev->flags & IFF_PROMISC) == IFF_PROMISC)
+ ks_set_promis(ks,
+ (u16)((netdev->flags & IFF_PROMISC) == IFF_PROMISC));
+ /* Turn on/off all mcast mode. */
+ else if ((netdev->flags & IFF_ALLMULTI) == IFF_ALLMULTI)
+ ks_set_mcast(ks,
+ (u16)((netdev->flags & IFF_ALLMULTI) == IFF_ALLMULTI));
+ else
+ ks_set_promis(ks, false);
+
+ if ((netdev->flags & IFF_MULTICAST) && netdev->mc_count) {
+ if (netdev->mc_count <= MAX_MCAST_LST) {
+ int i = 0;
+ for (ptr = netdev->mc_list; ptr; ptr = ptr->next) {
+ if (!(*ptr->dmi_addr & 1))
+ continue;
+ if (i >= MAX_MCAST_LST)
+ break;
+ memcpy(ks->mcast_lst[i++], ptr->dmi_addr,
+ MAC_ADDR_LEN);
+ }
+ ks->mcast_lst_size = (u8)i;
+ ks_set_grpaddr(ks);
+ } else {
+ /**
+ * List too big to support so
+ * turn on all mcast mode.
+ */
+ ks->mcast_lst_size = MAX_MCAST_LST;
+ ks_set_mcast(ks, true);
+ }
+ } else {
+ ks->mcast_lst_size = 0;
+ ks_clear_mcast(ks);
+ }
+} /* ks_set_rx_mode */
+
+static void ks_set_mac(struct ks_net *ks, u8 *data)
+{
+ u16 *pw = (u16 *)data;
+ u16 w, u;
+
+ ks_stop_rx(ks); /* Stop receiving for reconfiguration */
+
+ u = *pw++;
+ w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
+ ks_wrreg16(ks, KS_MARH, w);
+
+ u = *pw++;
+ w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
+ ks_wrreg16(ks, KS_MARM, w);
+
+ u = *pw;
+ w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
+ ks_wrreg16(ks, KS_MARL, w);
+
+ memcpy(ks->mac_addr, data, 6);
+
+ if (ks->enabled)
+ ks_start_rx(ks);
+}
+
+static int ks_set_mac_address(struct net_device *netdev, void *paddr)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ struct sockaddr *addr = paddr;
+ u8 *da;
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
+ da = (u8 *)netdev->dev_addr;
+
+ ks_set_mac(ks, da);
+ return 0;
+}
+
+static int ks_net_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+
+ if (!netif_running(netdev))
+ return -EINVAL;
+
+ return generic_mii_ioctl(&ks->mii, if_mii(req), cmd, NULL);
+}
+
+static const struct net_device_ops ks_netdev_ops = {
+ .ndo_open = ks_net_open,
+ .ndo_stop = ks_net_stop,
+ .ndo_do_ioctl = ks_net_ioctl,
+ .ndo_start_xmit = ks_start_xmit,
+ .ndo_set_mac_address = ks_set_mac_address,
+ .ndo_set_rx_mode = ks_set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+/* ethtool support */
+
+static void ks_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *di)
+{
+ strlcpy(di->driver, DRV_NAME, sizeof(di->driver));
+ strlcpy(di->version, "1.00", sizeof(di->version));
+ strlcpy(di->bus_info, dev_name(netdev->dev.parent),
+ sizeof(di->bus_info));
+}
+
+static u32 ks_get_msglevel(struct net_device *netdev)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ return ks->msg_enable;
+}
+
+static void ks_set_msglevel(struct net_device *netdev, u32 to)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ ks->msg_enable = to;
+}
+
+static int ks_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ return mii_ethtool_gset(&ks->mii, cmd);
+}
+
+static int ks_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ return mii_ethtool_sset(&ks->mii, cmd);
+}
+
+static u32 ks_get_link(struct net_device *netdev)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ return mii_link_ok(&ks->mii);
+}
+
+static int ks_nway_reset(struct net_device *netdev)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ return mii_nway_restart(&ks->mii);
+}
+
+static const struct ethtool_ops ks_ethtool_ops = {
+ .get_drvinfo = ks_get_drvinfo,
+ .get_msglevel = ks_get_msglevel,
+ .set_msglevel = ks_set_msglevel,
+ .get_settings = ks_get_settings,
+ .set_settings = ks_set_settings,
+ .get_link = ks_get_link,
+ .nway_reset = ks_nway_reset,
+};
+
+/* MII interface controls */
+
+/**
+ * ks_phy_reg - convert MII register into a KS8851 register
+ * @reg: MII register number.
+ *
+ * Return the KS8851 register number for the corresponding MII PHY register
+ * if possible. Return zero if the MII register has no direct mapping to the
+ * KS8851 register set.
+ */
+static int ks_phy_reg(int reg)
+{
+ switch (reg) {
+ case MII_BMCR:
+ return KS_P1MBCR;
+ case MII_BMSR:
+ return KS_P1MBSR;
+ case MII_PHYSID1:
+ return KS_PHY1ILR;
+ case MII_PHYSID2:
+ return KS_PHY1IHR;
+ case MII_ADVERTISE:
+ return KS_P1ANAR;
+ case MII_LPA:
+ return KS_P1ANLPR;
+ }
+
+ return 0x0;
+}
+
+/**
+ * ks_phy_read - MII interface PHY register read.
+ * @netdev: The network device the PHY is on.
+ * @phy_addr: Address of PHY (ignored as we only have one)
+ * @reg: The register to read.
+ *
+ * This call reads data from the PHY register specified in @reg. Since the
+ * device does not support all the MII registers, the non-existant values
+ * are always returned as zero.
+ *
+ * We return zero for unsupported registers as the MII code does not check
+ * the value returned for any error status, and simply returns it to the
+ * caller. The mii-tool that the driver was tested with takes any -ve error
+ * as real PHY capabilities, thus displaying incorrect data to the user.
+ */
+static int ks_phy_read(struct net_device *netdev, int phy_addr, int reg)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ int ksreg;
+ int result;
+
+ ksreg = ks_phy_reg(reg);
+ if (!ksreg)
+ return 0x0; /* no error return allowed, so use zero */
+
+ mutex_lock(&ks->lock);
+ result = ks_rdreg16(ks, ksreg);
+ mutex_unlock(&ks->lock);
+
+ return result;
+}
+
+static void ks_phy_write(struct net_device *netdev,
+ int phy, int reg, int value)
+{
+ struct ks_net *ks = netdev_priv(netdev);
+ int ksreg;
+
+ ksreg = ks_phy_reg(reg);
+ if (ksreg) {
+ mutex_lock(&ks->lock);
+ ks_wrreg16(ks, ksreg, value);
+ mutex_unlock(&ks->lock);
+ }
+}
+
+/**
+ * ks_read_selftest - read the selftest memory info.
+ * @ks: The device state
+ *
+ * Read and check the TX/RX memory selftest information.
+ */
+static int ks_read_selftest(struct ks_net *ks)
+{
+ unsigned both_done = MBIR_TXMBF | MBIR_RXMBF;
+ int ret = 0;
+ unsigned rd;
+
+ rd = ks_rdreg16(ks, KS_MBIR);
+
+ if ((rd & both_done) != both_done) {
+ ks_warn(ks, "Memory selftest not finished\n");
+ return 0;
+ }
+
+ if (rd & MBIR_TXMBFA) {
+ ks_err(ks, "TX memory selftest fails\n");
+ ret |= 1;
+ }
+
+ if (rd & MBIR_RXMBFA) {
+ ks_err(ks, "RX memory selftest fails\n");
+ ret |= 2;
+ }
+
+ ks_info(ks, "the selftest passes\n");
+ return ret;
+}
+
+static void ks_disable(struct ks_net *ks)
+{
+ u16 w;
+
+ w = ks_rdreg16(ks, KS_TXCR);
+
+ /* Disables QMU Transmit (TXCR). */
+ w &= ~TXCR_TXE;
+ ks_wrreg16(ks, KS_TXCR, w);
+
+ /* Disables QMU Receive (RXCR1). */
+ w = ks_rdreg16(ks, KS_RXCR1);
+ w &= ~RXCR1_RXE ;
+ ks_wrreg16(ks, KS_RXCR1, w);
+
+ ks->enabled = false;
+
+} /* ks_disable */
+
+static void ks_setup(struct ks_net *ks)
+{
+ u16 w;
+
+ /**
+ * Configure QMU Transmit
+ */
+
+ /* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */
+ ks_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI);
+
+ /* Setup Receive Frame Data Pointer Auto-Increment */
+ ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);
+
+ /* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */
+ ks_wrreg16(ks, KS_RXFCTR, 1 & RXFCTR_THRESHOLD_MASK);
+
+ /* Setup RxQ Command Control (RXQCR) */
+ ks->rc_rxqcr = RXQCR_CMD_CNTL;
+ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
+
+ /**
+ * set the force mode to half duplex, default is full duplex
+ * because if the auto-negotiation fails, most switch uses
+ * half-duplex.
+ */
+
+ w = ks_rdreg16(ks, KS_P1MBCR);
+ w &= ~P1MBCR_FORCE_FDX;
+ ks_wrreg16(ks, KS_P1MBCR, w);
+
+ w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
+ ks_wrreg16(ks, KS_TXCR, w);
+
+ w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE;
+
+ if (ks->promiscuous) /* bPromiscuous */
+ w |= (RXCR1_RXAE | RXCR1_RXINVF);
+ else if (ks->all_mcast) /* Multicast address passed mode */
+ w |= (RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA);
+ else /* Normal mode */
+ w |= RXCR1_RXPAFMA;
+
+ ks_wrreg16(ks, KS_RXCR1, w);
+} /*ks_setup */
+
+
+static void ks_setup_int(struct ks_net *ks)
+{
+ ks->rc_ier = 0x00;
+ /* Clear the interrupts status of the hardware. */
+ ks_wrreg16(ks, KS_ISR, 0xffff);
+
+ /* Enables the interrupts of the hardware. */
+ ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
+} /* ks_setup_int */
+
+void ks_enable(struct ks_net *ks)
+{
+ u16 w;
+
+ w = ks_rdreg16(ks, KS_TXCR);
+ /* Enables QMU Transmit (TXCR). */
+ ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
+
+ /*
+ * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
+ * Enable
+ */
+
+ w = ks_rdreg16(ks, KS_RXQCR);
+ ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
+
+ /* Enables QMU Receive (RXCR1). */
+ w = ks_rdreg16(ks, KS_RXCR1);
+ ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
+ ks->enabled = true;
+} /* ks_enable */
+
+static int ks_hw_init(struct ks_net *ks)
+{
+#define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES)
+ ks->promiscuous = 0;
+ ks->all_mcast = 0;
+ ks->mcast_lst_size = 0;
+
+ ks->frame_head_info = (struct type_frame_head *) \
+ kmalloc(MHEADER_SIZE, GFP_KERNEL);
+ if (!ks->frame_head_info) {
+ printk(KERN_ERR "Error: Fail to allocate frame memory\n");
+ return false;
+ }
+
+ ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS);
+ return true;
+}
+
+
+static int __devinit ks8851_probe(struct platform_device *pdev)
+{
+ int err = -ENOMEM;
+ struct resource *io_d, *io_c;
+ struct net_device *netdev;
+ struct ks_net *ks;
+ u16 id, data;
+
+ io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+
+ if (!request_mem_region(io_d->start, resource_size(io_d), DRV_NAME))
+ goto err_mem_region;
+
+ if (!request_mem_region(io_c->start, resource_size(io_c), DRV_NAME))
+ goto err_mem_region1;
+
+ netdev = alloc_etherdev(sizeof(struct ks_net));
+ if (!netdev)
+ goto err_alloc_etherdev;
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ ks = netdev_priv(netdev);
+ ks->netdev = netdev;
+ ks->hw_addr = ioremap(io_d->start, resource_size(io_d));
+
+ if (!ks->hw_addr)
+ goto err_ioremap;
+
+ ks->hw_addr_cmd = ioremap(io_c->start, resource_size(io_c));
+ if (!ks->hw_addr_cmd)
+ goto err_ioremap1;
+
+ ks->irq = platform_get_irq(pdev, 0);
+
+ if (ks->irq < 0) {
+ err = ks->irq;
+ goto err_get_irq;
+ }
+
+ ks->pdev = pdev;
+
+ mutex_init(&ks->lock);
+ spin_lock_init(&ks->statelock);
+
+ netdev->netdev_ops = &ks_netdev_ops;
+ netdev->ethtool_ops = &ks_ethtool_ops;
+
+ /* setup mii state */
+ ks->mii.dev = netdev;
+ ks->mii.phy_id = 1,
+ ks->mii.phy_id_mask = 1;
+ ks->mii.reg_num_mask = 0xf;
+ ks->mii.mdio_read = ks_phy_read;
+ ks->mii.mdio_write = ks_phy_write;
+
+ ks_info(ks, "message enable is %d\n", msg_enable);
+ /* set the default message enable */
+ ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV |
+ NETIF_MSG_PROBE |
+ NETIF_MSG_LINK));
+ ks_read_config(ks);
+
+ /* simple check for a valid chip being connected to the bus */
+ if ((ks_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
+ ks_err(ks, "failed to read device ID\n");
+ err = -ENODEV;
+ goto err_register;
+ }
+
+ if (ks_read_selftest(ks)) {
+ ks_err(ks, "failed to read device ID\n");
+ err = -ENODEV;
+ goto err_register;
+ }
+
+ err = register_netdev(netdev);
+ if (err)
+ goto err_register;
+
+ platform_set_drvdata(pdev, netdev);
+
+ ks_soft_reset(ks, GRR_GSR);
+ ks_hw_init(ks);
+ ks_disable(ks);
+ ks_setup(ks);
+ ks_setup_int(ks);
+ ks_enable_int(ks);
+ ks_enable(ks);
+ memcpy(netdev->dev_addr, ks->mac_addr, 6);
+
+ data = ks_rdreg16(ks, KS_OBCR);
+ ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA);
+
+ /**
+ * If you want to use the default MAC addr,
+ * comment out the 2 functions below.
+ */
+
+ random_ether_addr(netdev->dev_addr);
+ ks_set_mac(ks, netdev->dev_addr);
+
+ id = ks_rdreg16(ks, KS_CIDER);
+
+ printk(KERN_INFO DRV_NAME
+ " Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n",
+ (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);
+ return 0;
+
+err_register:
+err_get_irq:
+ iounmap(ks->hw_addr_cmd);
+err_ioremap1:
+ iounmap(ks->hw_addr);
+err_ioremap:
+ free_netdev(netdev);
+err_alloc_etherdev:
+ release_mem_region(io_c->start, resource_size(io_c));
+err_mem_region1:
+ release_mem_region(io_d->start, resource_size(io_d));
+err_mem_region:
+ return err;
+}
+
+static int __devexit ks8851_remove(struct platform_device *pdev)
+{
+ struct net_device *netdev = platform_get_drvdata(pdev);
+ struct ks_net *ks = netdev_priv(netdev);
+ struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ unregister_netdev(netdev);
+ iounmap(ks->hw_addr);
+ free_netdev(netdev);
+ release_mem_region(iomem->start, resource_size(iomem));
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+
+}
+
+static struct platform_driver ks8851_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = ks8851_probe,
+ .remove = __devexit_p(ks8851_remove),
+};
+
+static int __init ks8851_init(void)
+{
+ return platform_driver_register(&ks8851_platform_driver);
+}
+
+static void __exit ks8851_exit(void)
+{
+ platform_driver_unregister(&ks8851_platform_driver);
+}
+
+module_init(ks8851_init);
+module_exit(ks8851_exit);
+
+MODULE_DESCRIPTION("KS8851 MLL Network driver");
+MODULE_AUTHOR("David Choi <david.choi@micrel.com>");
+MODULE_LICENSE("GPL");
+module_param_named(message, msg_enable, int, 0);
+MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)");
+
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 92ceb689b4d..2af81735386 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -828,7 +828,7 @@ static int __exit meth_remove(struct platform_device *pdev)
static struct platform_driver meth_driver = {
.probe = meth_probe,
- .remove = __devexit_p(meth_remove),
+ .remove = __exit_p(meth_remove),
.driver = {
.name = "meth",
.owner = THIS_MODULE,
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 3dd481e77f9..5dd7225b178 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -1282,6 +1282,7 @@ static struct pci_device_id mlx4_pci_table[] = {
{ PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */
{ PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
{ PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/
+ { PCI_VDEVICE(MELLANOX, 0x676e) }, /* MT26478 ConnectX2 40GigE PCIe gen2 */
{ 0, }
};
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index b5aa974827e..9b9eab10770 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1714,7 +1714,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* 4 fragments per cmd des */
no_of_desc = (frag_count + 3) >> 2;
- if (unlikely(no_of_desc + 2) > netxen_tx_avail(tx_ring)) {
+ if (unlikely(no_of_desc + 2 > netxen_tx_avail(tx_ring))) {
netif_stop_queue(netdev);
return NETDEV_TX_BUSY;
}
diff --git a/drivers/net/pasemi_mac_ethtool.c b/drivers/net/pasemi_mac_ethtool.c
index 064a4fe1dd9..28a86224879 100644
--- a/drivers/net/pasemi_mac_ethtool.c
+++ b/drivers/net/pasemi_mac_ethtool.c
@@ -71,6 +71,9 @@ pasemi_mac_ethtool_get_settings(struct net_device *netdev,
struct pasemi_mac *mac = netdev_priv(netdev);
struct phy_device *phydev = mac->phydev;
+ if (!phydev)
+ return -EOPNOTSUPP;
+
return phy_ethtool_gset(phydev, cmd);
}
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 474876c879c..bd3447f0490 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1754,14 +1754,14 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
- PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
- PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "tamarack.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b),
PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0",
0xb4be14e3, 0x43ac239b, 0x0877b627),
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index cc394d07375..5910df60c93 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -2179,7 +2179,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
* session or the special tunnel type.
*/
static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct pppol2tp_session *session = sk->sk_user_data;
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index a9845a2f243..3ec6e85587a 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -9,6 +9,7 @@
#include <linux/pci.h>
#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
/*
* General definitions...
@@ -135,9 +136,9 @@ enum {
RST_FO_TFO = (1 << 0),
RST_FO_RR_MASK = 0x00060000,
RST_FO_RR_CQ_CAM = 0x00000000,
- RST_FO_RR_DROP = 0x00000001,
- RST_FO_RR_DQ = 0x00000002,
- RST_FO_RR_RCV_FUNC_CQ = 0x00000003,
+ RST_FO_RR_DROP = 0x00000002,
+ RST_FO_RR_DQ = 0x00000004,
+ RST_FO_RR_RCV_FUNC_CQ = 0x00000006,
RST_FO_FRB = (1 << 12),
RST_FO_MOP = (1 << 13),
RST_FO_REG = (1 << 14),
@@ -1381,15 +1382,15 @@ struct intr_context {
/* adapter flags definitions. */
enum {
- QL_ADAPTER_UP = (1 << 0), /* Adapter has been brought up. */
- QL_LEGACY_ENABLED = (1 << 3),
- QL_MSI_ENABLED = (1 << 3),
- QL_MSIX_ENABLED = (1 << 4),
- QL_DMA64 = (1 << 5),
- QL_PROMISCUOUS = (1 << 6),
- QL_ALLMULTI = (1 << 7),
- QL_PORT_CFG = (1 << 8),
- QL_CAM_RT_SET = (1 << 9),
+ QL_ADAPTER_UP = 0, /* Adapter has been brought up. */
+ QL_LEGACY_ENABLED = 1,
+ QL_MSI_ENABLED = 2,
+ QL_MSIX_ENABLED = 3,
+ QL_DMA64 = 4,
+ QL_PROMISCUOUS = 5,
+ QL_ALLMULTI = 6,
+ QL_PORT_CFG = 7,
+ QL_CAM_RT_SET = 8,
};
/* link_status bit definitions */
@@ -1477,7 +1478,6 @@ struct ql_adapter {
u32 mailbox_in;
u32 mailbox_out;
struct mbox_params idc_mbc;
- struct mutex mpi_mutex;
int tx_ring_size;
int rx_ring_size;
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 68f9bd280f8..52073946bce 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -45,7 +45,6 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
if (!netif_running(qdev->ndev))
return status;
- spin_lock(&qdev->hw_lock);
/* Skip the default queue, and update the outbound handler
* queues if they changed.
*/
@@ -92,7 +91,6 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
}
}
exit:
- spin_unlock(&qdev->hw_lock);
return status;
}
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 7783c5db81d..61680715cde 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -34,7 +34,6 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/skbuff.h>
-#include <linux/rtnetlink.h>
#include <linux/if_vlan.h>
#include <linux/delay.h>
#include <linux/mm.h>
@@ -1926,12 +1925,10 @@ static void ql_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
if (status)
return;
- spin_lock(&qdev->hw_lock);
if (ql_set_mac_addr_reg
(qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n");
}
- spin_unlock(&qdev->hw_lock);
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
@@ -1945,12 +1942,10 @@ static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
if (status)
return;
- spin_lock(&qdev->hw_lock);
if (ql_set_mac_addr_reg
(qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n");
}
- spin_unlock(&qdev->hw_lock);
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
@@ -2001,15 +1996,17 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
/*
* Check MPI processor activity.
*/
- if (var & STS_PI) {
+ if ((var & STS_PI) &&
+ (ql_read32(qdev, INTR_MASK) & INTR_MASK_PI)) {
/*
* We've got an async event or mailbox completion.
* Handle it and clear the source of the interrupt.
*/
QPRINTK(qdev, INTR, ERR, "Got MPI processor interrupt.\n");
ql_disable_completion_interrupt(qdev, intr_context->intr);
- queue_delayed_work_on(smp_processor_id(), qdev->workqueue,
- &qdev->mpi_work, 0);
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+ queue_delayed_work_on(smp_processor_id(),
+ qdev->workqueue, &qdev->mpi_work, 0);
work_done++;
}
@@ -3142,14 +3139,14 @@ static int ql_route_initialize(struct ql_adapter *qdev)
{
int status = 0;
- status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ /* Clear all the entries in the routing table. */
+ status = ql_clear_routing_entries(qdev);
if (status)
return status;
- /* Clear all the entries in the routing table. */
- status = ql_clear_routing_entries(qdev);
+ status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
if (status)
- goto exit;
+ return status;
status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1);
if (status) {
@@ -3380,12 +3377,10 @@ static int ql_adapter_down(struct ql_adapter *qdev)
ql_free_rx_buffers(qdev);
- spin_lock(&qdev->hw_lock);
status = ql_adapter_reset(qdev);
if (status)
QPRINTK(qdev, IFDOWN, ERR, "reset(func #%d) FAILED!\n",
qdev->func);
- spin_unlock(&qdev->hw_lock);
return status;
}
@@ -3587,7 +3582,6 @@ static void qlge_set_multicast_list(struct net_device *ndev)
status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
if (status)
return;
- spin_lock(&qdev->hw_lock);
/*
* Set or clear promiscuous mode if a
* transition is taking place.
@@ -3664,7 +3658,6 @@ static void qlge_set_multicast_list(struct net_device *ndev)
}
}
exit:
- spin_unlock(&qdev->hw_lock);
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
}
@@ -3684,10 +3677,8 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
if (status)
return status;
- spin_lock(&qdev->hw_lock);
status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
- spin_unlock(&qdev->hw_lock);
if (status)
QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
@@ -3705,7 +3696,7 @@ static void ql_asic_reset_work(struct work_struct *work)
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, asic_reset_work.work);
int status;
-
+ rtnl_lock();
status = ql_adapter_down(qdev);
if (status)
goto error;
@@ -3713,12 +3704,12 @@ static void ql_asic_reset_work(struct work_struct *work)
status = ql_adapter_up(qdev);
if (status)
goto error;
-
+ rtnl_unlock();
return;
error:
QPRINTK(qdev, IFUP, ALERT,
"Driver up/down cycle failed, closing device\n");
- rtnl_lock();
+
set_bit(QL_ADAPTER_UP, &qdev->flags);
dev_close(qdev->ndev);
rtnl_unlock();
@@ -3834,11 +3825,14 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
return err;
}
+ qdev->ndev = ndev;
+ qdev->pdev = pdev;
+ pci_set_drvdata(pdev, ndev);
pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (pos <= 0) {
dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, "
"aborting.\n");
- goto err_out;
+ return pos;
} else {
pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16);
val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
@@ -3851,7 +3845,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
dev_err(&pdev->dev, "PCI region request failed.\n");
- goto err_out;
+ return err;
}
pci_set_master(pdev);
@@ -3869,7 +3863,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
goto err_out;
}
- pci_set_drvdata(pdev, ndev);
qdev->reg_base =
ioremap_nocache(pci_resource_start(pdev, 1),
pci_resource_len(pdev, 1));
@@ -3889,8 +3882,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
goto err_out;
}
- qdev->ndev = ndev;
- qdev->pdev = pdev;
err = ql_get_board_info(qdev);
if (err) {
dev_err(&pdev->dev, "Register access failed.\n");
@@ -3930,7 +3921,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work);
INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
- mutex_init(&qdev->mpi_mutex);
init_completion(&qdev->ide_completion);
if (!cards_found) {
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 6685bd97da9..c2e43073047 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -472,7 +472,6 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int status, count;
- mutex_lock(&qdev->mpi_mutex);
/* Begin polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -541,7 +540,6 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
status = -EIO;
}
end:
- mutex_unlock(&qdev->mpi_mutex);
/* End polled mode for MPI */
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
return status;
@@ -776,7 +774,9 @@ static int ql_idc_wait(struct ql_adapter *qdev)
static int ql_set_port_cfg(struct ql_adapter *qdev)
{
int status;
+ rtnl_lock();
status = ql_mb_set_port_cfg(qdev);
+ rtnl_unlock();
if (status)
return status;
status = ql_idc_wait(qdev);
@@ -797,7 +797,9 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
int status;
+ rtnl_lock();
status = ql_mb_get_port_cfg(qdev);
+ rtnl_unlock();
if (status) {
QPRINTK(qdev, DRV, ERR,
"Bug: Failed to get port config data.\n");
@@ -855,7 +857,9 @@ void ql_mpi_idc_work(struct work_struct *work)
* needs to be set.
* */
set_bit(QL_CAM_RT_SET, &qdev->flags);
+ rtnl_lock();
status = ql_mb_idc_ack(qdev);
+ rtnl_unlock();
if (status) {
QPRINTK(qdev, DRV, ERR,
"Bug: No pending IDC!\n");
@@ -871,7 +875,7 @@ void ql_mpi_work(struct work_struct *work)
struct mbox_params *mbcp = &mbc;
int err = 0;
- mutex_lock(&qdev->mpi_mutex);
+ rtnl_lock();
while (ql_read32(qdev, STS) & STS_PI) {
memset(mbcp, 0, sizeof(struct mbox_params));
@@ -884,7 +888,7 @@ void ql_mpi_work(struct work_struct *work)
break;
}
- mutex_unlock(&qdev->mpi_mutex);
+ rtnl_unlock();
ql_enable_completion_interrupt(qdev, 0);
}
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index ecf3279fbef..f4dfd1f679a 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -826,7 +826,7 @@ static int __exit sgiseeq_remove(struct platform_device *pdev)
static struct platform_driver sgiseeq_driver = {
.probe = sgiseeq_probe,
- .remove = __devexit_p(sgiseeq_remove),
+ .remove = __exit_p(sgiseeq_remove),
.driver = {
.name = "sgiseeq",
.owner = THIS_MODULE,
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 55bad408196..01f6811f132 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3935,11 +3935,14 @@ static int __devinit skge_probe(struct pci_dev *pdev,
#endif
err = -ENOMEM;
- hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+ /* space for skge@pci:0000:04:00.0 */
+ hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:" )
+ + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
if (!hw) {
dev_err(&pdev->dev, "cannot allocate hardware struct\n");
goto err_out_free_regions;
}
+ sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
hw->pdev = pdev;
spin_lock_init(&hw->hw_lock);
@@ -3974,7 +3977,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
goto err_out_free_netdev;
}
- err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, dev->name, hw);
+ err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, hw->irq_name, hw);
if (err) {
dev_err(&pdev->dev, "%s: cannot assign irq %d\n",
dev->name, pdev->irq);
@@ -3982,14 +3985,17 @@ static int __devinit skge_probe(struct pci_dev *pdev,
}
skge_show_addr(dev);
- if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) {
- if (register_netdev(dev1) == 0)
+ if (hw->ports > 1) {
+ dev1 = skge_devinit(hw, 1, using_dac);
+ if (dev1 && register_netdev(dev1) == 0)
skge_show_addr(dev1);
else {
/* Failure to register second port need not be fatal */
dev_warn(&pdev->dev, "register of second port failed\n");
hw->dev[1] = NULL;
- free_netdev(dev1);
+ hw->ports = 1;
+ if (dev1)
+ free_netdev(dev1);
}
}
pci_set_drvdata(pdev, hw);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 17caccbb768..831de1b6e96 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -2423,6 +2423,8 @@ struct skge_hw {
u16 phy_addr;
spinlock_t phy_lock;
struct tasklet_struct phy_task;
+
+ char irq_name[0]; /* skge@pci:000:04:00.0 */
};
enum pause_control {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index ef1165718dd..2ab5c39f33c 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -4487,13 +4487,16 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
err = -ENOMEM;
- hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+
+ hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:")
+ + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
if (!hw) {
dev_err(&pdev->dev, "cannot allocate hardware struct\n");
goto err_out_free_regions;
}
hw->pdev = pdev;
+ sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
if (!hw->regs) {
@@ -4539,7 +4542,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
err = request_irq(pdev->irq, sky2_intr,
(hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
- dev->name, hw);
+ hw->irq_name, hw);
if (err) {
dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
goto err_out_unregister;
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index e0f23a10104..ed54129698b 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2085,6 +2085,8 @@ struct sky2_hw {
struct timer_list watchdog_timer;
struct work_struct restart_work;
wait_queue_head_t msi_wait;
+
+ char irq_name[0];
};
static inline int sky2_is_copper(const struct sky2_hw *hw)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index f09bc5dfe8b..ba5d3fe753b 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -902,11 +902,12 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
struct tg3 *tp = bp->priv;
u32 val;
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
- return -EAGAIN;
+ spin_lock_bh(&tp->lock);
if (tg3_readphy(tp, reg, &val))
- return -EIO;
+ val = -EIO;
+
+ spin_unlock_bh(&tp->lock);
return val;
}
@@ -914,14 +915,16 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
{
struct tg3 *tp = bp->priv;
+ u32 ret = 0;
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
- return -EAGAIN;
+ spin_lock_bh(&tp->lock);
if (tg3_writephy(tp, reg, val))
- return -EIO;
+ ret = -EIO;
- return 0;
+ spin_unlock_bh(&tp->lock);
+
+ return ret;
}
static int tg3_mdio_reset(struct mii_bus *bp)
@@ -1011,12 +1014,6 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
static void tg3_mdio_start(struct tg3 *tp)
{
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
- mutex_lock(&tp->mdio_bus->mdio_lock);
- tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
- mutex_unlock(&tp->mdio_bus->mdio_lock);
- }
-
tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
tw32_f(MAC_MI_MODE, tp->mi_mode);
udelay(80);
@@ -1041,15 +1038,6 @@ static void tg3_mdio_start(struct tg3 *tp)
tg3_mdio_config_5785(tp);
}
-static void tg3_mdio_stop(struct tg3 *tp)
-{
- if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
- mutex_lock(&tp->mdio_bus->mdio_lock);
- tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
- mutex_unlock(&tp->mdio_bus->mdio_lock);
- }
-}
-
static int tg3_mdio_init(struct tg3 *tp)
{
int i;
@@ -1141,7 +1129,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
mdiobus_unregister(tp->mdio_bus);
mdiobus_free(tp->mdio_bus);
- tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
}
}
@@ -1363,7 +1350,7 @@ static void tg3_adjust_link(struct net_device *dev)
struct tg3 *tp = netdev_priv(dev);
struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];
- spin_lock(&tp->lock);
+ spin_lock_bh(&tp->lock);
mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
MAC_MODE_HALF_DUPLEX);
@@ -1431,7 +1418,7 @@ static void tg3_adjust_link(struct net_device *dev)
tp->link_config.active_speed = phydev->speed;
tp->link_config.active_duplex = phydev->duplex;
- spin_unlock(&tp->lock);
+ spin_unlock_bh(&tp->lock);
if (linkmesg)
tg3_link_report(tp);
@@ -6392,8 +6379,6 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_nvram_lock(tp);
- tg3_mdio_stop(tp);
-
tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
/* No matching tg3_nvram_unlock() after this because
@@ -8698,6 +8683,8 @@ static int tg3_close(struct net_device *dev)
del_timer_sync(&tp->timer);
+ tg3_phy_stop(tp);
+
tg3_full_lock(tp, 1);
#if 0
tg3_dump_state(tp);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 82b45d8797b..bab7940158e 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2412,7 +2412,6 @@ struct ring_info {
struct tx_ring_info {
struct sk_buff *skb;
- u32 prev_vlan_tag;
};
struct tg3_config_info {
@@ -2749,7 +2748,6 @@ struct tg3 {
#define TG3_FLG3_5701_DMA_BUG 0x00000008
#define TG3_FLG3_USE_PHYLIB 0x00000010
#define TG3_FLG3_MDIOBUS_INITED 0x00000020
-#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
#define TG3_FLG3_PHY_CONNECTED 0x00000080
#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100
#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index d032bba9bc4..0caa8008c51 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -418,6 +418,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
goto halt_fail_and_release;
}
memcpy(net->dev_addr, bp, ETH_ALEN);
+ memcpy(net->perm_addr, bp, ETH_ALEN);
/* set a nonzero filter to enable data transfers */
memset(u.set, 0, sizeof *u.set);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d445845f277..8d009760277 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -948,7 +948,7 @@ free:
return err;
}
-static void virtnet_remove(struct virtio_device *vdev)
+static void __devexit virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
struct sk_buff *skb;
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 49ea9c92b7e..d7a764a2fc1 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -31,13 +31,12 @@ config STRIP
---help---
Say Y if you have a Metricom radio and intend to use Starmode Radio
IP. STRIP is a radio protocol developed for the MosquitoNet project
- (on the WWW at <http://mosquitonet.stanford.edu/>) to send Internet
- traffic using Metricom radios. Metricom radios are small, battery
- powered, 100kbit/sec packet radio transceivers, about the size and
- weight of a cellular telephone. (You may also have heard them called
- "Metricom modems" but we avoid the term "modem" because it misleads
- many people into thinking that you can plug a Metricom modem into a
- phone line and use it as a modem.)
+ to send Internet traffic using Metricom radios. Metricom radios are
+ small, battery powered, 100kbit/sec packet radio transceivers, about
+ the size and weight of a cellular telephone. (You may also have heard
+ them called "Metricom modems" but we avoid the term "modem" because
+ it misleads many people into thinking that you can plug a Metricom
+ modem into a phone line and use it as a modem.)
You can use STRIP on any Linux machine with a serial port, although
it is obviously most useful for people with laptop computers. If you
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index b3e5cf3735b..dbd488da18b 100644
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -1141,7 +1141,8 @@ static int ar9170_set_freq_cal_data(struct ar9170 *ar,
u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
int chain, idx, i;
- u8 f;
+ u32 phy_data = 0;
+ u8 f, tmp;
switch (channel->band) {
case IEEE80211_BAND_2GHZ:
@@ -1208,9 +1209,6 @@ static int ar9170_set_freq_cal_data(struct ar9170 *ar,
}
for (i = 0; i < 76; i++) {
- u32 phy_data;
- u8 tmp;
-
if (i < 25) {
tmp = ar9170_interpolate_val(i, &pwrs[0][0],
&vpds[0][0]);
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index e96091b3149..9c1397996e0 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -340,10 +340,15 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
q->mmio_base + B43_PIO_TXDATA,
sizeof(u16));
if (data_len & 1) {
+ u8 tail[2] = { 0, };
+
/* Write the last byte. */
ctl &= ~B43_PIO_TXCTL_WRITEHI;
b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
- b43_piotx_write16(q, B43_PIO_TXDATA, data[data_len - 1]);
+ tail[0] = data[data_len - 1];
+ ssb_block_write(dev->dev, tail, 2,
+ q->mmio_base + B43_PIO_TXDATA,
+ sizeof(u16));
}
return ctl;
@@ -386,26 +391,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
q->mmio_base + B43_PIO8_TXDATA,
sizeof(u32));
if (data_len & 3) {
- u32 value = 0;
+ u8 tail[4] = { 0, };
/* Write the last few bytes. */
ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
B43_PIO8_TXCTL_24_31);
- data = &(data[data_len - 1]);
switch (data_len & 3) {
case 3:
- ctl |= B43_PIO8_TXCTL_16_23;
- value |= (u32)(*data) << 16;
- data--;
+ ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
+ tail[0] = data[data_len - 3];
+ tail[1] = data[data_len - 2];
+ tail[2] = data[data_len - 1];
+ break;
case 2:
ctl |= B43_PIO8_TXCTL_8_15;
- value |= (u32)(*data) << 8;
- data--;
+ tail[0] = data[data_len - 2];
+ tail[1] = data[data_len - 1];
+ break;
case 1:
- value |= (u32)(*data);
+ tail[0] = data[data_len - 1];
+ break;
}
b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
- b43_piotx_write32(q, B43_PIO8_TXDATA, value);
+ ssb_block_write(dev->dev, tail, 4,
+ q->mmio_base + B43_PIO8_TXDATA,
+ sizeof(u32));
}
return ctl;
@@ -693,21 +703,25 @@ data_ready:
q->mmio_base + B43_PIO8_RXDATA,
sizeof(u32));
if (len & 3) {
- u32 value;
- char *data;
+ u8 tail[4] = { 0, };
/* Read the last few bytes. */
- value = b43_piorx_read32(q, B43_PIO8_RXDATA);
- data = &(skb->data[len + padding - 1]);
+ ssb_block_read(dev->dev, tail, 4,
+ q->mmio_base + B43_PIO8_RXDATA,
+ sizeof(u32));
switch (len & 3) {
case 3:
- *data = (value >> 16);
- data--;
+ skb->data[len + padding - 3] = tail[0];
+ skb->data[len + padding - 2] = tail[1];
+ skb->data[len + padding - 1] = tail[2];
+ break;
case 2:
- *data = (value >> 8);
- data--;
+ skb->data[len + padding - 2] = tail[0];
+ skb->data[len + padding - 1] = tail[1];
+ break;
case 1:
- *data = value;
+ skb->data[len + padding - 1] = tail[0];
+ break;
}
}
} else {
@@ -715,11 +729,13 @@ data_ready:
q->mmio_base + B43_PIO_RXDATA,
sizeof(u16));
if (len & 1) {
- u16 value;
+ u8 tail[2] = { 0, };
/* Read the last byte. */
- value = b43_piorx_read16(q, B43_PIO_RXDATA);
- skb->data[len + padding - 1] = value;
+ ssb_block_read(dev->dev, tail, 2,
+ q->mmio_base + B43_PIO_RXDATA,
+ sizeof(u16));
+ skb->data[len + padding - 1] = tail[0];
}
}
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 896f532182f..38cfd79e059 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -631,6 +631,9 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
if (WARN_ON(!data->beacon_int))
data->beacon_int = 1;
+ if (data->started)
+ mod_timer(&data->beacon_timer,
+ jiffies + data->beacon_int);
}
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 1cbd9b4a3ef..b8f5ee33445 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2381,6 +2381,7 @@ static struct usb_device_id rt73usb_device_table[] = {
/* Huawei-3Com */
{ USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) },
/* Hercules */
+ { USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) },
/* Linksys */
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index f424146a2bc..ac8aa09ba0d 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -130,7 +130,7 @@ static struct pcmcia_low_level assabet_pcmcia_ops = {
.socket_suspend = assabet_pcmcia_socket_suspend,
};
-int __init pcmcia_assabet_init(struct device *dev)
+int pcmcia_assabet_init(struct device *dev)
{
int ret = -ENODEV;
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
index 4c41e86ccff..0c76d337815 100644
--- a/drivers/pcmcia/sa1100_neponset.c
+++ b/drivers/pcmcia/sa1100_neponset.c
@@ -123,7 +123,7 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {
.socket_suspend = sa1111_pcmcia_socket_suspend,
};
-int __init pcmcia_neponset_init(struct sa1111_dev *sadev)
+int pcmcia_neponset_init(struct sa1111_dev *sadev)
{
int ret = -ENODEV;
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index afdbdaaf80c..a2a742c8ff7 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1211,15 +1211,6 @@ static int sony_nc_add(struct acpi_device *device)
}
}
- /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1
- * should be respected as we already checked for the device presence above */
- if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) {
- dprintk("Invoking _INI\n");
- if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI,
- NULL, NULL)))
- dprintk("_INI Method failed\n");
- }
-
if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
&handle))) {
if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
@@ -1399,27 +1390,20 @@ struct sonypi_eventtypes {
struct sonypi_event *events;
};
-struct device_ctrl {
+struct sony_pic_dev {
+ struct acpi_device *acpi_dev;
+ struct sony_pic_irq *cur_irq;
+ struct sony_pic_ioport *cur_ioport;
+ struct list_head interrupts;
+ struct list_head ioports;
+ struct mutex lock;
+ struct sonypi_eventtypes *event_types;
+ int (*handle_irq)(const u8, const u8);
int model;
- int (*handle_irq)(const u8, const u8);
u16 evport_offset;
- u8 has_camera;
- u8 has_bluetooth;
- u8 has_wwan;
- struct sonypi_eventtypes *event_types;
-};
-
-struct sony_pic_dev {
- struct device_ctrl *control;
- struct acpi_device *acpi_dev;
- struct sony_pic_irq *cur_irq;
- struct sony_pic_ioport *cur_ioport;
- struct list_head interrupts;
- struct list_head ioports;
- struct mutex lock;
- u8 camera_power;
- u8 bluetooth_power;
- u8 wwan_power;
+ u8 camera_power;
+ u8 bluetooth_power;
+ u8 wwan_power;
};
static struct sony_pic_dev spic_dev = {
@@ -1427,6 +1411,8 @@ static struct sony_pic_dev spic_dev = {
.ioports = LIST_HEAD_INIT(spic_dev.ioports),
};
+static int spic_drv_registered;
+
/* Event masks */
#define SONYPI_JOGGER_MASK 0x00000001
#define SONYPI_CAPTURE_MASK 0x00000002
@@ -1724,27 +1710,6 @@ static int type3_handle_irq(const u8 data_mask, const u8 ev)
return 1;
}
-static struct device_ctrl spic_types[] = {
- {
- .model = SONYPI_DEVICE_TYPE1,
- .handle_irq = NULL,
- .evport_offset = SONYPI_TYPE1_OFFSET,
- .event_types = type1_events,
- },
- {
- .model = SONYPI_DEVICE_TYPE2,
- .handle_irq = NULL,
- .evport_offset = SONYPI_TYPE2_OFFSET,
- .event_types = type2_events,
- },
- {
- .model = SONYPI_DEVICE_TYPE3,
- .handle_irq = type3_handle_irq,
- .evport_offset = SONYPI_TYPE3_OFFSET,
- .event_types = type3_events,
- },
-};
-
static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
{
struct pci_dev *pcidev;
@@ -1752,48 +1717,63 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
if (pcidev) {
- dev->control = &spic_types[0];
+ dev->model = SONYPI_DEVICE_TYPE1;
+ dev->evport_offset = SONYPI_TYPE1_OFFSET;
+ dev->event_types = type1_events;
goto out;
}
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH6_1, NULL);
if (pcidev) {
- dev->control = &spic_types[2];
+ dev->model = SONYPI_DEVICE_TYPE2;
+ dev->evport_offset = SONYPI_TYPE2_OFFSET;
+ dev->event_types = type2_events;
goto out;
}
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
if (pcidev) {
- dev->control = &spic_types[2];
+ dev->model = SONYPI_DEVICE_TYPE3;
+ dev->handle_irq = type3_handle_irq;
+ dev->evport_offset = SONYPI_TYPE3_OFFSET;
+ dev->event_types = type3_events;
goto out;
}
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
if (pcidev) {
- dev->control = &spic_types[2];
+ dev->model = SONYPI_DEVICE_TYPE3;
+ dev->handle_irq = type3_handle_irq;
+ dev->evport_offset = SONYPI_TYPE3_OFFSET;
+ dev->event_types = type3_events;
goto out;
}
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
if (pcidev) {
- dev->control = &spic_types[2];
+ dev->model = SONYPI_DEVICE_TYPE3;
+ dev->handle_irq = type3_handle_irq;
+ dev->evport_offset = SONYPI_TYPE3_OFFSET;
+ dev->event_types = type3_events;
goto out;
}
/* default */
- dev->control = &spic_types[1];
+ dev->model = SONYPI_DEVICE_TYPE2;
+ dev->evport_offset = SONYPI_TYPE2_OFFSET;
+ dev->event_types = type2_events;
out:
if (pcidev)
pci_dev_put(pcidev);
printk(KERN_INFO DRV_PFX "detected Type%d model\n",
- dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
- dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
+ dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
+ dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
}
/* camera tests and poweron/poweroff */
@@ -2566,7 +2546,7 @@ static int sony_pic_enable(struct acpi_device *device,
buffer.pointer = resource;
/* setup Type 1 resources */
- if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) {
+ if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
/* setup io resources */
resource->res1.type = ACPI_RESOURCE_TYPE_IO;
@@ -2649,29 +2629,28 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
data_mask = inb_p(dev->cur_ioport->io2.minimum);
else
data_mask = inb_p(dev->cur_ioport->io1.minimum +
- dev->control->evport_offset);
+ dev->evport_offset);
dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
ev, data_mask, dev->cur_ioport->io1.minimum,
- dev->control->evport_offset);
+ dev->evport_offset);
if (ev == 0x00 || ev == 0xff)
return IRQ_HANDLED;
- for (i = 0; dev->control->event_types[i].mask; i++) {
+ for (i = 0; dev->event_types[i].mask; i++) {
- if ((data_mask & dev->control->event_types[i].data) !=
- dev->control->event_types[i].data)
+ if ((data_mask & dev->event_types[i].data) !=
+ dev->event_types[i].data)
continue;
- if (!(mask & dev->control->event_types[i].mask))
+ if (!(mask & dev->event_types[i].mask))
continue;
- for (j = 0; dev->control->event_types[i].events[j].event; j++) {
- if (ev == dev->control->event_types[i].events[j].data) {
+ for (j = 0; dev->event_types[i].events[j].event; j++) {
+ if (ev == dev->event_types[i].events[j].data) {
device_event =
- dev->control->
- event_types[i].events[j].event;
+ dev->event_types[i].events[j].event;
goto found;
}
}
@@ -2679,13 +2658,12 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
/* Still not able to decode the event try to pass
* it over to the minidriver
*/
- if (dev->control->handle_irq &&
- dev->control->handle_irq(data_mask, ev) == 0)
+ if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0)
return IRQ_HANDLED;
dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
ev, data_mask, dev->cur_ioport->io1.minimum,
- dev->control->evport_offset);
+ dev->evport_offset);
return IRQ_HANDLED;
found:
@@ -2816,7 +2794,7 @@ static int sony_pic_add(struct acpi_device *device)
/* request IRQ */
list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) {
if (!request_irq(irq->irq.interrupts[0], sony_pic_irq,
- IRQF_SHARED, "sony-laptop", &spic_dev)) {
+ IRQF_DISABLED, "sony-laptop", &spic_dev)) {
dprintk("IRQ: %d - triggering: %d - "
"polarity: %d - shr: %d\n",
irq->irq.interrupts[0],
@@ -2949,6 +2927,7 @@ static int __init sony_laptop_init(void)
"Unable to register SPIC driver.");
goto out;
}
+ spic_drv_registered = 1;
}
result = acpi_bus_register_driver(&sony_nc_driver);
@@ -2960,7 +2939,7 @@ static int __init sony_laptop_init(void)
return 0;
out_unregister_pic:
- if (!no_spic)
+ if (spic_drv_registered)
acpi_bus_unregister_driver(&sony_pic_driver);
out:
return result;
@@ -2969,7 +2948,7 @@ out:
static void __exit sony_laptop_exit(void)
{
acpi_bus_unregister_driver(&sony_nc_driver);
- if (!no_spic)
+ if (spic_drv_registered)
acpi_bus_unregister_driver(&sony_pic_driver);
}
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index 1b78f639ead..76769978285 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -125,7 +125,7 @@ static int qstat_seq_open(struct inode *inode, struct file *filp)
filp->f_path.dentry->d_inode->i_private);
}
-static struct file_operations debugfs_fops = {
+static const struct file_operations debugfs_fops = {
.owner = THIS_MODULE,
.open = qstat_seq_open,
.read = seq_read,
diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c
index eff943923c6..968e3c7c263 100644
--- a/drivers/s390/cio/qdio_perf.c
+++ b/drivers/s390/cio/qdio_perf.c
@@ -84,7 +84,7 @@ static int qdio_perf_seq_open(struct inode *inode, struct file *filp)
return single_open(filp, qdio_perf_proc_show, NULL);
}
-static struct file_operations qdio_perf_proc_fops = {
+static const struct file_operations qdio_perf_proc_fops = {
.owner = THIS_MODULE,
.open = qdio_perf_seq_open,
.read = seq_read,
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index a328b5f284d..040f751809e 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1317,7 +1317,7 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
}
}
-static struct file_operations sg_fops = {
+static const struct file_operations sg_fops = {
.owner = THIS_MODULE,
.read = sg_read,
.write = sg_write,
@@ -2194,9 +2194,11 @@ static int sg_proc_seq_show_int(struct seq_file *s, void *v);
static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer,
size_t count, loff_t *off);
-static struct file_operations adio_fops = {
- /* .owner, .read and .llseek added in sg_proc_init() */
+static const struct file_operations adio_fops = {
+ .owner = THIS_MODULE,
.open = sg_proc_single_open_adio,
+ .read = seq_read,
+ .llseek = seq_lseek,
.write = sg_proc_write_adio,
.release = single_release,
};
@@ -2204,23 +2206,32 @@ static struct file_operations adio_fops = {
static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
static ssize_t sg_proc_write_dressz(struct file *filp,
const char __user *buffer, size_t count, loff_t *off);
-static struct file_operations dressz_fops = {
+static const struct file_operations dressz_fops = {
+ .owner = THIS_MODULE,
.open = sg_proc_single_open_dressz,
+ .read = seq_read,
+ .llseek = seq_lseek,
.write = sg_proc_write_dressz,
.release = single_release,
};
static int sg_proc_seq_show_version(struct seq_file *s, void *v);
static int sg_proc_single_open_version(struct inode *inode, struct file *file);
-static struct file_operations version_fops = {
+static const struct file_operations version_fops = {
+ .owner = THIS_MODULE,
.open = sg_proc_single_open_version,
+ .read = seq_read,
+ .llseek = seq_lseek,
.release = single_release,
};
static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v);
static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file);
-static struct file_operations devhdr_fops = {
+static const struct file_operations devhdr_fops = {
+ .owner = THIS_MODULE,
.open = sg_proc_single_open_devhdr,
+ .read = seq_read,
+ .llseek = seq_lseek,
.release = single_release,
};
@@ -2229,8 +2240,11 @@ static int sg_proc_open_dev(struct inode *inode, struct file *file);
static void * dev_seq_start(struct seq_file *s, loff_t *pos);
static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos);
static void dev_seq_stop(struct seq_file *s, void *v);
-static struct file_operations dev_fops = {
+static const struct file_operations dev_fops = {
+ .owner = THIS_MODULE,
.open = sg_proc_open_dev,
+ .read = seq_read,
+ .llseek = seq_lseek,
.release = seq_release,
};
static const struct seq_operations dev_seq_ops = {
@@ -2242,8 +2256,11 @@ static const struct seq_operations dev_seq_ops = {
static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v);
static int sg_proc_open_devstrs(struct inode *inode, struct file *file);
-static struct file_operations devstrs_fops = {
+static const struct file_operations devstrs_fops = {
+ .owner = THIS_MODULE,
.open = sg_proc_open_devstrs,
+ .read = seq_read,
+ .llseek = seq_lseek,
.release = seq_release,
};
static const struct seq_operations devstrs_seq_ops = {
@@ -2255,8 +2272,11 @@ static const struct seq_operations devstrs_seq_ops = {
static int sg_proc_seq_show_debug(struct seq_file *s, void *v);
static int sg_proc_open_debug(struct inode *inode, struct file *file);
-static struct file_operations debug_fops = {
+static const struct file_operations debug_fops = {
+ .owner = THIS_MODULE,
.open = sg_proc_open_debug,
+ .read = seq_read,
+ .llseek = seq_lseek,
.release = seq_release,
};
static const struct seq_operations debug_seq_ops = {
@@ -2269,7 +2289,7 @@ static const struct seq_operations debug_seq_ops = {
struct sg_proc_leaf {
const char * name;
- struct file_operations * fops;
+ const struct file_operations * fops;
};
static struct sg_proc_leaf sg_proc_leaf_arr[] = {
@@ -2295,9 +2315,6 @@ sg_proc_init(void)
for (k = 0; k < num_leaves; ++k) {
leaf = &sg_proc_leaf_arr[k];
mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO;
- leaf->fops->owner = THIS_MODULE;
- leaf->fops->read = seq_read;
- leaf->fops->llseek = seq_lseek;
proc_create(leaf->name, mask, sg_proc_sgp, leaf->fops);
}
return 0;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 2209620d234..b1ae774016f 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -64,6 +64,8 @@ static int serial_index(struct uart_port *port)
return (serial8250_reg.minor - 64) + port->line;
}
+static unsigned int skip_txen_test; /* force skip of txen test at init time */
+
/*
* Debugging.
*/
@@ -2108,7 +2110,7 @@ static int serial8250_startup(struct uart_port *port)
is variable. So, let's just don't test if we receive
TX irq. This way, we'll never enable UART_BUG_TXEN.
*/
- if (up->port.flags & UPF_NO_TXEN_TEST)
+ if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
goto dont_test_tx_en;
/*
@@ -3248,6 +3250,9 @@ MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
module_param(nr_uarts, uint, 0644);
MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
+module_param(skip_txen_test, uint, 0644);
+MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
+
#ifdef CONFIG_SERIAL_8250_RSA
module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e70712044a7..e5225725727 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -862,7 +862,7 @@ config SERIAL_IMX_CONSOLE
config SERIAL_UARTLITE
tristate "Xilinx uartlite serial port support"
- depends on PPC32 || MICROBLAZE
+ depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE
select SERIAL_CORE
help
Say Y here if you want to use the Xilinx uartlite serial controller.
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 2d7feecaf49..0028b6f89ce 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -307,7 +307,7 @@ static void stop_processor(struct icom_port *icom_port)
if (port < 4) {
temp = readl(stop_proc[port].global_control_reg);
temp =
- (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
+ (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
writel(temp, stop_proc[port].global_control_reg);
/* write flush */
@@ -336,7 +336,7 @@ static void start_processor(struct icom_port *icom_port)
if (port < 4) {
temp = readl(start_proc[port].global_control_reg);
temp =
- (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
+ (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
writel(temp, start_proc[port].global_control_reg);
/* write flush */
@@ -509,8 +509,8 @@ static void load_code(struct icom_port *icom_port)
dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
}
- if (new_page != NULL)
- pci_free_consistent(dev, 4096, new_page, temp_pci);
+ if (new_page != NULL)
+ pci_free_consistent(dev, 4096, new_page, temp_pci);
}
static int startup(struct icom_port *icom_port)
@@ -1493,15 +1493,15 @@ static int __devinit icom_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
int index;
- unsigned int command_reg;
- int retval;
- struct icom_adapter *icom_adapter;
- struct icom_port *icom_port;
+ unsigned int command_reg;
+ int retval;
+ struct icom_adapter *icom_adapter;
+ struct icom_port *icom_port;
- retval = pci_enable_device(dev);
- if (retval) {
+ retval = pci_enable_device(dev);
+ if (retval) {
dev_err(&dev->dev, "Device enable FAILED\n");
- return retval;
+ return retval;
}
if ( (retval = pci_request_regions(dev, "icom"))) {
@@ -1510,23 +1510,23 @@ static int __devinit icom_probe(struct pci_dev *dev,
return retval;
}
- pci_set_master(dev);
+ pci_set_master(dev);
- if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
+ if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
dev_err(&dev->dev, "PCI Config read FAILED\n");
- return retval;
- }
+ return retval;
+ }
pci_write_config_dword(dev, PCI_COMMAND,
command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
| PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
- if (ent->driver_data == ADAPTER_V1) {
+ if (ent->driver_data == ADAPTER_V1) {
pci_write_config_dword(dev, 0x44, 0x8300830A);
- } else {
+ } else {
pci_write_config_dword(dev, 0x44, 0x42004200);
pci_write_config_dword(dev, 0x48, 0x42004200);
- }
+ }
retval = icom_alloc_adapter(&icom_adapter);
@@ -1536,10 +1536,10 @@ static int __devinit icom_probe(struct pci_dev *dev,
goto probe_exit0;
}
- icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
- icom_adapter->pci_dev = dev;
- icom_adapter->version = ent->driver_data;
- icom_adapter->subsystem_id = ent->subdevice;
+ icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
+ icom_adapter->pci_dev = dev;
+ icom_adapter->version = ent->driver_data;
+ icom_adapter->subsystem_id = ent->subdevice;
retval = icom_init_ports(icom_adapter);
@@ -1548,7 +1548,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
goto probe_exit1;
}
- icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
+ icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
if (!icom_adapter->base_addr)
goto probe_exit1;
@@ -1562,7 +1562,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
retval = icom_load_ports(icom_adapter);
- for (index = 0; index < icom_adapter->numb_ports; index++) {
+ for (index = 0; index < icom_adapter->numb_ports; index++) {
icom_port = &icom_adapter->port_info[index];
if (icom_port->status == ICOM_PORT_ACTIVE) {
@@ -1579,7 +1579,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
icom_port->status = ICOM_PORT_OFF;
dev_err(&dev->dev, "Device add failed\n");
} else
- dev_info(&dev->dev, "Device added\n");
+ dev_info(&dev->dev, "Device added\n");
}
}
@@ -1595,9 +1595,7 @@ probe_exit0:
pci_release_regions(dev);
pci_disable_device(dev);
- return retval;
-
-
+ return retval;
}
static void __devexit icom_remove(struct pci_dev *dev)
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 7f5e2687322..2199d819a98 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -638,7 +638,7 @@ static void __init sa1100_init_ports(void)
PPSR |= PPC_TXD1 | PPC_TXD3;
}
-void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns)
+void __devinit sa1100_register_uart_fns(struct sa1100_port_fns *fns)
{
if (fns->get_mctrl)
sa1100_pops.get_mctrl = fns->get_mctrl;
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index a3bb49031a7..ff4617e2142 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -873,10 +873,10 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
- PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
- PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
@@ -884,9 +884,9 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "COMpad2.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"),
PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b),
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 0f7cf4c453e..c50e9fbbf74 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -221,21 +221,26 @@ sio_quot_set(struct uart_txx9_port *up, int quot)
sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6);
}
+static struct uart_txx9_port *to_uart_txx9_port(struct uart_port *port)
+{
+ return container_of(port, struct uart_txx9_port, port);
+}
+
static void serial_txx9_stop_tx(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
}
static void serial_txx9_start_tx(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
}
static void serial_txx9_stop_rx(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
up->port.read_status_mask &= ~TXX9_SIDISR_RDIS;
}
@@ -246,7 +251,7 @@ static void serial_txx9_enable_ms(struct uart_port *port)
static void serial_txx9_initialize(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
unsigned int tmout = 10000;
sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
@@ -414,7 +419,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id)
static unsigned int serial_txx9_tx_empty(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
unsigned long flags;
unsigned int ret;
@@ -427,7 +432,7 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port)
static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
unsigned int ret;
/* no modem control lines */
@@ -440,7 +445,7 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
if (mctrl & TIOCM_RTS)
sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
@@ -450,7 +455,7 @@ static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
static void serial_txx9_break_ctl(struct uart_port *port, int break_state)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
unsigned long flags;
spin_lock_irqsave(&up->port.lock, flags);
@@ -494,7 +499,7 @@ static int serial_txx9_get_poll_char(struct uart_port *port)
{
unsigned int ier;
unsigned char c;
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
/*
* First save the IER then disable the interrupts
@@ -520,7 +525,7 @@ static int serial_txx9_get_poll_char(struct uart_port *port)
static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
{
unsigned int ier;
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
/*
* First save the IER then disable the interrupts
@@ -551,7 +556,7 @@ static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
static int serial_txx9_startup(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
unsigned long flags;
int retval;
@@ -596,7 +601,7 @@ static int serial_txx9_startup(struct uart_port *port)
static void serial_txx9_shutdown(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
unsigned long flags;
/*
@@ -636,7 +641,7 @@ static void
serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
unsigned int cval, fcr = 0;
unsigned long flags;
unsigned int baud, quot;
@@ -814,19 +819,19 @@ static void serial_txx9_release_resource(struct uart_txx9_port *up)
static void serial_txx9_release_port(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
serial_txx9_release_resource(up);
}
static int serial_txx9_request_port(struct uart_port *port)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
return serial_txx9_request_resource(up);
}
static void serial_txx9_config_port(struct uart_port *port, int uflags)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
int ret;
/*
@@ -897,7 +902,7 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv,
static void serial_txx9_console_putchar(struct uart_port *port, int ch)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ struct uart_txx9_port *up = to_uart_txx9_port(port);
wait_for_xmitr(up);
sio_out(up, TXX9_SITFIFO, ch);
diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c
index d3b49680047..b204a092913 100644
--- a/drivers/sfi/sfi_core.c
+++ b/drivers/sfi/sfi_core.c
@@ -90,7 +90,11 @@ static struct sfi_table_simple *syst_va __read_mostly;
*/
static u32 sfi_use_ioremap __read_mostly;
-static void __iomem *sfi_map_memory(u64 phys, u32 size)
+/*
+ * sfi_un/map_memory calls early_ioremap/iounmap which is a __init function
+ * and introduces section mismatch. So use __ref to make it calm.
+ */
+static void __iomem * __ref sfi_map_memory(u64 phys, u32 size)
{
if (!phys || !size)
return NULL;
@@ -101,7 +105,7 @@ static void __iomem *sfi_map_memory(u64 phys, u32 size)
return early_ioremap(phys, size);
}
-static void sfi_unmap_memory(void __iomem *virt, u32 size)
+static void __ref sfi_unmap_memory(void __iomem *virt, u32 size)
{
if (!virt || !size)
return;
@@ -125,7 +129,7 @@ static void sfi_print_table_header(unsigned long long pa,
* sfi_verify_table()
* Sanity check table lengh, calculate checksum
*/
-static __init int sfi_verify_table(struct sfi_table_header *table)
+static int sfi_verify_table(struct sfi_table_header *table)
{
u8 checksum = 0;
@@ -213,12 +217,17 @@ static int sfi_table_check_key(struct sfi_table_header *th,
* the mapped virt address will be returned, and the virt space
* will be released by call sfi_put_table() later
*
+ * This two cases are from two different functions with two different
+ * sections and causes section mismatch warning. So use __ref to tell
+ * modpost not to make any noise.
+ *
* Return value:
* NULL: when can't find a table matching the key
* ERR_PTR(error): error value
* virt table address: when a matched table is found
*/
-struct sfi_table_header *sfi_check_table(u64 pa, struct sfi_table_key *key)
+struct sfi_table_header *
+ __ref sfi_check_table(u64 pa, struct sfi_table_key *key)
{
struct sfi_table_header *th;
void *ret = NULL;
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6d7a3f82c54..21a118269ca 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -17,7 +17,7 @@ obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
obj-$(CONFIG_SPI_GPIO) += spi_gpio.o
-obj-$(CONFIG_SPI_IMX) += mxc_spi.o
+obj-$(CONFIG_SPI_IMX) += spi_imx.o
obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o
obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/spi_imx.c
index b1447236ae8..89c22efedfb 100644
--- a/drivers/spi/mxc_spi.c
+++ b/drivers/spi/spi_imx.c
@@ -48,14 +48,14 @@
#define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */
#define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */
-struct mxc_spi_config {
+struct spi_imx_config {
unsigned int speed_hz;
unsigned int bpw;
unsigned int mode;
int cs;
};
-struct mxc_spi_data {
+struct spi_imx_data {
struct spi_bitbang bitbang;
struct completion xfer_done;
@@ -66,43 +66,43 @@ struct mxc_spi_data {
int *chipselect;
unsigned int count;
- void (*tx)(struct mxc_spi_data *);
- void (*rx)(struct mxc_spi_data *);
+ void (*tx)(struct spi_imx_data *);
+ void (*rx)(struct spi_imx_data *);
void *rx_buf;
const void *tx_buf;
unsigned int txfifo; /* number of words pushed in tx FIFO */
/* SoC specific functions */
- void (*intctrl)(struct mxc_spi_data *, int);
- int (*config)(struct mxc_spi_data *, struct mxc_spi_config *);
- void (*trigger)(struct mxc_spi_data *);
- int (*rx_available)(struct mxc_spi_data *);
+ void (*intctrl)(struct spi_imx_data *, int);
+ int (*config)(struct spi_imx_data *, struct spi_imx_config *);
+ void (*trigger)(struct spi_imx_data *);
+ int (*rx_available)(struct spi_imx_data *);
};
#define MXC_SPI_BUF_RX(type) \
-static void mxc_spi_buf_rx_##type(struct mxc_spi_data *mxc_spi) \
+static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx) \
{ \
- unsigned int val = readl(mxc_spi->base + MXC_CSPIRXDATA); \
+ unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA); \
\
- if (mxc_spi->rx_buf) { \
- *(type *)mxc_spi->rx_buf = val; \
- mxc_spi->rx_buf += sizeof(type); \
+ if (spi_imx->rx_buf) { \
+ *(type *)spi_imx->rx_buf = val; \
+ spi_imx->rx_buf += sizeof(type); \
} \
}
#define MXC_SPI_BUF_TX(type) \
-static void mxc_spi_buf_tx_##type(struct mxc_spi_data *mxc_spi) \
+static void spi_imx_buf_tx_##type(struct spi_imx_data *spi_imx) \
{ \
type val = 0; \
\
- if (mxc_spi->tx_buf) { \
- val = *(type *)mxc_spi->tx_buf; \
- mxc_spi->tx_buf += sizeof(type); \
+ if (spi_imx->tx_buf) { \
+ val = *(type *)spi_imx->tx_buf; \
+ spi_imx->tx_buf += sizeof(type); \
} \
\
- mxc_spi->count -= sizeof(type); \
+ spi_imx->count -= sizeof(type); \
\
- writel(val, mxc_spi->base + MXC_CSPITXDATA); \
+ writel(val, spi_imx->base + MXC_CSPITXDATA); \
}
MXC_SPI_BUF_RX(u8)
@@ -119,7 +119,7 @@ static int mxc_clkdivs[] = {0, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
256, 384, 512, 768, 1024};
/* MX21, MX27 */
-static unsigned int mxc_spi_clkdiv_1(unsigned int fin,
+static unsigned int spi_imx_clkdiv_1(unsigned int fin,
unsigned int fspi)
{
int i, max;
@@ -137,7 +137,7 @@ static unsigned int mxc_spi_clkdiv_1(unsigned int fin,
}
/* MX1, MX31, MX35 */
-static unsigned int mxc_spi_clkdiv_2(unsigned int fin,
+static unsigned int spi_imx_clkdiv_2(unsigned int fin,
unsigned int fspi)
{
int i, div = 4;
@@ -174,7 +174,7 @@ static unsigned int mxc_spi_clkdiv_2(unsigned int fin,
* the i.MX35 has a slightly different register layout for bits
* we do not use here.
*/
-static void mx31_intctrl(struct mxc_spi_data *mxc_spi, int enable)
+static void mx31_intctrl(struct spi_imx_data *spi_imx, int enable)
{
unsigned int val = 0;
@@ -183,24 +183,24 @@ static void mx31_intctrl(struct mxc_spi_data *mxc_spi, int enable)
if (enable & MXC_INT_RR)
val |= MX31_INTREG_RREN;
- writel(val, mxc_spi->base + MXC_CSPIINT);
+ writel(val, spi_imx->base + MXC_CSPIINT);
}
-static void mx31_trigger(struct mxc_spi_data *mxc_spi)
+static void mx31_trigger(struct spi_imx_data *spi_imx)
{
unsigned int reg;
- reg = readl(mxc_spi->base + MXC_CSPICTRL);
+ reg = readl(spi_imx->base + MXC_CSPICTRL);
reg |= MX31_CSPICTRL_XCH;
- writel(reg, mxc_spi->base + MXC_CSPICTRL);
+ writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx31_config(struct mxc_spi_data *mxc_spi,
- struct mxc_spi_config *config)
+static int mx31_config(struct spi_imx_data *spi_imx,
+ struct spi_imx_config *config)
{
unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER;
- reg |= mxc_spi_clkdiv_2(mxc_spi->spi_clk, config->speed_hz) <<
+ reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
MX31_CSPICTRL_DR_SHIFT;
if (cpu_is_mx31())
@@ -223,14 +223,14 @@ static int mx31_config(struct mxc_spi_data *mxc_spi,
reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT;
}
- writel(reg, mxc_spi->base + MXC_CSPICTRL);
+ writel(reg, spi_imx->base + MXC_CSPICTRL);
return 0;
}
-static int mx31_rx_available(struct mxc_spi_data *mxc_spi)
+static int mx31_rx_available(struct spi_imx_data *spi_imx)
{
- return readl(mxc_spi->base + MX31_CSPISTATUS) & MX31_STATUS_RR;
+ return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR;
}
#define MX27_INTREG_RR (1 << 4)
@@ -246,7 +246,7 @@ static int mx31_rx_available(struct mxc_spi_data *mxc_spi)
#define MX27_CSPICTRL_DR_SHIFT 14
#define MX27_CSPICTRL_CS_SHIFT 19
-static void mx27_intctrl(struct mxc_spi_data *mxc_spi, int enable)
+static void mx27_intctrl(struct spi_imx_data *spi_imx, int enable)
{
unsigned int val = 0;
@@ -255,24 +255,24 @@ static void mx27_intctrl(struct mxc_spi_data *mxc_spi, int enable)
if (enable & MXC_INT_RR)
val |= MX27_INTREG_RREN;
- writel(val, mxc_spi->base + MXC_CSPIINT);
+ writel(val, spi_imx->base + MXC_CSPIINT);
}
-static void mx27_trigger(struct mxc_spi_data *mxc_spi)
+static void mx27_trigger(struct spi_imx_data *spi_imx)
{
unsigned int reg;
- reg = readl(mxc_spi->base + MXC_CSPICTRL);
+ reg = readl(spi_imx->base + MXC_CSPICTRL);
reg |= MX27_CSPICTRL_XCH;
- writel(reg, mxc_spi->base + MXC_CSPICTRL);
+ writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx27_config(struct mxc_spi_data *mxc_spi,
- struct mxc_spi_config *config)
+static int mx27_config(struct spi_imx_data *spi_imx,
+ struct spi_imx_config *config)
{
unsigned int reg = MX27_CSPICTRL_ENABLE | MX27_CSPICTRL_MASTER;
- reg |= mxc_spi_clkdiv_1(mxc_spi->spi_clk, config->speed_hz) <<
+ reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz) <<
MX27_CSPICTRL_DR_SHIFT;
reg |= config->bpw - 1;
@@ -285,14 +285,14 @@ static int mx27_config(struct mxc_spi_data *mxc_spi,
if (config->cs < 0)
reg |= (config->cs + 32) << MX27_CSPICTRL_CS_SHIFT;
- writel(reg, mxc_spi->base + MXC_CSPICTRL);
+ writel(reg, spi_imx->base + MXC_CSPICTRL);
return 0;
}
-static int mx27_rx_available(struct mxc_spi_data *mxc_spi)
+static int mx27_rx_available(struct spi_imx_data *spi_imx)
{
- return readl(mxc_spi->base + MXC_CSPIINT) & MX27_INTREG_RR;
+ return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR;
}
#define MX1_INTREG_RR (1 << 3)
@@ -306,7 +306,7 @@ static int mx27_rx_available(struct mxc_spi_data *mxc_spi)
#define MX1_CSPICTRL_MASTER (1 << 10)
#define MX1_CSPICTRL_DR_SHIFT 13
-static void mx1_intctrl(struct mxc_spi_data *mxc_spi, int enable)
+static void mx1_intctrl(struct spi_imx_data *spi_imx, int enable)
{
unsigned int val = 0;
@@ -315,24 +315,24 @@ static void mx1_intctrl(struct mxc_spi_data *mxc_spi, int enable)
if (enable & MXC_INT_RR)
val |= MX1_INTREG_RREN;
- writel(val, mxc_spi->base + MXC_CSPIINT);
+ writel(val, spi_imx->base + MXC_CSPIINT);
}
-static void mx1_trigger(struct mxc_spi_data *mxc_spi)
+static void mx1_trigger(struct spi_imx_data *spi_imx)
{
unsigned int reg;
- reg = readl(mxc_spi->base + MXC_CSPICTRL);
+ reg = readl(spi_imx->base + MXC_CSPICTRL);
reg |= MX1_CSPICTRL_XCH;
- writel(reg, mxc_spi->base + MXC_CSPICTRL);
+ writel(reg, spi_imx->base + MXC_CSPICTRL);
}
-static int mx1_config(struct mxc_spi_data *mxc_spi,
- struct mxc_spi_config *config)
+static int mx1_config(struct spi_imx_data *spi_imx,
+ struct spi_imx_config *config)
{
unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER;
- reg |= mxc_spi_clkdiv_2(mxc_spi->spi_clk, config->speed_hz) <<
+ reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
MX1_CSPICTRL_DR_SHIFT;
reg |= config->bpw - 1;
@@ -341,156 +341,151 @@ static int mx1_config(struct mxc_spi_data *mxc_spi,
if (config->mode & SPI_CPOL)
reg |= MX1_CSPICTRL_POL;
- writel(reg, mxc_spi->base + MXC_CSPICTRL);
+ writel(reg, spi_imx->base + MXC_CSPICTRL);
return 0;
}
-static int mx1_rx_available(struct mxc_spi_data *mxc_spi)
+static int mx1_rx_available(struct spi_imx_data *spi_imx)
{
- return readl(mxc_spi->base + MXC_CSPIINT) & MX1_INTREG_RR;
+ return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR;
}
-static void mxc_spi_chipselect(struct spi_device *spi, int is_active)
+static void spi_imx_chipselect(struct spi_device *spi, int is_active)
{
- struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master);
- unsigned int cs = 0;
- int gpio = mxc_spi->chipselect[spi->chip_select];
- struct mxc_spi_config config;
+ struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+ int gpio = spi_imx->chipselect[spi->chip_select];
+ int active = is_active != BITBANG_CS_INACTIVE;
+ int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH);
- if (spi->mode & SPI_CS_HIGH)
- cs = 1;
-
- if (is_active == BITBANG_CS_INACTIVE) {
- if (gpio >= 0)
- gpio_set_value(gpio, !cs);
+ if (gpio < 0)
return;
- }
-
- config.bpw = spi->bits_per_word;
- config.speed_hz = spi->max_speed_hz;
- config.mode = spi->mode;
- config.cs = mxc_spi->chipselect[spi->chip_select];
-
- mxc_spi->config(mxc_spi, &config);
-
- /* Initialize the functions for transfer */
- if (config.bpw <= 8) {
- mxc_spi->rx = mxc_spi_buf_rx_u8;
- mxc_spi->tx = mxc_spi_buf_tx_u8;
- } else if (config.bpw <= 16) {
- mxc_spi->rx = mxc_spi_buf_rx_u16;
- mxc_spi->tx = mxc_spi_buf_tx_u16;
- } else if (config.bpw <= 32) {
- mxc_spi->rx = mxc_spi_buf_rx_u32;
- mxc_spi->tx = mxc_spi_buf_tx_u32;
- } else
- BUG();
- if (gpio >= 0)
- gpio_set_value(gpio, cs);
-
- return;
+ gpio_set_value(gpio, dev_is_lowactive ^ active);
}
-static void mxc_spi_push(struct mxc_spi_data *mxc_spi)
+static void spi_imx_push(struct spi_imx_data *spi_imx)
{
- while (mxc_spi->txfifo < 8) {
- if (!mxc_spi->count)
+ while (spi_imx->txfifo < 8) {
+ if (!spi_imx->count)
break;
- mxc_spi->tx(mxc_spi);
- mxc_spi->txfifo++;
+ spi_imx->tx(spi_imx);
+ spi_imx->txfifo++;
}
- mxc_spi->trigger(mxc_spi);
+ spi_imx->trigger(spi_imx);
}
-static irqreturn_t mxc_spi_isr(int irq, void *dev_id)
+static irqreturn_t spi_imx_isr(int irq, void *dev_id)
{
- struct mxc_spi_data *mxc_spi = dev_id;
+ struct spi_imx_data *spi_imx = dev_id;
- while (mxc_spi->rx_available(mxc_spi)) {
- mxc_spi->rx(mxc_spi);
- mxc_spi->txfifo--;
+ while (spi_imx->rx_available(spi_imx)) {
+ spi_imx->rx(spi_imx);
+ spi_imx->txfifo--;
}
- if (mxc_spi->count) {
- mxc_spi_push(mxc_spi);
+ if (spi_imx->count) {
+ spi_imx_push(spi_imx);
return IRQ_HANDLED;
}
- if (mxc_spi->txfifo) {
+ if (spi_imx->txfifo) {
/* No data left to push, but still waiting for rx data,
* enable receive data available interrupt.
*/
- mxc_spi->intctrl(mxc_spi, MXC_INT_RR);
+ spi_imx->intctrl(spi_imx, MXC_INT_RR);
return IRQ_HANDLED;
}
- mxc_spi->intctrl(mxc_spi, 0);
- complete(&mxc_spi->xfer_done);
+ spi_imx->intctrl(spi_imx, 0);
+ complete(&spi_imx->xfer_done);
return IRQ_HANDLED;
}
-static int mxc_spi_setupxfer(struct spi_device *spi,
+static int spi_imx_setupxfer(struct spi_device *spi,
struct spi_transfer *t)
{
- struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master);
- struct mxc_spi_config config;
+ struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+ struct spi_imx_config config;
config.bpw = t ? t->bits_per_word : spi->bits_per_word;
config.speed_hz = t ? t->speed_hz : spi->max_speed_hz;
config.mode = spi->mode;
+ config.cs = spi_imx->chipselect[spi->chip_select];
+
+ if (!config.speed_hz)
+ config.speed_hz = spi->max_speed_hz;
+ if (!config.bpw)
+ config.bpw = spi->bits_per_word;
+ if (!config.speed_hz)
+ config.speed_hz = spi->max_speed_hz;
+
+ /* Initialize the functions for transfer */
+ if (config.bpw <= 8) {
+ spi_imx->rx = spi_imx_buf_rx_u8;
+ spi_imx->tx = spi_imx_buf_tx_u8;
+ } else if (config.bpw <= 16) {
+ spi_imx->rx = spi_imx_buf_rx_u16;
+ spi_imx->tx = spi_imx_buf_tx_u16;
+ } else if (config.bpw <= 32) {
+ spi_imx->rx = spi_imx_buf_rx_u32;
+ spi_imx->tx = spi_imx_buf_tx_u32;
+ } else
+ BUG();
- mxc_spi->config(mxc_spi, &config);
+ spi_imx->config(spi_imx, &config);
return 0;
}
-static int mxc_spi_transfer(struct spi_device *spi,
+static int spi_imx_transfer(struct spi_device *spi,
struct spi_transfer *transfer)
{
- struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master);
+ struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
- mxc_spi->tx_buf = transfer->tx_buf;
- mxc_spi->rx_buf = transfer->rx_buf;
- mxc_spi->count = transfer->len;
- mxc_spi->txfifo = 0;
+ spi_imx->tx_buf = transfer->tx_buf;
+ spi_imx->rx_buf = transfer->rx_buf;
+ spi_imx->count = transfer->len;
+ spi_imx->txfifo = 0;
- init_completion(&mxc_spi->xfer_done);
+ init_completion(&spi_imx->xfer_done);
- mxc_spi_push(mxc_spi);
+ spi_imx_push(spi_imx);
- mxc_spi->intctrl(mxc_spi, MXC_INT_TE);
+ spi_imx->intctrl(spi_imx, MXC_INT_TE);
- wait_for_completion(&mxc_spi->xfer_done);
+ wait_for_completion(&spi_imx->xfer_done);
return transfer->len;
}
-static int mxc_spi_setup(struct spi_device *spi)
+static int spi_imx_setup(struct spi_device *spi)
{
- if (!spi->bits_per_word)
- spi->bits_per_word = 8;
+ struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+ int gpio = spi_imx->chipselect[spi->chip_select];
pr_debug("%s: mode %d, %u bpw, %d hz\n", __func__,
spi->mode, spi->bits_per_word, spi->max_speed_hz);
- mxc_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+ if (gpio >= 0)
+ gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
+
+ spi_imx_chipselect(spi, BITBANG_CS_INACTIVE);
return 0;
}
-static void mxc_spi_cleanup(struct spi_device *spi)
+static void spi_imx_cleanup(struct spi_device *spi)
{
}
-static int __init mxc_spi_probe(struct platform_device *pdev)
+static int __init spi_imx_probe(struct platform_device *pdev)
{
struct spi_imx_master *mxc_platform_info;
struct spi_master *master;
- struct mxc_spi_data *mxc_spi;
+ struct spi_imx_data *spi_imx;
struct resource *res;
int i, ret;
@@ -500,7 +495,7 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
return -EINVAL;
}
- master = spi_alloc_master(&pdev->dev, sizeof(struct mxc_spi_data));
+ master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data));
if (!master)
return -ENOMEM;
@@ -509,32 +504,32 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
master->bus_num = pdev->id;
master->num_chipselect = mxc_platform_info->num_chipselect;
- mxc_spi = spi_master_get_devdata(master);
- mxc_spi->bitbang.master = spi_master_get(master);
- mxc_spi->chipselect = mxc_platform_info->chipselect;
+ spi_imx = spi_master_get_devdata(master);
+ spi_imx->bitbang.master = spi_master_get(master);
+ spi_imx->chipselect = mxc_platform_info->chipselect;
for (i = 0; i < master->num_chipselect; i++) {
- if (mxc_spi->chipselect[i] < 0)
+ if (spi_imx->chipselect[i] < 0)
continue;
- ret = gpio_request(mxc_spi->chipselect[i], DRIVER_NAME);
+ ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
if (ret) {
i--;
while (i > 0)
- if (mxc_spi->chipselect[i] >= 0)
- gpio_free(mxc_spi->chipselect[i--]);
+ if (spi_imx->chipselect[i] >= 0)
+ gpio_free(spi_imx->chipselect[i--]);
dev_err(&pdev->dev, "can't get cs gpios");
goto out_master_put;
}
- gpio_direction_output(mxc_spi->chipselect[i], 1);
}
- mxc_spi->bitbang.chipselect = mxc_spi_chipselect;
- mxc_spi->bitbang.setup_transfer = mxc_spi_setupxfer;
- mxc_spi->bitbang.txrx_bufs = mxc_spi_transfer;
- mxc_spi->bitbang.master->setup = mxc_spi_setup;
- mxc_spi->bitbang.master->cleanup = mxc_spi_cleanup;
+ spi_imx->bitbang.chipselect = spi_imx_chipselect;
+ spi_imx->bitbang.setup_transfer = spi_imx_setupxfer;
+ spi_imx->bitbang.txrx_bufs = spi_imx_transfer;
+ spi_imx->bitbang.master->setup = spi_imx_setup;
+ spi_imx->bitbang.master->cleanup = spi_imx_cleanup;
+ spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
- init_completion(&mxc_spi->xfer_done);
+ init_completion(&spi_imx->xfer_done);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
@@ -549,58 +544,58 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
goto out_gpio_free;
}
- mxc_spi->base = ioremap(res->start, resource_size(res));
- if (!mxc_spi->base) {
+ spi_imx->base = ioremap(res->start, resource_size(res));
+ if (!spi_imx->base) {
ret = -EINVAL;
goto out_release_mem;
}
- mxc_spi->irq = platform_get_irq(pdev, 0);
- if (!mxc_spi->irq) {
+ spi_imx->irq = platform_get_irq(pdev, 0);
+ if (!spi_imx->irq) {
ret = -EINVAL;
goto out_iounmap;
}
- ret = request_irq(mxc_spi->irq, mxc_spi_isr, 0, DRIVER_NAME, mxc_spi);
+ ret = request_irq(spi_imx->irq, spi_imx_isr, 0, DRIVER_NAME, spi_imx);
if (ret) {
- dev_err(&pdev->dev, "can't get irq%d: %d\n", mxc_spi->irq, ret);
+ dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret);
goto out_iounmap;
}
if (cpu_is_mx31() || cpu_is_mx35()) {
- mxc_spi->intctrl = mx31_intctrl;
- mxc_spi->config = mx31_config;
- mxc_spi->trigger = mx31_trigger;
- mxc_spi->rx_available = mx31_rx_available;
+ spi_imx->intctrl = mx31_intctrl;
+ spi_imx->config = mx31_config;
+ spi_imx->trigger = mx31_trigger;
+ spi_imx->rx_available = mx31_rx_available;
} else if (cpu_is_mx27() || cpu_is_mx21()) {
- mxc_spi->intctrl = mx27_intctrl;
- mxc_spi->config = mx27_config;
- mxc_spi->trigger = mx27_trigger;
- mxc_spi->rx_available = mx27_rx_available;
+ spi_imx->intctrl = mx27_intctrl;
+ spi_imx->config = mx27_config;
+ spi_imx->trigger = mx27_trigger;
+ spi_imx->rx_available = mx27_rx_available;
} else if (cpu_is_mx1()) {
- mxc_spi->intctrl = mx1_intctrl;
- mxc_spi->config = mx1_config;
- mxc_spi->trigger = mx1_trigger;
- mxc_spi->rx_available = mx1_rx_available;
+ spi_imx->intctrl = mx1_intctrl;
+ spi_imx->config = mx1_config;
+ spi_imx->trigger = mx1_trigger;
+ spi_imx->rx_available = mx1_rx_available;
} else
BUG();
- mxc_spi->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(mxc_spi->clk)) {
+ spi_imx->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(spi_imx->clk)) {
dev_err(&pdev->dev, "unable to get clock\n");
- ret = PTR_ERR(mxc_spi->clk);
+ ret = PTR_ERR(spi_imx->clk);
goto out_free_irq;
}
- clk_enable(mxc_spi->clk);
- mxc_spi->spi_clk = clk_get_rate(mxc_spi->clk);
+ clk_enable(spi_imx->clk);
+ spi_imx->spi_clk = clk_get_rate(spi_imx->clk);
if (!cpu_is_mx31() || !cpu_is_mx35())
- writel(1, mxc_spi->base + MXC_RESET);
+ writel(1, spi_imx->base + MXC_RESET);
- mxc_spi->intctrl(mxc_spi, 0);
+ spi_imx->intctrl(spi_imx, 0);
- ret = spi_bitbang_start(&mxc_spi->bitbang);
+ ret = spi_bitbang_start(&spi_imx->bitbang);
if (ret) {
dev_err(&pdev->dev, "bitbang start failed with %d\n", ret);
goto out_clk_put;
@@ -611,18 +606,18 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
return ret;
out_clk_put:
- clk_disable(mxc_spi->clk);
- clk_put(mxc_spi->clk);
+ clk_disable(spi_imx->clk);
+ clk_put(spi_imx->clk);
out_free_irq:
- free_irq(mxc_spi->irq, mxc_spi);
+ free_irq(spi_imx->irq, spi_imx);
out_iounmap:
- iounmap(mxc_spi->base);
+ iounmap(spi_imx->base);
out_release_mem:
release_mem_region(res->start, resource_size(res));
out_gpio_free:
for (i = 0; i < master->num_chipselect; i++)
- if (mxc_spi->chipselect[i] >= 0)
- gpio_free(mxc_spi->chipselect[i]);
+ if (spi_imx->chipselect[i] >= 0)
+ gpio_free(spi_imx->chipselect[i]);
out_master_put:
spi_master_put(master);
kfree(master);
@@ -630,24 +625,24 @@ out_master_put:
return ret;
}
-static int __exit mxc_spi_remove(struct platform_device *pdev)
+static int __exit spi_imx_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct mxc_spi_data *mxc_spi = spi_master_get_devdata(master);
+ struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
int i;
- spi_bitbang_stop(&mxc_spi->bitbang);
+ spi_bitbang_stop(&spi_imx->bitbang);
- writel(0, mxc_spi->base + MXC_CSPICTRL);
- clk_disable(mxc_spi->clk);
- clk_put(mxc_spi->clk);
- free_irq(mxc_spi->irq, mxc_spi);
- iounmap(mxc_spi->base);
+ writel(0, spi_imx->base + MXC_CSPICTRL);
+ clk_disable(spi_imx->clk);
+ clk_put(spi_imx->clk);
+ free_irq(spi_imx->irq, spi_imx);
+ iounmap(spi_imx->base);
for (i = 0; i < master->num_chipselect; i++)
- if (mxc_spi->chipselect[i] >= 0)
- gpio_free(mxc_spi->chipselect[i]);
+ if (spi_imx->chipselect[i] >= 0)
+ gpio_free(spi_imx->chipselect[i]);
spi_master_put(master);
@@ -658,27 +653,27 @@ static int __exit mxc_spi_remove(struct platform_device *pdev)
return 0;
}
-static struct platform_driver mxc_spi_driver = {
+static struct platform_driver spi_imx_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
- .probe = mxc_spi_probe,
- .remove = __exit_p(mxc_spi_remove),
+ .probe = spi_imx_probe,
+ .remove = __exit_p(spi_imx_remove),
};
-static int __init mxc_spi_init(void)
+static int __init spi_imx_init(void)
{
- return platform_driver_register(&mxc_spi_driver);
+ return platform_driver_register(&spi_imx_driver);
}
-static void __exit mxc_spi_exit(void)
+static void __exit spi_imx_exit(void)
{
- platform_driver_unregister(&mxc_spi_driver);
+ platform_driver_unregister(&spi_imx_driver);
}
-module_init(mxc_spi_init);
-module_exit(mxc_spi_exit);
+module_init(spi_imx_init);
+module_exit(spi_imx_exit);
MODULE_DESCRIPTION("SPI Master Controller driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index f921bd1109e..5d23983f02f 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -537,7 +537,7 @@ static int spidev_release(struct inode *inode, struct file *filp)
return status;
}
-static struct file_operations spidev_fops = {
+static const struct file_operations spidev_fops = {
.owner = THIS_MODULE,
/* REVISIT switch to aio primitives, so that userspace
* gets more complete API coverage. It'll simplify things
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
index ac8577358ba..c24e4e0367a 100644
--- a/drivers/staging/dst/dcore.c
+++ b/drivers/staging/dst/dcore.c
@@ -102,7 +102,7 @@ static int dst_request(struct request_queue *q, struct bio *bio)
struct dst_node *n = q->queuedata;
int err = -EIO;
- if (bio_empty_barrier(bio) && !q->prepare_discard_fn) {
+ if (bio_empty_barrier(bio) && !blk_queue_discard(q)) {
/*
* This is a dirty^Wnice hack, but if we complete this
* operation with -EOPNOTSUPP like intended, XFS
@@ -847,7 +847,7 @@ static dst_command_func dst_commands[] = {
/*
* Configuration parser.
*/
-static void cn_dst_callback(struct cn_msg *msg)
+static void cn_dst_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
struct dst_ctl *ctl;
int err;
@@ -855,6 +855,11 @@ static void cn_dst_callback(struct cn_msg *msg)
struct dst_node *n = NULL, *tmp;
unsigned int hash;
+ if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) {
+ err = -EPERM;
+ goto out;
+ }
+
if (msg->len < sizeof(struct dst_ctl)) {
err = -EBADMSG;
goto out;
diff --git a/drivers/staging/iio/light/tsl2561.c b/drivers/staging/iio/light/tsl2561.c
index ea8a5efc19b..fc2107f4c04 100644
--- a/drivers/staging/iio/light/tsl2561.c
+++ b/drivers/staging/iio/light/tsl2561.c
@@ -239,10 +239,6 @@ static int __devexit tsl2561_remove(struct i2c_client *client)
return tsl2561_powerdown(client);
}
-static unsigned short normal_i2c[] = { 0x29, 0x39, 0x49, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
static const struct i2c_device_id tsl2561_id[] = {
{ "tsl2561", 0 },
{ }
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
index 90f962ee5fd..5d04bf5b021 100644
--- a/drivers/staging/pohmelfs/config.c
+++ b/drivers/staging/pohmelfs/config.c
@@ -527,10 +527,13 @@ out_unlock:
return err;
}
-static void pohmelfs_cn_callback(struct cn_msg *msg)
+static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
int err;
+ if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
+ return;
+
switch (msg->flags) {
case POHMELFS_FLAGS_ADD:
case POHMELFS_FLAGS_DEL:
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index 333ee02e7b2..864f0ba6a34 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -993,7 +993,7 @@ skip_io_on_zombie:
return retval;
}
-static struct file_operations fops = {
+static const struct file_operations fops = {
.owner = THIS_MODULE,
.read = usbtmc_read,
.write = usbtmc_write,
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index c44367fea18..bf0f6520c6d 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -30,6 +30,7 @@
#include <linux/wait.h>
#include <linux/compiler.h>
#include <asm/uaccess.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 29500154d00..2d867fd2241 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -875,7 +875,7 @@ printer_ioctl(struct file *fd, unsigned int code, unsigned long arg)
}
/* used after endpoint configuration */
-static struct file_operations printer_io_operations = {
+static const struct file_operations printer_io_operations = {
.owner = THIS_MODULE,
.open = printer_open,
.read = printer_read,
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h
index 03087e7b919..9a537aa0796 100644
--- a/drivers/usb/gadget/r8a66597-udc.h
+++ b/drivers/usb/gadget/r8a66597-udc.h
@@ -131,31 +131,48 @@ static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
}
static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
- unsigned long offset, u16 *buf,
+ unsigned long offset,
+ unsigned char *buf,
int len)
{
+ unsigned long fifoaddr = r8a66597->reg + offset;
+ unsigned int data;
+ int i;
+
if (r8a66597->pdata->on_chip) {
- unsigned long fifoaddr = r8a66597->reg + offset;
- unsigned long count;
- union {
- unsigned long dword;
- unsigned char byte[4];
- } data;
- unsigned char *pb;
- int i;
-
- count = len / 4;
- insl(fifoaddr, buf, count);
-
- if (len & 0x00000003) {
- data.dword = inl(fifoaddr);
- pb = (unsigned char *)buf + count * 4;
- for (i = 0; i < (len & 0x00000003); i++)
- pb[i] = data.byte[i];
+ /* 32-bit accesses for on_chip controllers */
+
+ /* aligned buf case */
+ if (len >= 4 && !((unsigned long)buf & 0x03)) {
+ insl(fifoaddr, buf, len / 4);
+ buf += len & ~0x03;
+ len &= 0x03;
+ }
+
+ /* unaligned buf case */
+ for (i = 0; i < len; i++) {
+ if (!(i & 0x03))
+ data = inl(fifoaddr);
+
+ buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
}
} else {
- len = (len + 1) / 2;
- insw(r8a66597->reg + offset, buf, len);
+ /* 16-bit accesses for external controllers */
+
+ /* aligned buf case */
+ if (len >= 2 && !((unsigned long)buf & 0x01)) {
+ insw(fifoaddr, buf, len / 2);
+ buf += len & ~0x01;
+ len &= 0x01;
+ }
+
+ /* unaligned buf case */
+ for (i = 0; i < len; i++) {
+ if (!(i & 0x01))
+ data = inw(fifoaddr);
+
+ buf[i] = (data >> ((i & 0x01) * 8)) & 0xff;
+ }
}
}
@@ -166,38 +183,40 @@ static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
}
static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
- unsigned long offset, u16 *buf,
+ unsigned long offset,
+ unsigned char *buf,
int len)
{
unsigned long fifoaddr = r8a66597->reg + offset;
+ int adj = 0;
+ int i;
if (r8a66597->pdata->on_chip) {
- unsigned long count;
- unsigned char *pb;
- int i;
-
- count = len / 4;
- outsl(fifoaddr, buf, count);
-
- if (len & 0x00000003) {
- pb = (unsigned char *)buf + count * 4;
- for (i = 0; i < (len & 0x00000003); i++) {
- if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
- outb(pb[i], fifoaddr + i);
- else
- outb(pb[i], fifoaddr + 3 - i);
- }
+ /* 32-bit access only if buf is 32-bit aligned */
+ if (len >= 4 && !((unsigned long)buf & 0x03)) {
+ outsl(fifoaddr, buf, len / 4);
+ buf += len & ~0x03;
+ len &= 0x03;
}
} else {
- int odd = len & 0x0001;
-
- len = len / 2;
- outsw(fifoaddr, buf, len);
- if (unlikely(odd)) {
- buf = &buf[len];
- outb((unsigned char)*buf, fifoaddr);
+ /* 16-bit access only if buf is 16-bit aligned */
+ if (len >= 2 && !((unsigned long)buf & 0x01)) {
+ outsw(fifoaddr, buf, len / 2);
+ buf += len & ~0x01;
+ len &= 0x01;
}
}
+
+ /* adjust fifo address in the little endian case */
+ if (!(r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)) {
+ if (r8a66597->pdata->on_chip)
+ adj = 0x03; /* 32-bit wide */
+ else
+ adj = 0x01; /* 16-bit wide */
+ }
+
+ for (i = 0; i < len; i++)
+ outb(buf[i], fifoaddr + adj - (i & adj));
}
static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c
index cf2d45946c5..2273c815941 100644
--- a/drivers/usb/host/whci/debug.c
+++ b/drivers/usb/host/whci/debug.c
@@ -134,7 +134,7 @@ static int pzl_open(struct inode *inode, struct file *file)
return single_open(file, pzl_print, inode->i_private);
}
-static struct file_operations di_fops = {
+static const struct file_operations di_fops = {
.open = di_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -142,7 +142,7 @@ static struct file_operations di_fops = {
.owner = THIS_MODULE,
};
-static struct file_operations asl_fops = {
+static const struct file_operations asl_fops = {
.open = asl_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -150,7 +150,7 @@ static struct file_operations asl_fops = {
.owner = THIS_MODULE,
};
-static struct file_operations pzl_fops = {
+static const struct file_operations pzl_fops = {
.open = pzl_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index d645f3899fe..32d0199d0c3 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -429,8 +429,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
return read_count;
}
-static struct
-file_operations usb_rio_fops = {
+static const struct file_operations usb_rio_fops = {
.owner = THIS_MODULE,
.read = read_rio,
.write = write_rio,
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c
index 4a42993700c..2eecec0c13c 100644
--- a/drivers/uwb/uwb-debug.c
+++ b/drivers/uwb/uwb-debug.c
@@ -205,7 +205,7 @@ static ssize_t command_write(struct file *file, const char __user *buf,
return ret < 0 ? ret : len;
}
-static struct file_operations command_fops = {
+static const struct file_operations command_fops = {
.open = command_open,
.write = command_write,
.read = NULL,
@@ -255,7 +255,7 @@ static int reservations_open(struct inode *inode, struct file *file)
return single_open(file, reservations_print, inode->i_private);
}
-static struct file_operations reservations_fops = {
+static const struct file_operations reservations_fops = {
.open = reservations_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -283,7 +283,7 @@ static int drp_avail_open(struct inode *inode, struct file *file)
return single_open(file, drp_avail_print, inode->i_private);
}
-static struct file_operations drp_avail_fops = {
+static const struct file_operations drp_avail_fops = {
.open = drp_avail_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 42e1005e291..d065894ce38 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -26,7 +26,6 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
-#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <video/da8xx-fb.h>
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index f2de5a1acd6..5c5a1ad1d39 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -27,8 +27,6 @@
#include <mach/msm_iomap.h>
#include <mach/irqs.h>
#include <mach/board.h>
-#include <linux/delay.h>
-
#include <mach/msm_fb.h>
#include "mddi_hw.h"
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index d5e59556f9e..70dadf9d233 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -93,7 +93,7 @@ struct blizzard_reg_list {
};
/* These need to be saved / restored separately from the rest. */
-static struct blizzard_reg_list blizzard_pll_regs[] = {
+static const struct blizzard_reg_list blizzard_pll_regs[] = {
{
.start = 0x04, /* Don't save PLL ctrl (0x0C) */
.end = 0x0a,
@@ -104,7 +104,7 @@ static struct blizzard_reg_list blizzard_pll_regs[] = {
},
};
-static struct blizzard_reg_list blizzard_gen_regs[] = {
+static const struct blizzard_reg_list blizzard_gen_regs[] = {
{
.start = 0x18, /* SDRAM control */
.end = 0x20,
@@ -191,7 +191,7 @@ struct blizzard_struct {
struct omapfb_device *fbdev;
struct lcd_ctrl_extif *extif;
- struct lcd_ctrl *int_ctrl;
+ const struct lcd_ctrl *int_ctrl;
void (*power_up)(struct device *dev);
void (*power_down)(struct device *dev);
@@ -1372,7 +1372,7 @@ static void blizzard_get_caps(int plane, struct omapfb_caps *caps)
(1 << OMAPFB_COLOR_YUV420);
}
-static void _save_regs(struct blizzard_reg_list *list, int cnt)
+static void _save_regs(const struct blizzard_reg_list *list, int cnt)
{
int i;
@@ -1383,7 +1383,7 @@ static void _save_regs(struct blizzard_reg_list *list, int cnt)
}
}
-static void _restore_regs(struct blizzard_reg_list *list, int cnt)
+static void _restore_regs(const struct blizzard_reg_list *list, int cnt)
{
int i;
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 125e605b8c6..0d0c8c8b9b5 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -393,7 +393,7 @@ static void omapfb_sync(struct fb_info *fbi)
* Set fb_info.fix fields and also updates fbdev.
* When calling this fb_info.var must be set up already.
*/
-static void set_fb_fix(struct fb_info *fbi)
+static void set_fb_fix(struct fb_info *fbi, int from_init)
{
struct fb_fix_screeninfo *fix = &fbi->fix;
struct fb_var_screeninfo *var = &fbi->var;
@@ -403,10 +403,16 @@ static void set_fb_fix(struct fb_info *fbi)
rg = &plane->fbdev->mem_desc.region[plane->idx];
fbi->screen_base = rg->vaddr;
- mutex_lock(&fbi->mm_lock);
- fix->smem_start = rg->paddr;
- fix->smem_len = rg->size;
- mutex_unlock(&fbi->mm_lock);
+
+ if (!from_init) {
+ mutex_lock(&fbi->mm_lock);
+ fix->smem_start = rg->paddr;
+ fix->smem_len = rg->size;
+ mutex_unlock(&fbi->mm_lock);
+ } else {
+ fix->smem_start = rg->paddr;
+ fix->smem_len = rg->size;
+ }
fix->type = FB_TYPE_PACKED_PIXELS;
bpp = var->bits_per_pixel;
@@ -704,7 +710,7 @@ static int omapfb_set_par(struct fb_info *fbi)
int r = 0;
omapfb_rqueue_lock(fbdev);
- set_fb_fix(fbi);
+ set_fb_fix(fbi, 0);
r = ctrl_change_mode(fbi);
omapfb_rqueue_unlock(fbdev);
@@ -904,7 +910,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
if (old_size != size) {
if (size) {
memcpy(&fbi->var, new_var, sizeof(fbi->var));
- set_fb_fix(fbi);
+ set_fb_fix(fbi, 0);
} else {
/*
* Set these explicitly to indicate that the
@@ -1504,7 +1510,7 @@ static int fbinfo_init(struct omapfb_device *fbdev, struct fb_info *info)
var->bits_per_pixel = fbdev->panel->bpp;
set_fb_var(info, var);
- set_fb_fix(info);
+ set_fb_fix(info, 1);
r = fb_alloc_cmap(&info->cmap, 16, 0);
if (r != 0)
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index e98baf6916b..e35232a1857 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -67,11 +67,14 @@ static DEFINE_MUTEX(uvfb_lock);
* find the kernel part of the task struct, copy the registers and
* the buffer contents and then complete the task.
*/
-static void uvesafb_cn_callback(struct cn_msg *msg)
+static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
struct uvesafb_task *utask;
struct uvesafb_ktask *task;
+ if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
+ return;
+
if (msg->seq >= UVESAFB_TASKS_MAX)
return;
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
index df52cb355f7..406caa6a71c 100644
--- a/drivers/w1/masters/ds2482.c
+++ b/drivers/w1/masters/ds2482.c
@@ -24,19 +24,6 @@
#include "../w1_int.h"
/**
- * Address is selected using 2 pins, resulting in 4 possible addresses.
- * 0x18, 0x19, 0x1a, 0x1b
- * However, the chip cannot be detected without doing an i2c write,
- * so use the force module parameter.
- */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/**
- * Insmod parameters
- */
-I2C_CLIENT_INSMOD_1(ds2482);
-
-/**
* The DS2482 registers - there are 3 registers that are addressed by a read
* pointer. The read pointer is set by the last command executed.
*
@@ -96,8 +83,6 @@ static const u8 ds2482_chan_rd[8] =
static int ds2482_probe(struct i2c_client *client,
const struct i2c_device_id *id);
-static int ds2482_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info);
static int ds2482_remove(struct i2c_client *client);
@@ -117,8 +102,6 @@ static struct i2c_driver ds2482_driver = {
.probe = ds2482_probe,
.remove = ds2482_remove,
.id_table = ds2482_id,
- .detect = ds2482_detect,
- .address_data = &addr_data,
};
/*
@@ -425,19 +408,6 @@ static u8 ds2482_w1_reset_bus(void *data)
}
-static int ds2482_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info)
-{
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
- I2C_FUNC_SMBUS_BYTE))
- return -ENODEV;
-
- strlcpy(info->type, "ds2482", I2C_NAME_SIZE);
-
- return 0;
-}
-
static int ds2482_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -446,6 +416,11 @@ static int ds2482_probe(struct i2c_client *client,
int temp1;
int idx;
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+ I2C_FUNC_SMBUS_BYTE))
+ return -ENODEV;
+
if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 52ccb3d3a96..45c126fea31 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -306,7 +306,7 @@ static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rm
return error;
}
-static void w1_cn_callback(struct cn_msg *msg)
+static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1);
struct w1_netlink_cmd *cmd;
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c
index a9592d981b1..6c4269b836b 100644
--- a/drivers/xen/xenfs/xenbus.c
+++ b/drivers/xen/xenfs/xenbus.c
@@ -43,6 +43,7 @@
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/mount.h>
#include <linux/pagemap.h>
diff --git a/firmware/Makefile b/firmware/Makefile
index 5ea80b19785..a6c7c3e47e4 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -67,10 +67,13 @@ fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
e100/d102e_ucode.bin
fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
-fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis
+fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \
+ cis/DP83903.cis cis/NE2K.cis \
+ cis/tamarack.cis
fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
-fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis
+fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \
+ cis/COMpad2.cis cis/COMpad4.cis
fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
advansys/3550.bin advansys/38C0800.bin
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 3f8c4f6bc43..c437e14f0b1 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -597,6 +597,9 @@ Driver: PCMCIA_PCNET - NE2000 compatible PCMCIA adapter
File: cis/LA-PCM.cis
cis/PCMLM28.cis
+ cis/DP83903.cis
+ cis/NE2K.cis
+ cis/tamarack.cis
Licence: GPL
@@ -628,6 +631,8 @@ Driver: SERIAL_8250_CS - Serial PCMCIA adapter
File: cis/MT5634ZLX.cis
cis/RS-COM-2P.cis
+ cis/COMpad2.cis
+ cis/COMpad4.cis
Licence: GPL
diff --git a/firmware/cis/COMpad2.cis.ihex b/firmware/cis/COMpad2.cis.ihex
new file mode 100644
index 00000000000..1671c5e48ca
--- /dev/null
+++ b/firmware/cis/COMpad2.cis.ihex
@@ -0,0 +1,11 @@
+:1000000001030000FF151F0401414456414E5445B1
+:10001000434800434F4D7061642D33322F38350013
+:10002000312E300000FF210202011A0501050001F6
+:10003000031B0EC18118AA61E80207E8030730B864
+:100040009E1B08820108AA6030030F1B0883010869
+:10005000AA6040030F1B08840108AA6050030F1B0D
+:0D00600008850108AA6060030F1400FF006E
+:00000001FF
+#
+# Replacement CIS for Advantech COMpad-32/85
+#
diff --git a/firmware/cis/COMpad4.cis.ihex b/firmware/cis/COMpad4.cis.ihex
new file mode 100644
index 00000000000..27bbec1921b
--- /dev/null
+++ b/firmware/cis/COMpad4.cis.ihex
@@ -0,0 +1,9 @@
+:1000000001030000FF151F0401414456414E5445B1
+:10001000434800434F4D7061642D33322F383542D1
+:100020002D34000000FF210202011A050102000127
+:10003000011B0BC18118AA6040021F30B89E1B082B
+:0C004000820108AA6040031F1400FF00AA
+:00000001FF
+#
+# Replacement CIS for Advantech COMpad-32/85B-4
+#
diff --git a/firmware/cis/DP83903.cis.ihex b/firmware/cis/DP83903.cis.ihex
new file mode 100644
index 00000000000..6d73ea3cf1b
--- /dev/null
+++ b/firmware/cis/DP83903.cis.ihex
@@ -0,0 +1,14 @@
+:1000000001030000FF152904014D756C74696675C4
+:100010006E6374696F6E20436172640000004E531A
+:1000200043204D46204C414E2F4D6F64656D00FFBF
+:1000300020047501000021020000060B02004900A7
+:100040000000006A000000FF00130343495321022F
+:1000500006001A060517201077021B0C970179017C
+:10006000556530FFFF284000FF001303434953212B
+:100070000202001A060507401077021B09870119C2
+:0800800001552330FFFFFF00D2
+:00000001FF
+#
+# This CIS is for cards based on the National Semiconductor
+# DP83903 Multiple Function Interface Chip
+#
diff --git a/firmware/cis/NE2K.cis.ihex b/firmware/cis/NE2K.cis.ihex
new file mode 100644
index 00000000000..1bb40fc4759
--- /dev/null
+++ b/firmware/cis/NE2K.cis.ihex
@@ -0,0 +1,8 @@
+:1000000001030000FF1515040150434D4349410011
+:1000100045746865726E6574000000FF2102060079
+:100020001A050120F803031B09E001190155653089
+:06003000FFFF1400FF00B9
+:00000001FF
+#
+# Replacement CIS for various busted NE2000-compatible cards
+#
diff --git a/firmware/cis/tamarack.cis.ihex b/firmware/cis/tamarack.cis.ihex
new file mode 100644
index 00000000000..1e86547fb36
--- /dev/null
+++ b/firmware/cis/tamarack.cis.ihex
@@ -0,0 +1,10 @@
+:100000000103D400FF17034100FF152404015441EC
+:100010004D415241434B0045746865726E657400F2
+:10002000410030303437343331313830303100FF33
+:10003000210206001A050120F803031B14E08119B0
+:100040003F554D5D06864626E551000F100F30FFE7
+:05005000FF1400FF0099
+:00000001FF
+#
+# Replacement CIS for Surecom, Tamarack NE2000 cards
+#
diff --git a/fs/afs/cache.h b/fs/afs/cache.h
deleted file mode 100644
index 5c4f6b499e9..00000000000
--- a/fs/afs/cache.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* AFS local cache management interface
- *
- * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/fscache.h>
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 106be66dafd..6ece2a13bf7 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -18,10 +18,10 @@
#include <linux/key.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
+#include <linux/fscache.h>
#include "afs.h"
#include "afs_vl.h"
-#include "cache.h"
#define AFS_CELL_MAX_ADDRS 15
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index d11c51fc2a3..2ca7a7cafdb 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -8,8 +8,10 @@
*
*/
+#include <linux/cred.h>
#include <linux/file.h>
#include <linux/poll.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fs.h>
diff --git a/fs/bio.c b/fs/bio.c
index 76738005c8e..402cb84a92a 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -249,6 +249,7 @@ void bio_free(struct bio *bio, struct bio_set *bs)
mempool_free(p, bs->bio_pool);
}
+EXPORT_SYMBOL(bio_free);
void bio_init(struct bio *bio)
{
@@ -257,6 +258,7 @@ void bio_init(struct bio *bio)
bio->bi_comp_cpu = -1;
atomic_set(&bio->bi_cnt, 1);
}
+EXPORT_SYMBOL(bio_init);
/**
* bio_alloc_bioset - allocate a bio for I/O
@@ -311,6 +313,7 @@ err_free:
mempool_free(p, bs->bio_pool);
return NULL;
}
+EXPORT_SYMBOL(bio_alloc_bioset);
static void bio_fs_destructor(struct bio *bio)
{
@@ -337,6 +340,7 @@ struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
return bio;
}
+EXPORT_SYMBOL(bio_alloc);
static void bio_kmalloc_destructor(struct bio *bio)
{
@@ -380,6 +384,7 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
return bio;
}
+EXPORT_SYMBOL(bio_kmalloc);
void zero_fill_bio(struct bio *bio)
{
@@ -416,6 +421,7 @@ void bio_put(struct bio *bio)
bio->bi_destructor(bio);
}
}
+EXPORT_SYMBOL(bio_put);
inline int bio_phys_segments(struct request_queue *q, struct bio *bio)
{
@@ -424,6 +430,7 @@ inline int bio_phys_segments(struct request_queue *q, struct bio *bio)
return bio->bi_phys_segments;
}
+EXPORT_SYMBOL(bio_phys_segments);
/**
* __bio_clone - clone a bio
@@ -451,6 +458,7 @@ void __bio_clone(struct bio *bio, struct bio *bio_src)
bio->bi_size = bio_src->bi_size;
bio->bi_idx = bio_src->bi_idx;
}
+EXPORT_SYMBOL(__bio_clone);
/**
* bio_clone - clone a bio
@@ -482,6 +490,7 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
return b;
}
+EXPORT_SYMBOL(bio_clone);
/**
* bio_get_nr_vecs - return approx number of vecs
@@ -505,6 +514,7 @@ int bio_get_nr_vecs(struct block_device *bdev)
return nr_pages;
}
+EXPORT_SYMBOL(bio_get_nr_vecs);
static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
*page, unsigned int len, unsigned int offset,
@@ -635,6 +645,7 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page,
return __bio_add_page(q, bio, page, len, offset,
queue_max_hw_sectors(q));
}
+EXPORT_SYMBOL(bio_add_pc_page);
/**
* bio_add_page - attempt to add page to bio
@@ -655,6 +666,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q));
}
+EXPORT_SYMBOL(bio_add_page);
struct bio_map_data {
struct bio_vec *iovecs;
@@ -776,6 +788,7 @@ int bio_uncopy_user(struct bio *bio)
bio_put(bio);
return ret;
}
+EXPORT_SYMBOL(bio_uncopy_user);
/**
* bio_copy_user_iov - copy user data to bio
@@ -920,6 +933,7 @@ struct bio *bio_copy_user(struct request_queue *q, struct rq_map_data *map_data,
return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask);
}
+EXPORT_SYMBOL(bio_copy_user);
static struct bio *__bio_map_user_iov(struct request_queue *q,
struct block_device *bdev,
@@ -1050,6 +1064,7 @@ struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev,
return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask);
}
+EXPORT_SYMBOL(bio_map_user);
/**
* bio_map_user_iov - map user sg_iovec table into bio
@@ -1117,13 +1132,13 @@ void bio_unmap_user(struct bio *bio)
__bio_unmap_user(bio);
bio_put(bio);
}
+EXPORT_SYMBOL(bio_unmap_user);
static void bio_map_kern_endio(struct bio *bio, int err)
{
bio_put(bio);
}
-
static struct bio *__bio_map_kern(struct request_queue *q, void *data,
unsigned int len, gfp_t gfp_mask)
{
@@ -1189,6 +1204,7 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
bio_put(bio);
return ERR_PTR(-EINVAL);
}
+EXPORT_SYMBOL(bio_map_kern);
static void bio_copy_kern_endio(struct bio *bio, int err)
{
@@ -1250,6 +1266,7 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
return bio;
}
+EXPORT_SYMBOL(bio_copy_kern);
/*
* bio_set_pages_dirty() and bio_check_pages_dirty() are support functions
@@ -1400,6 +1417,7 @@ void bio_endio(struct bio *bio, int error)
if (bio->bi_end_io)
bio->bi_end_io(bio, error);
}
+EXPORT_SYMBOL(bio_endio);
void bio_pair_release(struct bio_pair *bp)
{
@@ -1410,6 +1428,7 @@ void bio_pair_release(struct bio_pair *bp)
mempool_free(bp, bp->bio2.bi_private);
}
}
+EXPORT_SYMBOL(bio_pair_release);
static void bio_pair_end_1(struct bio *bi, int err)
{
@@ -1477,6 +1496,7 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
return bp;
}
+EXPORT_SYMBOL(bio_split);
/**
* bio_sector_offset - Find hardware sector offset in bio
@@ -1547,6 +1567,7 @@ void bioset_free(struct bio_set *bs)
kfree(bs);
}
+EXPORT_SYMBOL(bioset_free);
/**
* bioset_create - Create a bio_set
@@ -1592,6 +1613,7 @@ bad:
bioset_free(bs);
return NULL;
}
+EXPORT_SYMBOL(bioset_create);
static void __init biovec_init_slabs(void)
{
@@ -1636,29 +1658,4 @@ static int __init init_bio(void)
return 0;
}
-
subsys_initcall(init_bio);
-
-EXPORT_SYMBOL(bio_alloc);
-EXPORT_SYMBOL(bio_kmalloc);
-EXPORT_SYMBOL(bio_put);
-EXPORT_SYMBOL(bio_free);
-EXPORT_SYMBOL(bio_endio);
-EXPORT_SYMBOL(bio_init);
-EXPORT_SYMBOL(__bio_clone);
-EXPORT_SYMBOL(bio_clone);
-EXPORT_SYMBOL(bio_phys_segments);
-EXPORT_SYMBOL(bio_add_page);
-EXPORT_SYMBOL(bio_add_pc_page);
-EXPORT_SYMBOL(bio_get_nr_vecs);
-EXPORT_SYMBOL(bio_map_user);
-EXPORT_SYMBOL(bio_unmap_user);
-EXPORT_SYMBOL(bio_map_kern);
-EXPORT_SYMBOL(bio_copy_kern);
-EXPORT_SYMBOL(bio_pair_release);
-EXPORT_SYMBOL(bio_split);
-EXPORT_SYMBOL(bio_copy_user);
-EXPORT_SYMBOL(bio_uncopy_user);
-EXPORT_SYMBOL(bioset_create);
-EXPORT_SYMBOL(bioset_free);
-EXPORT_SYMBOL(bio_alloc_bioset);
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index f128427b995..69b355ae7f4 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -27,7 +27,7 @@
#include "btrfs_inode.h"
#include "xattr.h"
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_BTRFS_POSIX_ACL
static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
{
@@ -313,7 +313,7 @@ struct xattr_handler btrfs_xattr_acl_access_handler = {
.set = btrfs_xattr_acl_access_set,
};
-#else /* CONFIG_FS_POSIX_ACL */
+#else /* CONFIG_BTRFS_POSIX_ACL */
int btrfs_acl_chmod(struct inode *inode)
{
@@ -325,4 +325,4 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir)
return 0;
}
-#endif /* CONFIG_FS_POSIX_ACL */
+#endif /* CONFIG_BTRFS_POSIX_ACL */
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 82ee56bba29..a54d354cefc 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -128,6 +128,14 @@ struct btrfs_inode {
u64 last_unlink_trans;
/*
+ * These two counters are for delalloc metadata reservations. We keep
+ * track of how many extents we've accounted for vs how many extents we
+ * have.
+ */
+ int delalloc_reserved_extents;
+ int delalloc_extents;
+
+ /*
* ordered_data_close is set by truncate when a file that used
* to have good data has been truncated to zero. When it is set
* the btrfs file release call will add this inode to the
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 80599b4e42b..dd8ced9814c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -675,18 +675,19 @@ struct btrfs_space_info {
current allocations */
u64 bytes_readonly; /* total bytes that are read only */
u64 bytes_super; /* total bytes reserved for the super blocks */
-
- /* delalloc accounting */
- u64 bytes_delalloc; /* number of bytes reserved for allocation,
- this space is not necessarily reserved yet
- by the allocator */
+ u64 bytes_root; /* the number of bytes needed to commit a
+ transaction */
u64 bytes_may_use; /* number of bytes that may be used for
- delalloc */
+ delalloc/allocations */
+ u64 bytes_delalloc; /* number of bytes currently reserved for
+ delayed allocation */
int full; /* indicates that we cannot allocate any more
chunks for this space */
int force_alloc; /* set if we need to force a chunk alloc for
this space */
+ int force_delalloc; /* make people start doing filemap_flush until
+ we're under a threshold */
struct list_head list;
@@ -695,6 +696,9 @@ struct btrfs_space_info {
spinlock_t lock;
struct rw_semaphore groups_sem;
atomic_t caching_threads;
+
+ int allocating_chunk;
+ wait_queue_head_t wait;
};
/*
@@ -2022,7 +2026,12 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde);
void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
-int btrfs_check_metadata_free_space(struct btrfs_root *root);
+int btrfs_reserve_metadata_space(struct btrfs_root *root, int num_items);
+int btrfs_unreserve_metadata_space(struct btrfs_root *root, int num_items);
+int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
+ struct inode *inode, int num_items);
+int btrfs_reserve_metadata_for_delalloc(struct btrfs_root *root,
+ struct inode *inode, int num_items);
int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
u64 bytes);
void btrfs_free_reserved_data_space(struct btrfs_root *root,
@@ -2326,7 +2335,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync);
int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
int skip_pinned);
int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
-extern struct file_operations btrfs_file_operations;
+extern const struct file_operations btrfs_file_operations;
int btrfs_drop_extents(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct inode *inode,
u64 start, u64 end, u64 locked_end,
@@ -2357,7 +2366,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options);
int btrfs_sync_fs(struct super_block *sb, int wait);
/* acl.c */
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_BTRFS_POSIX_ACL
int btrfs_check_acl(struct inode *inode, int mask);
#else
#define btrfs_check_acl NULL
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 644e796fd64..af0435f79fa 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -822,14 +822,14 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
int btrfs_write_tree_block(struct extent_buffer *buf)
{
- return btrfs_fdatawrite_range(buf->first_page->mapping, buf->start,
- buf->start + buf->len - 1, WB_SYNC_ALL);
+ return filemap_fdatawrite_range(buf->first_page->mapping, buf->start,
+ buf->start + buf->len - 1);
}
int btrfs_wait_tree_block_writeback(struct extent_buffer *buf)
{
- return btrfs_wait_on_page_writeback_range(buf->first_page->mapping,
- buf->start, buf->start + buf->len - 1);
+ return filemap_fdatawait_range(buf->first_page->mapping,
+ buf->start, buf->start + buf->len - 1);
}
struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
@@ -1630,7 +1630,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
fs_info->sb = sb;
fs_info->max_extent = (u64)-1;
fs_info->max_inline = 8192 * 1024;
- fs_info->metadata_ratio = 8;
+ fs_info->metadata_ratio = 0;
fs_info->thread_pool_size = min_t(unsigned long,
num_online_cpus() + 2, 8);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 993f93ff7ba..359a754c782 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -68,6 +68,8 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans,
struct extent_buffer **must_clean);
static int find_next_key(struct btrfs_path *path, int level,
struct btrfs_key *key);
+static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
+ int dump_block_groups);
static noinline int
block_group_cache_done(struct btrfs_block_group_cache *cache)
@@ -2765,67 +2767,346 @@ void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode)
alloc_target);
}
+static u64 calculate_bytes_needed(struct btrfs_root *root, int num_items)
+{
+ u64 num_bytes;
+ int level;
+
+ level = BTRFS_MAX_LEVEL - 2;
+ /*
+ * NOTE: these calculations are absolutely the worst possible case.
+ * This assumes that _every_ item we insert will require a new leaf, and
+ * that the tree has grown to its maximum level size.
+ */
+
+ /*
+ * for every item we insert we could insert both an extent item and a
+ * extent ref item. Then for ever item we insert, we will need to cow
+ * both the original leaf, plus the leaf to the left and right of it.
+ *
+ * Unless we are talking about the extent root, then we just want the
+ * number of items * 2, since we just need the extent item plus its ref.
+ */
+ if (root == root->fs_info->extent_root)
+ num_bytes = num_items * 2;
+ else
+ num_bytes = (num_items + (2 * num_items)) * 3;
+
+ /*
+ * num_bytes is total number of leaves we could need times the leaf
+ * size, and then for every leaf we could end up cow'ing 2 nodes per
+ * level, down to the leaf level.
+ */
+ num_bytes = (num_bytes * root->leafsize) +
+ (num_bytes * (level * 2)) * root->nodesize;
+
+ return num_bytes;
+}
+
/*
- * for now this just makes sure we have at least 5% of our metadata space free
- * for use.
+ * Unreserve metadata space for delalloc. If we have less reserved credits than
+ * we have extents, this function does nothing.
*/
-int btrfs_check_metadata_free_space(struct btrfs_root *root)
+int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
+ struct inode *inode, int num_items)
{
struct btrfs_fs_info *info = root->fs_info;
struct btrfs_space_info *meta_sinfo;
- u64 alloc_target, thresh;
- int committed = 0, ret;
+ u64 num_bytes;
+ u64 alloc_target;
+ bool bug = false;
/* get the space info for where the metadata will live */
alloc_target = btrfs_get_alloc_profile(root, 0);
meta_sinfo = __find_space_info(info, alloc_target);
- if (!meta_sinfo)
- goto alloc;
-again:
+ num_bytes = calculate_bytes_needed(root->fs_info->extent_root,
+ num_items);
+
spin_lock(&meta_sinfo->lock);
- if (!meta_sinfo->full)
- thresh = meta_sinfo->total_bytes * 80;
- else
- thresh = meta_sinfo->total_bytes * 95;
+ if (BTRFS_I(inode)->delalloc_reserved_extents <=
+ BTRFS_I(inode)->delalloc_extents) {
+ spin_unlock(&meta_sinfo->lock);
+ return 0;
+ }
+
+ BTRFS_I(inode)->delalloc_reserved_extents--;
+ BUG_ON(BTRFS_I(inode)->delalloc_reserved_extents < 0);
+
+ if (meta_sinfo->bytes_delalloc < num_bytes) {
+ bug = true;
+ meta_sinfo->bytes_delalloc = 0;
+ } else {
+ meta_sinfo->bytes_delalloc -= num_bytes;
+ }
+ spin_unlock(&meta_sinfo->lock);
+ BUG_ON(bug);
+
+ return 0;
+}
+
+static void check_force_delalloc(struct btrfs_space_info *meta_sinfo)
+{
+ u64 thresh;
+
+ thresh = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
+ meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
+ meta_sinfo->bytes_super + meta_sinfo->bytes_root +
+ meta_sinfo->bytes_may_use;
+
+ thresh = meta_sinfo->total_bytes - thresh;
+ thresh *= 80;
do_div(thresh, 100);
+ if (thresh <= meta_sinfo->bytes_delalloc)
+ meta_sinfo->force_delalloc = 1;
+ else
+ meta_sinfo->force_delalloc = 0;
+}
- if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
- meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
- meta_sinfo->bytes_super > thresh) {
- struct btrfs_trans_handle *trans;
- if (!meta_sinfo->full) {
- meta_sinfo->force_alloc = 1;
+static int maybe_allocate_chunk(struct btrfs_root *root,
+ struct btrfs_space_info *info)
+{
+ struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
+ struct btrfs_trans_handle *trans;
+ bool wait = false;
+ int ret = 0;
+ u64 min_metadata;
+ u64 free_space;
+
+ free_space = btrfs_super_total_bytes(disk_super);
+ /*
+ * we allow the metadata to grow to a max of either 5gb or 5% of the
+ * space in the volume.
+ */
+ min_metadata = min((u64)5 * 1024 * 1024 * 1024,
+ div64_u64(free_space * 5, 100));
+ if (info->total_bytes >= min_metadata) {
+ spin_unlock(&info->lock);
+ return 0;
+ }
+
+ if (info->full) {
+ spin_unlock(&info->lock);
+ return 0;
+ }
+
+ if (!info->allocating_chunk) {
+ info->force_alloc = 1;
+ info->allocating_chunk = 1;
+ init_waitqueue_head(&info->wait);
+ } else {
+ wait = true;
+ }
+
+ spin_unlock(&info->lock);
+
+ if (wait) {
+ wait_event(info->wait,
+ !info->allocating_chunk);
+ return 1;
+ }
+
+ trans = btrfs_start_transaction(root, 1);
+ if (!trans) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = do_chunk_alloc(trans, root->fs_info->extent_root,
+ 4096 + 2 * 1024 * 1024,
+ info->flags, 0);
+ btrfs_end_transaction(trans, root);
+ if (ret)
+ goto out;
+out:
+ spin_lock(&info->lock);
+ info->allocating_chunk = 0;
+ spin_unlock(&info->lock);
+ wake_up(&info->wait);
+
+ if (ret)
+ return 0;
+ return 1;
+}
+
+/*
+ * Reserve metadata space for delalloc.
+ */
+int btrfs_reserve_metadata_for_delalloc(struct btrfs_root *root,
+ struct inode *inode, int num_items)
+{
+ struct btrfs_fs_info *info = root->fs_info;
+ struct btrfs_space_info *meta_sinfo;
+ u64 num_bytes;
+ u64 used;
+ u64 alloc_target;
+ int flushed = 0;
+ int force_delalloc;
+
+ /* get the space info for where the metadata will live */
+ alloc_target = btrfs_get_alloc_profile(root, 0);
+ meta_sinfo = __find_space_info(info, alloc_target);
+
+ num_bytes = calculate_bytes_needed(root->fs_info->extent_root,
+ num_items);
+again:
+ spin_lock(&meta_sinfo->lock);
+
+ force_delalloc = meta_sinfo->force_delalloc;
+
+ if (unlikely(!meta_sinfo->bytes_root))
+ meta_sinfo->bytes_root = calculate_bytes_needed(root, 6);
+
+ if (!flushed)
+ meta_sinfo->bytes_delalloc += num_bytes;
+
+ used = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
+ meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
+ meta_sinfo->bytes_super + meta_sinfo->bytes_root +
+ meta_sinfo->bytes_may_use + meta_sinfo->bytes_delalloc;
+
+ if (used > meta_sinfo->total_bytes) {
+ flushed++;
+
+ if (flushed == 1) {
+ if (maybe_allocate_chunk(root, meta_sinfo))
+ goto again;
+ flushed++;
+ } else {
spin_unlock(&meta_sinfo->lock);
-alloc:
- trans = btrfs_start_transaction(root, 1);
- if (!trans)
- return -ENOMEM;
+ }
- ret = do_chunk_alloc(trans, root->fs_info->extent_root,
- 2 * 1024 * 1024, alloc_target, 0);
- btrfs_end_transaction(trans, root);
- if (!meta_sinfo) {
- meta_sinfo = __find_space_info(info,
- alloc_target);
- }
+ if (flushed == 2) {
+ filemap_flush(inode->i_mapping);
+ goto again;
+ } else if (flushed == 3) {
+ btrfs_start_delalloc_inodes(root);
+ btrfs_wait_ordered_extents(root, 0);
goto again;
}
+ spin_lock(&meta_sinfo->lock);
+ meta_sinfo->bytes_delalloc -= num_bytes;
spin_unlock(&meta_sinfo->lock);
+ printk(KERN_ERR "enospc, has %d, reserved %d\n",
+ BTRFS_I(inode)->delalloc_extents,
+ BTRFS_I(inode)->delalloc_reserved_extents);
+ dump_space_info(meta_sinfo, 0, 0);
+ return -ENOSPC;
+ }
- if (!committed) {
- committed = 1;
- trans = btrfs_join_transaction(root, 1);
- if (!trans)
- return -ENOMEM;
- ret = btrfs_commit_transaction(trans, root);
- if (ret)
- return ret;
+ BTRFS_I(inode)->delalloc_reserved_extents++;
+ check_force_delalloc(meta_sinfo);
+ spin_unlock(&meta_sinfo->lock);
+
+ if (!flushed && force_delalloc)
+ filemap_flush(inode->i_mapping);
+
+ return 0;
+}
+
+/*
+ * unreserve num_items number of items worth of metadata space. This needs to
+ * be paired with btrfs_reserve_metadata_space.
+ *
+ * NOTE: if you have the option, run this _AFTER_ you do a
+ * btrfs_end_transaction, since btrfs_end_transaction will run delayed ref
+ * oprations which will result in more used metadata, so we want to make sure we
+ * can do that without issue.
+ */
+int btrfs_unreserve_metadata_space(struct btrfs_root *root, int num_items)
+{
+ struct btrfs_fs_info *info = root->fs_info;
+ struct btrfs_space_info *meta_sinfo;
+ u64 num_bytes;
+ u64 alloc_target;
+ bool bug = false;
+
+ /* get the space info for where the metadata will live */
+ alloc_target = btrfs_get_alloc_profile(root, 0);
+ meta_sinfo = __find_space_info(info, alloc_target);
+
+ num_bytes = calculate_bytes_needed(root, num_items);
+
+ spin_lock(&meta_sinfo->lock);
+ if (meta_sinfo->bytes_may_use < num_bytes) {
+ bug = true;
+ meta_sinfo->bytes_may_use = 0;
+ } else {
+ meta_sinfo->bytes_may_use -= num_bytes;
+ }
+ spin_unlock(&meta_sinfo->lock);
+
+ BUG_ON(bug);
+
+ return 0;
+}
+
+/*
+ * Reserve some metadata space for use. We'll calculate the worste case number
+ * of bytes that would be needed to modify num_items number of items. If we
+ * have space, fantastic, if not, you get -ENOSPC. Please call
+ * btrfs_unreserve_metadata_space when you are done for the _SAME_ number of
+ * items you reserved, since whatever metadata you needed should have already
+ * been allocated.
+ *
+ * This will commit the transaction to make more space if we don't have enough
+ * metadata space. THe only time we don't do this is if we're reserving space
+ * inside of a transaction, then we will just return -ENOSPC and it is the
+ * callers responsibility to handle it properly.
+ */
+int btrfs_reserve_metadata_space(struct btrfs_root *root, int num_items)
+{
+ struct btrfs_fs_info *info = root->fs_info;
+ struct btrfs_space_info *meta_sinfo;
+ u64 num_bytes;
+ u64 used;
+ u64 alloc_target;
+ int retries = 0;
+
+ /* get the space info for where the metadata will live */
+ alloc_target = btrfs_get_alloc_profile(root, 0);
+ meta_sinfo = __find_space_info(info, alloc_target);
+
+ num_bytes = calculate_bytes_needed(root, num_items);
+again:
+ spin_lock(&meta_sinfo->lock);
+
+ if (unlikely(!meta_sinfo->bytes_root))
+ meta_sinfo->bytes_root = calculate_bytes_needed(root, 6);
+
+ if (!retries)
+ meta_sinfo->bytes_may_use += num_bytes;
+
+ used = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
+ meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
+ meta_sinfo->bytes_super + meta_sinfo->bytes_root +
+ meta_sinfo->bytes_may_use + meta_sinfo->bytes_delalloc;
+
+ if (used > meta_sinfo->total_bytes) {
+ retries++;
+ if (retries == 1) {
+ if (maybe_allocate_chunk(root, meta_sinfo))
+ goto again;
+ retries++;
+ } else {
+ spin_unlock(&meta_sinfo->lock);
+ }
+
+ if (retries == 2) {
+ btrfs_start_delalloc_inodes(root);
+ btrfs_wait_ordered_extents(root, 0);
goto again;
}
+ spin_lock(&meta_sinfo->lock);
+ meta_sinfo->bytes_may_use -= num_bytes;
+ spin_unlock(&meta_sinfo->lock);
+
+ dump_space_info(meta_sinfo, 0, 0);
return -ENOSPC;
}
+
+ check_force_delalloc(meta_sinfo);
spin_unlock(&meta_sinfo->lock);
return 0;
@@ -2888,7 +3169,7 @@ alloc:
spin_unlock(&data_sinfo->lock);
/* commit the current transaction and try again */
- if (!committed) {
+ if (!committed && !root->fs_info->open_ioctl_trans) {
committed = 1;
trans = btrfs_join_transaction(root, 1);
if (!trans)
@@ -2916,7 +3197,7 @@ alloc:
BTRFS_I(inode)->reserved_bytes += bytes;
spin_unlock(&data_sinfo->lock);
- return btrfs_check_metadata_free_space(root);
+ return 0;
}
/*
@@ -3015,17 +3296,15 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
BUG_ON(!space_info);
spin_lock(&space_info->lock);
- if (space_info->force_alloc) {
+ if (space_info->force_alloc)
force = 1;
- space_info->force_alloc = 0;
- }
if (space_info->full) {
spin_unlock(&space_info->lock);
goto out;
}
thresh = space_info->total_bytes - space_info->bytes_readonly;
- thresh = div_factor(thresh, 6);
+ thresh = div_factor(thresh, 8);
if (!force &&
(space_info->bytes_used + space_info->bytes_pinned +
space_info->bytes_reserved + alloc_bytes) < thresh) {
@@ -3039,7 +3318,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
* we keep a reasonable number of metadata chunks allocated in the
* FS as well.
*/
- if (flags & BTRFS_BLOCK_GROUP_DATA) {
+ if (flags & BTRFS_BLOCK_GROUP_DATA && fs_info->metadata_ratio) {
fs_info->data_chunk_allocations++;
if (!(fs_info->data_chunk_allocations %
fs_info->metadata_ratio))
@@ -3047,8 +3326,11 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
}
ret = btrfs_alloc_chunk(trans, extent_root, flags);
+ spin_lock(&space_info->lock);
if (ret)
space_info->full = 1;
+ space_info->force_alloc = 0;
+ spin_unlock(&space_info->lock);
out:
mutex_unlock(&extent_root->fs_info->chunk_mutex);
return ret;
@@ -4063,21 +4345,32 @@ loop:
return ret;
}
-static void dump_space_info(struct btrfs_space_info *info, u64 bytes)
+static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
+ int dump_block_groups)
{
struct btrfs_block_group_cache *cache;
+ spin_lock(&info->lock);
printk(KERN_INFO "space_info has %llu free, is %sfull\n",
(unsigned long long)(info->total_bytes - info->bytes_used -
- info->bytes_pinned - info->bytes_reserved),
+ info->bytes_pinned - info->bytes_reserved -
+ info->bytes_super),
(info->full) ? "" : "not ");
printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu,"
- " may_use=%llu, used=%llu\n",
+ " may_use=%llu, used=%llu, root=%llu, super=%llu, reserved=%llu"
+ "\n",
(unsigned long long)info->total_bytes,
(unsigned long long)info->bytes_pinned,
(unsigned long long)info->bytes_delalloc,
(unsigned long long)info->bytes_may_use,
- (unsigned long long)info->bytes_used);
+ (unsigned long long)info->bytes_used,
+ (unsigned long long)info->bytes_root,
+ (unsigned long long)info->bytes_super,
+ (unsigned long long)info->bytes_reserved);
+ spin_unlock(&info->lock);
+
+ if (!dump_block_groups)
+ return;
down_read(&info->groups_sem);
list_for_each_entry(cache, &info->block_groups, list) {
@@ -4145,7 +4438,7 @@ again:
printk(KERN_ERR "btrfs allocation failed flags %llu, "
"wanted %llu\n", (unsigned long long)data,
(unsigned long long)num_bytes);
- dump_space_info(sinfo, num_bytes);
+ dump_space_info(sinfo, num_bytes, 1);
}
return ret;
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 0cb88f8146e..de1793ba004 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -280,6 +280,14 @@ static struct extent_buffer *buffer_search(struct extent_io_tree *tree,
return NULL;
}
+static void merge_cb(struct extent_io_tree *tree, struct extent_state *new,
+ struct extent_state *other)
+{
+ if (tree->ops && tree->ops->merge_extent_hook)
+ tree->ops->merge_extent_hook(tree->mapping->host, new,
+ other);
+}
+
/*
* utility function to look for merge candidates inside a given range.
* Any extents with matching state are merged together into a single
@@ -303,6 +311,7 @@ static int merge_state(struct extent_io_tree *tree,
other = rb_entry(other_node, struct extent_state, rb_node);
if (other->end == state->start - 1 &&
other->state == state->state) {
+ merge_cb(tree, state, other);
state->start = other->start;
other->tree = NULL;
rb_erase(&other->rb_node, &tree->state);
@@ -314,33 +323,37 @@ static int merge_state(struct extent_io_tree *tree,
other = rb_entry(other_node, struct extent_state, rb_node);
if (other->start == state->end + 1 &&
other->state == state->state) {
+ merge_cb(tree, state, other);
other->start = state->start;
state->tree = NULL;
rb_erase(&state->rb_node, &tree->state);
free_extent_state(state);
+ state = NULL;
}
}
+
return 0;
}
-static void set_state_cb(struct extent_io_tree *tree,
+static int set_state_cb(struct extent_io_tree *tree,
struct extent_state *state,
unsigned long bits)
{
if (tree->ops && tree->ops->set_bit_hook) {
- tree->ops->set_bit_hook(tree->mapping->host, state->start,
- state->end, state->state, bits);
+ return tree->ops->set_bit_hook(tree->mapping->host,
+ state->start, state->end,
+ state->state, bits);
}
+
+ return 0;
}
static void clear_state_cb(struct extent_io_tree *tree,
struct extent_state *state,
unsigned long bits)
{
- if (tree->ops && tree->ops->clear_bit_hook) {
- tree->ops->clear_bit_hook(tree->mapping->host, state->start,
- state->end, state->state, bits);
- }
+ if (tree->ops && tree->ops->clear_bit_hook)
+ tree->ops->clear_bit_hook(tree->mapping->host, state, bits);
}
/*
@@ -358,6 +371,7 @@ static int insert_state(struct extent_io_tree *tree,
int bits)
{
struct rb_node *node;
+ int ret;
if (end < start) {
printk(KERN_ERR "btrfs end < start %llu %llu\n",
@@ -365,11 +379,14 @@ static int insert_state(struct extent_io_tree *tree,
(unsigned long long)start);
WARN_ON(1);
}
- if (bits & EXTENT_DIRTY)
- tree->dirty_bytes += end - start + 1;
state->start = start;
state->end = end;
- set_state_cb(tree, state, bits);
+ ret = set_state_cb(tree, state, bits);
+ if (ret)
+ return ret;
+
+ if (bits & EXTENT_DIRTY)
+ tree->dirty_bytes += end - start + 1;
state->state |= bits;
node = tree_insert(&tree->state, end, &state->rb_node);
if (node) {
@@ -387,6 +404,15 @@ static int insert_state(struct extent_io_tree *tree,
return 0;
}
+static int split_cb(struct extent_io_tree *tree, struct extent_state *orig,
+ u64 split)
+{
+ if (tree->ops && tree->ops->split_extent_hook)
+ return tree->ops->split_extent_hook(tree->mapping->host,
+ orig, split);
+ return 0;
+}
+
/*
* split a given extent state struct in two, inserting the preallocated
* struct 'prealloc' as the newly created second half. 'split' indicates an
@@ -405,6 +431,9 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig,
struct extent_state *prealloc, u64 split)
{
struct rb_node *node;
+
+ split_cb(tree, orig, split);
+
prealloc->start = orig->start;
prealloc->end = split - 1;
prealloc->state = orig->state;
@@ -542,8 +571,8 @@ hit_next:
if (err)
goto out;
if (state->end <= end) {
- set |= clear_state_bit(tree, state, bits,
- wake, delete);
+ set |= clear_state_bit(tree, state, bits, wake,
+ delete);
if (last_end == (u64)-1)
goto out;
start = last_end + 1;
@@ -561,12 +590,11 @@ hit_next:
prealloc = alloc_extent_state(GFP_ATOMIC);
err = split_state(tree, state, prealloc, end + 1);
BUG_ON(err == -EEXIST);
-
if (wake)
wake_up(&state->wq);
- set |= clear_state_bit(tree, prealloc, bits,
- wake, delete);
+ set |= clear_state_bit(tree, prealloc, bits, wake, delete);
+
prealloc = NULL;
goto out;
}
@@ -667,16 +695,23 @@ out:
return 0;
}
-static void set_state_bits(struct extent_io_tree *tree,
+static int set_state_bits(struct extent_io_tree *tree,
struct extent_state *state,
int bits)
{
+ int ret;
+
+ ret = set_state_cb(tree, state, bits);
+ if (ret)
+ return ret;
+
if ((bits & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) {
u64 range = state->end - state->start + 1;
tree->dirty_bytes += range;
}
- set_state_cb(tree, state, bits);
state->state |= bits;
+
+ return 0;
}
static void cache_state(struct extent_state *state,
@@ -758,7 +793,10 @@ hit_next:
goto out;
}
- set_state_bits(tree, state, bits);
+ err = set_state_bits(tree, state, bits);
+ if (err)
+ goto out;
+
cache_state(state, cached_state);
merge_state(tree, state);
if (last_end == (u64)-1)
@@ -805,7 +843,9 @@ hit_next:
if (err)
goto out;
if (state->end <= end) {
- set_state_bits(tree, state, bits);
+ err = set_state_bits(tree, state, bits);
+ if (err)
+ goto out;
cache_state(state, cached_state);
merge_state(tree, state);
if (last_end == (u64)-1)
@@ -829,11 +869,13 @@ hit_next:
this_end = last_start - 1;
err = insert_state(tree, prealloc, start, this_end,
bits);
- cache_state(prealloc, cached_state);
- prealloc = NULL;
BUG_ON(err == -EEXIST);
- if (err)
+ if (err) {
+ prealloc = NULL;
goto out;
+ }
+ cache_state(prealloc, cached_state);
+ prealloc = NULL;
start = this_end + 1;
goto search_again;
}
@@ -852,7 +894,11 @@ hit_next:
err = split_state(tree, state, prealloc, end + 1);
BUG_ON(err == -EEXIST);
- set_state_bits(tree, prealloc, bits);
+ err = set_state_bits(tree, prealloc, bits);
+ if (err) {
+ prealloc = NULL;
+ goto out;
+ }
cache_state(prealloc, cached_state);
merge_state(tree, prealloc);
prealloc = NULL;
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 14ed16fd862..4794ec891fe 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -60,8 +60,13 @@ struct extent_io_ops {
struct extent_state *state, int uptodate);
int (*set_bit_hook)(struct inode *inode, u64 start, u64 end,
unsigned long old, unsigned long bits);
- int (*clear_bit_hook)(struct inode *inode, u64 start, u64 end,
- unsigned long old, unsigned long bits);
+ int (*clear_bit_hook)(struct inode *inode, struct extent_state *state,
+ unsigned long bits);
+ int (*merge_extent_hook)(struct inode *inode,
+ struct extent_state *new,
+ struct extent_state *other);
+ int (*split_extent_hook)(struct inode *inode,
+ struct extent_state *orig, u64 split);
int (*write_cache_pages_lock_hook)(struct page *page);
};
@@ -79,10 +84,14 @@ struct extent_state {
u64 start;
u64 end; /* inclusive */
struct rb_node rb_node;
+
+ /* ADD NEW ELEMENTS AFTER THIS */
struct extent_io_tree *tree;
wait_queue_head_t wq;
atomic_t refs;
unsigned long state;
+ u64 split_start;
+ u64 split_end;
/* for use by the FS */
u64 private;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index a3492a3ad96..f19e1259a97 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -123,7 +123,10 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
end_of_last_block = start_pos + num_bytes - 1;
- btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
+ err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
+ if (err)
+ return err;
+
for (i = 0; i < num_pages; i++) {
struct page *p = pages[i];
SetPageUptodate(p);
@@ -917,21 +920,35 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
start_pos = pos;
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
+
+ /* do the reserve before the mutex lock in case we have to do some
+ * flushing. We wouldn't deadlock, but this is more polite.
+ */
+ err = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+ if (err)
+ goto out_nolock;
+
+ mutex_lock(&inode->i_mutex);
+
current->backing_dev_info = inode->i_mapping->backing_dev_info;
err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
if (err)
- goto out_nolock;
+ goto out;
+
if (count == 0)
- goto out_nolock;
+ goto out;
err = file_remove_suid(file);
if (err)
- goto out_nolock;
+ goto out;
+
file_update_time(file);
pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL);
- mutex_lock(&inode->i_mutex);
+ /* generic_write_checks can change our pos */
+ start_pos = pos;
+
BTRFS_I(inode)->sequence++;
first_index = pos >> PAGE_CACHE_SHIFT;
last_index = (pos + count) >> PAGE_CACHE_SHIFT;
@@ -1005,9 +1022,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
}
if (will_write) {
- btrfs_fdatawrite_range(inode->i_mapping, pos,
- pos + write_bytes - 1,
- WB_SYNC_ALL);
+ filemap_fdatawrite_range(inode->i_mapping, pos,
+ pos + write_bytes - 1);
} else {
balance_dirty_pages_ratelimited_nr(inode->i_mapping,
num_pages);
@@ -1028,6 +1044,7 @@ out:
mutex_unlock(&inode->i_mutex);
if (ret)
err = ret;
+ btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
out_nolock:
kfree(pages);
@@ -1196,7 +1213,7 @@ static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
return 0;
}
-struct file_operations btrfs_file_operations = {
+const struct file_operations btrfs_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.aio_read = generic_file_aio_read,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e9b76bcd1c1..112e5aa8589 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -62,7 +62,7 @@ static const struct inode_operations btrfs_special_inode_operations;
static const struct inode_operations btrfs_file_inode_operations;
static const struct address_space_operations btrfs_aops;
static const struct address_space_operations btrfs_symlink_aops;
-static struct file_operations btrfs_dir_file_operations;
+static const struct file_operations btrfs_dir_file_operations;
static struct extent_io_ops btrfs_extent_io_ops;
static struct kmem_cache *btrfs_inode_cachep;
@@ -1159,6 +1159,83 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
return ret;
}
+static int btrfs_split_extent_hook(struct inode *inode,
+ struct extent_state *orig, u64 split)
+{
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ u64 size;
+
+ if (!(orig->state & EXTENT_DELALLOC))
+ return 0;
+
+ size = orig->end - orig->start + 1;
+ if (size > root->fs_info->max_extent) {
+ u64 num_extents;
+ u64 new_size;
+
+ new_size = orig->end - split + 1;
+ num_extents = div64_u64(size + root->fs_info->max_extent - 1,
+ root->fs_info->max_extent);
+
+ /*
+ * if we break a large extent up then leave delalloc_extents be,
+ * since we've already accounted for the large extent.
+ */
+ if (div64_u64(new_size + root->fs_info->max_extent - 1,
+ root->fs_info->max_extent) < num_extents)
+ return 0;
+ }
+
+ BTRFS_I(inode)->delalloc_extents++;
+
+ return 0;
+}
+
+/*
+ * extent_io.c merge_extent_hook, used to track merged delayed allocation
+ * extents so we can keep track of new extents that are just merged onto old
+ * extents, such as when we are doing sequential writes, so we can properly
+ * account for the metadata space we'll need.
+ */
+static int btrfs_merge_extent_hook(struct inode *inode,
+ struct extent_state *new,
+ struct extent_state *other)
+{
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ u64 new_size, old_size;
+ u64 num_extents;
+
+ /* not delalloc, ignore it */
+ if (!(other->state & EXTENT_DELALLOC))
+ return 0;
+
+ old_size = other->end - other->start + 1;
+ if (new->start < other->start)
+ new_size = other->end - new->start + 1;
+ else
+ new_size = new->end - other->start + 1;
+
+ /* we're not bigger than the max, unreserve the space and go */
+ if (new_size <= root->fs_info->max_extent) {
+ BTRFS_I(inode)->delalloc_extents--;
+ return 0;
+ }
+
+ /*
+ * If we grew by another max_extent, just return, we want to keep that
+ * reserved amount.
+ */
+ num_extents = div64_u64(old_size + root->fs_info->max_extent - 1,
+ root->fs_info->max_extent);
+ if (div64_u64(new_size + root->fs_info->max_extent - 1,
+ root->fs_info->max_extent) > num_extents)
+ return 0;
+
+ BTRFS_I(inode)->delalloc_extents--;
+
+ return 0;
+}
+
/*
* extent_io.c set_bit_hook, used to track delayed allocation
* bytes in this file, and to maintain the list of inodes that
@@ -1167,6 +1244,7 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
unsigned long old, unsigned long bits)
{
+
/*
* set_bit and clear bit hooks normally require _irqsave/restore
* but in this case, we are only testeing for the DELALLOC
@@ -1174,6 +1252,8 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
*/
if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
struct btrfs_root *root = BTRFS_I(inode)->root;
+
+ BTRFS_I(inode)->delalloc_extents++;
btrfs_delalloc_reserve_space(root, inode, end - start + 1);
spin_lock(&root->fs_info->delalloc_lock);
BTRFS_I(inode)->delalloc_bytes += end - start + 1;
@@ -1190,22 +1270,27 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
/*
* extent_io.c clear_bit_hook, see set_bit_hook for why
*/
-static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
- unsigned long old, unsigned long bits)
+static int btrfs_clear_bit_hook(struct inode *inode,
+ struct extent_state *state, unsigned long bits)
{
/*
* set_bit and clear bit hooks normally require _irqsave/restore
* but in this case, we are only testeing for the DELALLOC
* bit, which is only set or cleared with irqs on
*/
- if ((old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
+ if ((state->state & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
struct btrfs_root *root = BTRFS_I(inode)->root;
+ BTRFS_I(inode)->delalloc_extents--;
+ btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
+
spin_lock(&root->fs_info->delalloc_lock);
- if (end - start + 1 > root->fs_info->delalloc_bytes) {
+ if (state->end - state->start + 1 >
+ root->fs_info->delalloc_bytes) {
printk(KERN_INFO "btrfs warning: delalloc account "
"%llu %llu\n",
- (unsigned long long)end - start + 1,
+ (unsigned long long)
+ state->end - state->start + 1,
(unsigned long long)
root->fs_info->delalloc_bytes);
btrfs_delalloc_free_space(root, inode, (u64)-1);
@@ -1213,9 +1298,12 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
BTRFS_I(inode)->delalloc_bytes = 0;
} else {
btrfs_delalloc_free_space(root, inode,
- end - start + 1);
- root->fs_info->delalloc_bytes -= end - start + 1;
- BTRFS_I(inode)->delalloc_bytes -= end - start + 1;
+ state->end -
+ state->start + 1);
+ root->fs_info->delalloc_bytes -= state->end -
+ state->start + 1;
+ BTRFS_I(inode)->delalloc_bytes -= state->end -
+ state->start + 1;
}
if (BTRFS_I(inode)->delalloc_bytes == 0 &&
!list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
@@ -2950,7 +3038,12 @@ again:
goto again;
}
- btrfs_set_extent_delalloc(inode, page_start, page_end);
+ ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+ if (ret) {
+ unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ goto out_unlock;
+ }
+
ret = 0;
if (offset != PAGE_CACHE_SIZE) {
kaddr = kmap(page);
@@ -2981,15 +3074,11 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
u64 last_byte;
u64 cur_offset;
u64 hole_size;
- int err;
+ int err = 0;
if (size <= hole_start)
return 0;
- err = btrfs_check_metadata_free_space(root);
- if (err)
- return err;
-
btrfs_truncate_page(inode->i_mapping, inode->i_size);
while (1) {
@@ -3024,12 +3113,18 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
cur_offset, &hint_byte, 1);
if (err)
break;
+
+ err = btrfs_reserve_metadata_space(root, 1);
+ if (err)
+ break;
+
err = btrfs_insert_file_extent(trans, root,
inode->i_ino, cur_offset, 0,
0, hole_size, 0, hole_size,
0, 0, 0);
btrfs_drop_extent_cache(inode, hole_start,
last_byte - 1, 0);
+ btrfs_unreserve_metadata_space(root, 1);
}
free_extent_map(em);
cur_offset = last_byte;
@@ -3990,11 +4085,18 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
if (!new_valid_dev(rdev))
return -EINVAL;
- err = btrfs_check_metadata_free_space(root);
+ /*
+ * 2 for inode item and ref
+ * 2 for dir items
+ * 1 for xattr if selinux is on
+ */
+ err = btrfs_reserve_metadata_space(root, 5);
if (err)
- goto fail;
+ return err;
trans = btrfs_start_transaction(root, 1);
+ if (!trans)
+ goto fail;
btrfs_set_trans_block_group(trans, dir);
err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -4032,6 +4134,7 @@ out_unlock:
nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
fail:
+ btrfs_unreserve_metadata_space(root, 5);
if (drop_inode) {
inode_dec_link_count(inode);
iput(inode);
@@ -4052,10 +4155,18 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
u64 objectid;
u64 index = 0;
- err = btrfs_check_metadata_free_space(root);
+ /*
+ * 2 for inode item and ref
+ * 2 for dir items
+ * 1 for xattr if selinux is on
+ */
+ err = btrfs_reserve_metadata_space(root, 5);
if (err)
- goto fail;
+ return err;
+
trans = btrfs_start_transaction(root, 1);
+ if (!trans)
+ goto fail;
btrfs_set_trans_block_group(trans, dir);
err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -4096,6 +4207,7 @@ out_unlock:
nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
fail:
+ btrfs_unreserve_metadata_space(root, 5);
if (drop_inode) {
inode_dec_link_count(inode);
iput(inode);
@@ -4118,10 +4230,16 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
if (inode->i_nlink == 0)
return -ENOENT;
- btrfs_inc_nlink(inode);
- err = btrfs_check_metadata_free_space(root);
+ /*
+ * 1 item for inode ref
+ * 2 items for dir items
+ */
+ err = btrfs_reserve_metadata_space(root, 3);
if (err)
- goto fail;
+ return err;
+
+ btrfs_inc_nlink(inode);
+
err = btrfs_set_inode_index(dir, &index);
if (err)
goto fail;
@@ -4145,6 +4263,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
fail:
+ btrfs_unreserve_metadata_space(root, 3);
if (drop_inode) {
inode_dec_link_count(inode);
iput(inode);
@@ -4164,17 +4283,21 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
u64 index = 0;
unsigned long nr = 1;
- err = btrfs_check_metadata_free_space(root);
+ /*
+ * 2 items for inode and ref
+ * 2 items for dir items
+ * 1 for xattr if selinux is on
+ */
+ err = btrfs_reserve_metadata_space(root, 5);
if (err)
- goto out_unlock;
+ return err;
trans = btrfs_start_transaction(root, 1);
- btrfs_set_trans_block_group(trans, dir);
-
- if (IS_ERR(trans)) {
- err = PTR_ERR(trans);
+ if (!trans) {
+ err = -ENOMEM;
goto out_unlock;
}
+ btrfs_set_trans_block_group(trans, dir);
err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
if (err) {
@@ -4223,6 +4346,7 @@ out_fail:
btrfs_end_transaction_throttle(trans, root);
out_unlock:
+ btrfs_unreserve_metadata_space(root, 5);
if (drop_on_err)
iput(inode);
btrfs_btree_balance_dirty(root, nr);
@@ -4747,6 +4871,13 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
goto out;
}
+ ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
+ if (ret) {
+ btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+ ret = VM_FAULT_SIGBUS;
+ goto out;
+ }
+
ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
again:
lock_page(page);
@@ -4778,7 +4909,23 @@ again:
goto again;
}
- btrfs_set_extent_delalloc(inode, page_start, page_end);
+ /*
+ * XXX - page_mkwrite gets called every time the page is dirtied, even
+ * if it was already dirty, so for space accounting reasons we need to
+ * clear any delalloc bits for the range we are fixing to save. There
+ * is probably a better way to do this, but for now keep consistent with
+ * prepare_pages in the normal write path.
+ */
+ clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
+ EXTENT_DIRTY | EXTENT_DELALLOC, GFP_NOFS);
+
+ ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
+ if (ret) {
+ unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
+ ret = VM_FAULT_SIGBUS;
+ btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
+ goto out_unlock;
+ }
ret = 0;
/* page is wholly or partially inside EOF */
@@ -4801,6 +4948,7 @@ again:
unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
out_unlock:
+ btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
if (!ret)
return VM_FAULT_LOCKED;
unlock_page(page);
@@ -4917,6 +5065,8 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
return NULL;
ei->last_trans = 0;
ei->logged_trans = 0;
+ ei->delalloc_extents = 0;
+ ei->delalloc_reserved_extents = 0;
btrfs_ordered_inode_tree_init(&ei->ordered_tree);
INIT_LIST_HEAD(&ei->i_orphan);
INIT_LIST_HEAD(&ei->ordered_operations);
@@ -5070,7 +5220,12 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
new_inode->i_size > BTRFS_EMPTY_DIR_SIZE)
return -ENOTEMPTY;
- ret = btrfs_check_metadata_free_space(root);
+ /*
+ * 2 items for dir items
+ * 1 item for orphan entry
+ * 1 item for ref
+ */
+ ret = btrfs_reserve_metadata_space(root, 4);
if (ret)
return ret;
@@ -5185,6 +5340,8 @@ out_fail:
if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
up_read(&root->fs_info->subvol_sem);
+
+ btrfs_unreserve_metadata_space(root, 4);
return ret;
}
@@ -5256,11 +5413,18 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root))
return -ENAMETOOLONG;
- err = btrfs_check_metadata_free_space(root);
+ /*
+ * 2 items for inode item and ref
+ * 2 items for dir items
+ * 1 item for xattr if selinux is on
+ */
+ err = btrfs_reserve_metadata_space(root, 5);
if (err)
- goto out_fail;
+ return err;
trans = btrfs_start_transaction(root, 1);
+ if (!trans)
+ goto out_fail;
btrfs_set_trans_block_group(trans, dir);
err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -5341,6 +5505,7 @@ out_unlock:
nr = trans->blocks_used;
btrfs_end_transaction_throttle(trans, root);
out_fail:
+ btrfs_unreserve_metadata_space(root, 5);
if (drop_inode) {
inode_dec_link_count(inode);
iput(inode);
@@ -5362,6 +5527,11 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans,
while (num_bytes > 0) {
alloc_size = min(num_bytes, root->fs_info->max_extent);
+
+ ret = btrfs_reserve_metadata_space(root, 1);
+ if (ret)
+ goto out;
+
ret = btrfs_reserve_extent(trans, root, alloc_size,
root->sectorsize, 0, alloc_hint,
(u64)-1, &ins, 1);
@@ -5381,6 +5551,7 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans,
num_bytes -= ins.offset;
cur_offset += ins.offset;
alloc_hint = ins.objectid + ins.offset;
+ btrfs_unreserve_metadata_space(root, 1);
}
out:
if (cur_offset > start) {
@@ -5544,7 +5715,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
.permission = btrfs_permission,
};
-static struct file_operations btrfs_dir_file_operations = {
+static const struct file_operations btrfs_dir_file_operations = {
.llseek = generic_file_llseek,
.read = generic_read_dir,
.readdir = btrfs_real_readdir,
@@ -5566,6 +5737,8 @@ static struct extent_io_ops btrfs_extent_io_ops = {
.readpage_io_failed_hook = btrfs_io_failed_hook,
.set_bit_hook = btrfs_set_bit_hook,
.clear_bit_hook = btrfs_clear_bit_hook,
+ .merge_extent_hook = btrfs_merge_extent_hook,
+ .split_extent_hook = btrfs_split_extent_hook,
};
/*
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a8577a7f26a..9a780c8d0ac 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -239,7 +239,13 @@ static noinline int create_subvol(struct btrfs_root *root,
u64 index = 0;
unsigned long nr = 1;
- ret = btrfs_check_metadata_free_space(root);
+ /*
+ * 1 - inode item
+ * 2 - refs
+ * 1 - root item
+ * 2 - dir items
+ */
+ ret = btrfs_reserve_metadata_space(root, 6);
if (ret)
return ret;
@@ -340,6 +346,9 @@ fail:
err = btrfs_commit_transaction(trans, root);
if (err && !ret)
ret = err;
+
+ btrfs_unreserve_metadata_space(root, 6);
+ btrfs_btree_balance_dirty(root, nr);
return ret;
}
@@ -355,19 +364,27 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
if (!root->ref_cows)
return -EINVAL;
- ret = btrfs_check_metadata_free_space(root);
+ /*
+ * 1 - inode item
+ * 2 - refs
+ * 1 - root item
+ * 2 - dir items
+ */
+ ret = btrfs_reserve_metadata_space(root, 6);
if (ret)
goto fail_unlock;
pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
if (!pending_snapshot) {
ret = -ENOMEM;
+ btrfs_unreserve_metadata_space(root, 6);
goto fail_unlock;
}
pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS);
if (!pending_snapshot->name) {
ret = -ENOMEM;
kfree(pending_snapshot);
+ btrfs_unreserve_metadata_space(root, 6);
goto fail_unlock;
}
memcpy(pending_snapshot->name, name, namelen);
@@ -1215,15 +1232,15 @@ static long btrfs_ioctl_trans_start(struct file *file)
struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_trans_handle *trans;
- int ret = 0;
+ int ret;
+ ret = -EPERM;
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ goto out;
- if (file->private_data) {
- ret = -EINPROGRESS;
+ ret = -EINPROGRESS;
+ if (file->private_data)
goto out;
- }
ret = mnt_want_write(file->f_path.mnt);
if (ret)
@@ -1233,12 +1250,19 @@ static long btrfs_ioctl_trans_start(struct file *file)
root->fs_info->open_ioctl_trans++;
mutex_unlock(&root->fs_info->trans_mutex);
+ ret = -ENOMEM;
trans = btrfs_start_ioctl_transaction(root, 0);
- if (trans)
- file->private_data = trans;
- else
- ret = -ENOMEM;
- /*printk(KERN_INFO "btrfs_ioctl_trans_start on %p\n", file);*/
+ if (!trans)
+ goto out_drop;
+
+ file->private_data = trans;
+ return 0;
+
+out_drop:
+ mutex_lock(&root->fs_info->trans_mutex);
+ root->fs_info->open_ioctl_trans--;
+ mutex_unlock(&root->fs_info->trans_mutex);
+ mnt_drop_write(file->f_path.mnt);
out:
return ret;
}
@@ -1254,24 +1278,20 @@ long btrfs_ioctl_trans_end(struct file *file)
struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_trans_handle *trans;
- int ret = 0;
trans = file->private_data;
- if (!trans) {
- ret = -EINVAL;
- goto out;
- }
- btrfs_end_transaction(trans, root);
+ if (!trans)
+ return -EINVAL;
file->private_data = NULL;
+ btrfs_end_transaction(trans, root);
+
mutex_lock(&root->fs_info->trans_mutex);
root->fs_info->open_ioctl_trans--;
mutex_unlock(&root->fs_info->trans_mutex);
mnt_drop_write(file->f_path.mnt);
-
-out:
- return ret;
+ return 0;
}
long btrfs_ioctl(struct file *file, unsigned int
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index b5d6d24726b..897fba835f8 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -458,7 +458,7 @@ void btrfs_start_ordered_extent(struct inode *inode,
* start IO on any dirty ones so the wait doesn't stall waiting
* for pdflush to find them
*/
- btrfs_fdatawrite_range(inode->i_mapping, start, end, WB_SYNC_ALL);
+ filemap_fdatawrite_range(inode->i_mapping, start, end);
if (wait) {
wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE,
&entry->flags));
@@ -488,17 +488,15 @@ again:
/* start IO across the range first to instantiate any delalloc
* extents
*/
- btrfs_fdatawrite_range(inode->i_mapping, start, orig_end, WB_SYNC_ALL);
+ filemap_fdatawrite_range(inode->i_mapping, start, orig_end);
/* The compression code will leave pages locked but return from
* writepage without setting the page writeback. Starting again
* with WB_SYNC_ALL will end up waiting for the IO to actually start.
*/
- btrfs_fdatawrite_range(inode->i_mapping, start, orig_end, WB_SYNC_ALL);
+ filemap_fdatawrite_range(inode->i_mapping, start, orig_end);
- btrfs_wait_on_page_writeback_range(inode->i_mapping,
- start >> PAGE_CACHE_SHIFT,
- orig_end >> PAGE_CACHE_SHIFT);
+ filemap_fdatawait_range(inode->i_mapping, start, orig_end);
end = orig_end;
found = 0;
@@ -716,89 +714,6 @@ out:
}
-/**
- * taken from mm/filemap.c because it isn't exported
- *
- * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range
- * @mapping: address space structure to write
- * @start: offset in bytes where the range starts
- * @end: offset in bytes where the range ends (inclusive)
- * @sync_mode: enable synchronous operation
- *
- * Start writeback against all of a mapping's dirty pages that lie
- * within the byte offsets <start, end> inclusive.
- *
- * If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as
- * opposed to a regular memory cleansing writeback. The difference between
- * these two operations is that if a dirty page/buffer is encountered, it must
- * be waited upon, and not just skipped over.
- */
-int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start,
- loff_t end, int sync_mode)
-{
- struct writeback_control wbc = {
- .sync_mode = sync_mode,
- .nr_to_write = mapping->nrpages * 2,
- .range_start = start,
- .range_end = end,
- };
- return btrfs_writepages(mapping, &wbc);
-}
-
-/**
- * taken from mm/filemap.c because it isn't exported
- *
- * wait_on_page_writeback_range - wait for writeback to complete
- * @mapping: target address_space
- * @start: beginning page index
- * @end: ending page index
- *
- * Wait for writeback to complete against pages indexed by start->end
- * inclusive
- */
-int btrfs_wait_on_page_writeback_range(struct address_space *mapping,
- pgoff_t start, pgoff_t end)
-{
- struct pagevec pvec;
- int nr_pages;
- int ret = 0;
- pgoff_t index;
-
- if (end < start)
- return 0;
-
- pagevec_init(&pvec, 0);
- index = start;
- while ((index <= end) &&
- (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
- PAGECACHE_TAG_WRITEBACK,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1)) != 0) {
- unsigned i;
-
- for (i = 0; i < nr_pages; i++) {
- struct page *page = pvec.pages[i];
-
- /* until radix tree lookup accepts end_index */
- if (page->index > end)
- continue;
-
- wait_on_page_writeback(page);
- if (PageError(page))
- ret = -EIO;
- }
- pagevec_release(&pvec);
- cond_resched();
- }
-
- /* Check for outstanding write errors */
- if (test_and_clear_bit(AS_ENOSPC, &mapping->flags))
- ret = -ENOSPC;
- if (test_and_clear_bit(AS_EIO, &mapping->flags))
- ret = -EIO;
-
- return ret;
-}
-
/*
* add a given inode to the list of inodes that must be fully on
* disk before a transaction commit finishes.
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index 993a7ea45c7..f82e87488ca 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -153,10 +153,6 @@ btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset);
int btrfs_ordered_update_i_size(struct inode *inode,
struct btrfs_ordered_extent *ordered);
int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum);
-int btrfs_wait_on_page_writeback_range(struct address_space *mapping,
- pgoff_t start, pgoff_t end);
-int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start,
- loff_t end, int sync_mode);
int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only);
int btrfs_run_ordered_operations(struct btrfs_root *root, int wait);
int btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 67035385444..9de9b223641 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -344,7 +344,9 @@ static int btrfs_fill_super(struct super_block *sb,
sb->s_export_op = &btrfs_export_ops;
sb->s_xattr = btrfs_xattr_handlers;
sb->s_time_gran = 1;
+#ifdef CONFIG_BTRFS_POSIX_ACL
sb->s_flags |= MS_POSIXACL;
+#endif
tree_root = open_ctree(sb, fs_devices, (char *)data);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 88f866f85e7..0b8f36d4400 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -186,6 +186,9 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
h->alloc_exclude_start = 0;
h->delayed_ref_updates = 0;
+ if (!current->journal_info)
+ current->journal_info = h;
+
root->fs_info->running_transaction->use_count++;
record_root_in_trans(h, root);
mutex_unlock(&root->fs_info->trans_mutex);
@@ -317,6 +320,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
wake_up(&cur_trans->writer_wait);
put_transaction(cur_trans);
mutex_unlock(&info->trans_mutex);
+
+ if (current->journal_info == trans)
+ current->journal_info = NULL;
memset(trans, 0, sizeof(*trans));
kmem_cache_free(btrfs_trans_handle_cachep, trans);
@@ -743,6 +749,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
memcpy(&pending->root_key, &key, sizeof(key));
fail:
kfree(new_root_item);
+ btrfs_unreserve_metadata_space(root, 6);
return ret;
}
@@ -1059,6 +1066,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
mutex_unlock(&root->fs_info->trans_mutex);
+ if (current->journal_info == trans)
+ current->journal_info = NULL;
+
kmem_cache_free(btrfs_trans_handle_cachep, trans);
return ret;
}
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 23e7d36ff32..7eda483d7b5 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -446,8 +446,10 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
goto error;
device->name = kstrdup(orig_dev->name, GFP_NOFS);
- if (!device->name)
+ if (!device->name) {
+ kfree(device);
goto error;
+ }
device->devid = orig_dev->devid;
device->work.func = pending_bios_fn;
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index a9d3bf4d268..b0fc93f95fd 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -260,7 +260,7 @@ err:
* attributes are handled directly.
*/
struct xattr_handler *btrfs_xattr_handlers[] = {
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_BTRFS_POSIX_ACL
&btrfs_xattr_acl_access_handler,
&btrfs_xattr_acl_default_handler,
#endif
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 0376ac66c44..be4392ca209 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/time.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
diff --git a/fs/ecryptfs/Kconfig b/fs/ecryptfs/Kconfig
index 8aadb99b763..1cd6d9d3e29 100644
--- a/fs/ecryptfs/Kconfig
+++ b/fs/ecryptfs/Kconfig
@@ -1,8 +1,9 @@
config ECRYPT_FS
tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && KEYS && NET
+ depends on EXPERIMENTAL && KEYS && CRYPTO
select CRYPTO_ECB
select CRYPTO_CBC
+ select CRYPTO_MD5
help
Encrypted filesystem that operates on the VFS layer. See
<file:Documentation/filesystems/ecryptfs.txt> to learn more about
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 101fe4c7b1e..c6ac85d6c70 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -35,6 +35,7 @@
#include <linux/key.h>
#include <linux/parser.h>
#include <linux/fs_stack.h>
+#include <linux/ima.h>
#include "ecryptfs_kernel.h"
/**
@@ -118,6 +119,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
const struct cred *cred = current_cred();
struct ecryptfs_inode_info *inode_info =
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
+ int opened_lower_file = 0;
int rc = 0;
mutex_lock(&inode_info->lower_file_mutex);
@@ -134,9 +136,12 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
"for lower_dentry [0x%p] and lower_mnt [0x%p]; "
"rc = [%d]\n", lower_dentry, lower_mnt, rc);
inode_info->lower_file = NULL;
- }
+ } else
+ opened_lower_file = 1;
}
mutex_unlock(&inode_info->lower_file_mutex);
+ if (opened_lower_file)
+ ima_counts_get(inode_info->lower_file);
return rc;
}
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index d5c0ea2e8f2..9f2d45d75b1 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -26,20 +26,6 @@ config EXT4_FS
If unsure, say N.
-config EXT4DEV_COMPAT
- bool "Enable ext4dev compatibility"
- depends on EXT4_FS
- help
- Starting with 2.6.28, the name of the ext4 filesystem was
- renamed from ext4dev to ext4. Unfortunately there are some
- legacy userspace programs (such as klibc's fstype) have
- "ext4dev" hardcoded.
-
- To enable backwards compatibility so that systems that are
- still expecting to mount ext4 filesystems using ext4dev,
- choose Y here. This feature will go away by 2.6.31, so
- please arrange to get your userspace programs fixed!
-
config EXT4_FS_XATTR
bool "Ext4 extended attributes"
depends on EXT4_FS
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ec367bce721..5c5bc5dafff 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1146,8 +1146,8 @@ static int check_block_validity(struct inode *inode, const char *msg,
}
/*
- * Return the number of dirty pages in the given inode starting at
- * page frame idx.
+ * Return the number of contiguous dirty pages in a given inode
+ * starting at page frame idx.
*/
static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
unsigned int max_pages)
@@ -1181,15 +1181,15 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
unlock_page(page);
break;
}
- head = page_buffers(page);
- bh = head;
- do {
- if (!buffer_delay(bh) &&
- !buffer_unwritten(bh)) {
- done = 1;
- break;
- }
- } while ((bh = bh->b_this_page) != head);
+ if (page_has_buffers(page)) {
+ bh = head = page_buffers(page);
+ do {
+ if (!buffer_delay(bh) &&
+ !buffer_unwritten(bh))
+ done = 1;
+ bh = bh->b_this_page;
+ } while (!done && (bh != head));
+ }
unlock_page(page);
if (done)
break;
@@ -3378,6 +3378,7 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
ssize_t ret;
int orphan = 0;
size_t count = iov_length(iov, nr_segs);
+ int retries = 0;
if (rw == WRITE) {
loff_t final_size = offset + count;
@@ -3400,9 +3401,12 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
}
}
+retry:
ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs,
ext4_get_block, NULL);
+ if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+ goto retry;
if (orphan) {
int err;
@@ -5612,14 +5616,12 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
*/
void ext4_dirty_inode(struct inode *inode)
{
- handle_t *current_handle = ext4_journal_current_handle();
handle_t *handle;
handle = ext4_journal_start(inode, 2);
if (IS_ERR(handle))
goto out;
- jbd_debug(5, "marking dirty. outer handle=%p\n", current_handle);
ext4_mark_inode_dirty(handle, inode);
ext4_journal_stop(handle);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 12e726a7073..312211ee05a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3966,27 +3966,6 @@ static struct file_system_type ext4_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
-#ifdef CONFIG_EXT4DEV_COMPAT
-static int ext4dev_get_sb(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *data,struct vfsmount *mnt)
-{
- printk(KERN_WARNING "EXT4-fs (%s): Update your userspace programs "
- "to mount using ext4\n", dev_name);
- printk(KERN_WARNING "EXT4-fs (%s): ext4dev backwards compatibility "
- "will go away by 2.6.31\n", dev_name);
- return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
-}
-
-static struct file_system_type ext4dev_fs_type = {
- .owner = THIS_MODULE,
- .name = "ext4dev",
- .get_sb = ext4dev_get_sb,
- .kill_sb = kill_block_super,
- .fs_flags = FS_REQUIRES_DEV,
-};
-MODULE_ALIAS("ext4dev");
-#endif
-
static int __init init_ext4_fs(void)
{
int err;
@@ -4011,13 +3990,6 @@ static int __init init_ext4_fs(void)
err = register_filesystem(&ext4_fs_type);
if (err)
goto out;
-#ifdef CONFIG_EXT4DEV_COMPAT
- err = register_filesystem(&ext4dev_fs_type);
- if (err) {
- unregister_filesystem(&ext4_fs_type);
- goto out;
- }
-#endif
return 0;
out:
destroy_inodecache();
@@ -4036,9 +4008,6 @@ out4:
static void __exit exit_ext4_fs(void)
{
unregister_filesystem(&ext4_fs_type);
-#ifdef CONFIG_EXT4DEV_COMPAT
- unregister_filesystem(&ext4dev_fs_type);
-#endif
destroy_inodecache();
exit_ext4_xattr();
exit_ext4_mballoc();
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 761af77491f..b0ab5219bec 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -770,7 +770,7 @@ static int jbd2_seq_info_release(struct inode *inode, struct file *file)
return seq_release(inode, file);
}
-static struct file_operations jbd2_seq_info_fops = {
+static const struct file_operations jbd2_seq_info_fops = {
.owner = THIS_MODULE,
.open = jbd2_seq_info_open,
.read = seq_read,
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 63976c0ccc2..99ea196f071 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1180,7 +1180,7 @@ static int nfs4_init_client(struct nfs_client *clp,
1, flags & NFS_MOUNT_NORESVPORT);
if (error < 0)
goto error;
- memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
+ strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
error = nfs_idmap_new(clp);
if (error < 0) {
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 2636c26d56f..fa3408f2011 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -121,7 +121,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
if (IS_ERR(mnt_path))
- return mnt;
+ return ERR_CAST(mnt_path);
mountdata->mnt_path = mnt_path;
maxbuflen = mnt_path - 1 - page2;
@@ -132,15 +132,15 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
if (buf->len <= 0 || buf->len >= maxbuflen)
continue;
- mountdata->addr = (struct sockaddr *)&addr;
-
if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len))
continue;
- mountdata->addrlen = nfs_parse_server_name(buf->data,
- buf->len,
- mountdata->addr, mountdata->addrlen);
+
+ mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len,
+ (struct sockaddr *)&addr, sizeof(addr));
if (mountdata->addrlen == 0)
continue;
+
+ mountdata->addr = (struct sockaddr *)&addr;
rpc_set_port(mountdata->addr, NFS_PORT);
memcpy(page2, buf->data, buf->len);
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index e27c6cef18f..0156c01c212 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -127,12 +127,6 @@ nfs4_schedule_state_renewal(struct nfs_client *clp)
}
void
-nfs4_renewd_prepare_shutdown(struct nfs_server *server)
-{
- cancel_delayed_work(&server->nfs_client->cl_renewd);
-}
-
-void
nfs4_kill_renewd(struct nfs_client *clp)
{
cancel_delayed_work_sync(&clp->cl_renewd);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 29786d3b932..6dabf6feec9 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -728,22 +728,24 @@ static void nfs_umount_begin(struct super_block *sb)
unlock_kernel();
}
-static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(int flags)
+static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version)
{
struct nfs_parsed_mount_data *data;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data) {
- data->flags = flags;
data->rsize = NFS_MAX_FILE_IO_SIZE;
data->wsize = NFS_MAX_FILE_IO_SIZE;
data->acregmin = NFS_DEF_ACREGMIN;
data->acregmax = NFS_DEF_ACREGMAX;
data->acdirmin = NFS_DEF_ACDIRMIN;
data->acdirmax = NFS_DEF_ACDIRMAX;
+ data->mount_server.port = NFS_UNSPEC_PORT;
data->nfs_server.port = NFS_UNSPEC_PORT;
+ data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
data->auth_flavors[0] = RPC_AUTH_UNIX;
data->auth_flavor_len = 1;
+ data->version = version;
data->minorversion = 0;
}
return data;
@@ -776,15 +778,13 @@ static int nfs_verify_server_address(struct sockaddr *addr)
* Select between a default port value and a user-specified port value.
* If a zero value is set, then autobind will be used.
*/
-static void nfs_set_default_port(struct sockaddr *sap, const int parsed_port,
+static void nfs_set_port(struct sockaddr *sap, int *port,
const unsigned short default_port)
{
- unsigned short port = default_port;
+ if (*port == NFS_UNSPEC_PORT)
+ *port = default_port;
- if (parsed_port != NFS_UNSPEC_PORT)
- port = parsed_port;
-
- rpc_set_port(sap, port);
+ rpc_set_port(sap, *port);
}
/*
@@ -1475,7 +1475,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
args->mount_server.addrlen = args->nfs_server.addrlen;
}
request.salen = args->mount_server.addrlen;
- nfs_set_default_port(request.sap, args->mount_server.port, 0);
+ nfs_set_port(request.sap, &args->mount_server.port, 0);
/*
* Now ask the mount server to map our export path
@@ -1711,8 +1711,6 @@ static int nfs_validate_mount_data(void *options,
if (!(data->flags & NFS_MOUNT_TCP))
args->nfs_server.protocol = XPRT_TRANSPORT_UDP;
- else
- args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
/* N.B. caller will free nfs_server.hostname in all cases */
args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
args->namlen = data->namlen;
@@ -1767,7 +1765,7 @@ static int nfs_validate_mount_data(void *options,
goto out_v4_not_compiled;
#endif
- nfs_set_default_port(sap, args->nfs_server.port, 0);
+ nfs_set_port(sap, &args->nfs_server.port, 0);
nfs_set_mount_transport_protocol(args);
@@ -1848,9 +1846,10 @@ nfs_compare_remount_data(struct nfs_server *nfss,
data->acdirmin != nfss->acdirmin / HZ ||
data->acdirmax != nfss->acdirmax / HZ ||
data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
+ data->nfs_server.port != nfss->port ||
data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
- memcmp(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
- data->nfs_server.addrlen) != 0)
+ !rpc_cmp_addr(&data->nfs_server.address,
+ &nfss->nfs_client->cl_addr))
return -EINVAL;
return 0;
@@ -1893,6 +1892,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
data->acdirmin = nfss->acdirmin / HZ;
data->acdirmax = nfss->acdirmax / HZ;
data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
+ data->nfs_server.port = nfss->port;
data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
data->nfs_server.addrlen);
@@ -2106,7 +2106,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
};
int error = -ENOMEM;
- data = nfs_alloc_parsed_mount_data(NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
+ data = nfs_alloc_parsed_mount_data(3);
mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
if (data == NULL || mntfh == NULL)
goto out_free_fh;
@@ -2331,7 +2331,7 @@ static int nfs4_validate_text_mount_data(void *options,
{
struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
- nfs_set_default_port(sap, args->nfs_server.port, NFS_PORT);
+ nfs_set_port(sap, &args->nfs_server.port, NFS_PORT);
nfs_validate_transport_protocol(args);
@@ -2376,7 +2376,6 @@ static int nfs4_validate_mount_data(void *options,
if (data == NULL)
goto out_no_data;
- args->version = 4;
switch (data->version) {
case 1:
if (data->host_addrlen > sizeof(args->nfs_server.address))
@@ -2660,7 +2659,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
struct nfs_parsed_mount_data *data;
int error = -ENOMEM;
- data = nfs_alloc_parsed_mount_data(0);
+ data = nfs_alloc_parsed_mount_data(4);
if (data == NULL)
goto out_free_data;
@@ -2690,7 +2689,6 @@ static void nfs4_kill_super(struct super_block *sb)
dprintk("--> %s\n", __func__);
nfs_super_return_all_delegations(sb);
kill_anon_super(sb);
- nfs4_renewd_prepare_shutdown(server);
nfs_fscache_release_super_cookie(sb);
nfs_free_server(server);
dprintk("<-- %s\n", __func__);
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 00388d2a3c9..5c01fc148ce 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -176,7 +176,7 @@ static const struct file_operations exports_operations = {
extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
extern int nfsd_pool_stats_release(struct inode *inode, struct file *file);
-static struct file_operations pool_stats_operations = {
+static const struct file_operations pool_stats_operations = {
.open = nfsd_pool_stats_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 1a4fa04cf07..e097099bfc8 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -697,7 +697,7 @@ not_empty:
return 0;
}
-struct file_operations nilfs_dir_operations = {
+const struct file_operations nilfs_dir_operations = {
.llseek = generic_file_llseek,
.read = generic_read_dir,
.readdir = nilfs_readdir,
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 7d7b4983dee..30292df443c 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -134,7 +134,7 @@ static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
* We have mostly NULL's here: the current defaults are ok for
* the nilfs filesystem.
*/
-struct file_operations nilfs_file_operations = {
+const struct file_operations nilfs_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index b18c4998f8d..f6326112d64 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -433,7 +433,7 @@ static const struct address_space_operations def_mdt_aops = {
};
static const struct inode_operations def_mdt_iops;
-static struct file_operations def_mdt_fops;
+static const struct file_operations def_mdt_fops;
/*
* NILFS2 uses pseudo inodes for meta data files such as DAT, cpfile, sufile,
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index bad7368782d..4da6f67e9a9 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -294,9 +294,9 @@ void nilfs_clear_gcdat_inode(struct the_nilfs *);
/*
* Inodes and files operations
*/
-extern struct file_operations nilfs_dir_operations;
+extern const struct file_operations nilfs_dir_operations;
extern const struct inode_operations nilfs_file_inode_operations;
-extern struct file_operations nilfs_file_operations;
+extern const struct file_operations nilfs_file_operations;
extern const struct address_space_operations nilfs_aops;
extern const struct inode_operations nilfs_dir_inode_operations;
extern const struct inode_operations nilfs_special_inode_operations;
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 09cc25d0461..c452d116b89 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -966,7 +966,7 @@ static ssize_t o2hb_debug_read(struct file *file, char __user *buf,
}
#endif /* CONFIG_DEBUG_FS */
-static struct file_operations o2hb_debug_fops = {
+static const struct file_operations o2hb_debug_fops = {
.open = o2hb_debug_open,
.release = o2hb_debug_release,
.read = o2hb_debug_read,
diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c
index cfb2be708ab..da794bc07a6 100644
--- a/fs/ocfs2/cluster/netdebug.c
+++ b/fs/ocfs2/cluster/netdebug.c
@@ -207,7 +207,7 @@ static int nst_fop_release(struct inode *inode, struct file *file)
return seq_release_private(inode, file);
}
-static struct file_operations nst_seq_fops = {
+static const struct file_operations nst_seq_fops = {
.open = nst_fop_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -388,7 +388,7 @@ static int sc_fop_release(struct inode *inode, struct file *file)
return seq_release_private(inode, file);
}
-static struct file_operations sc_seq_fops = {
+static const struct file_operations sc_seq_fops = {
.open = sc_fop_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index ca46002ec10..42b0bad7a61 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -478,7 +478,7 @@ bail:
return -ENOMEM;
}
-static struct file_operations debug_purgelist_fops = {
+static const struct file_operations debug_purgelist_fops = {
.open = debug_purgelist_open,
.release = debug_buffer_release,
.read = debug_buffer_read,
@@ -538,7 +538,7 @@ bail:
return -ENOMEM;
}
-static struct file_operations debug_mle_fops = {
+static const struct file_operations debug_mle_fops = {
.open = debug_mle_open,
.release = debug_buffer_release,
.read = debug_buffer_read,
@@ -741,7 +741,7 @@ static int debug_lockres_release(struct inode *inode, struct file *file)
return seq_release_private(inode, file);
}
-static struct file_operations debug_lockres_fops = {
+static const struct file_operations debug_lockres_fops = {
.open = debug_lockres_open,
.release = debug_lockres_release,
.read = seq_read,
@@ -925,7 +925,7 @@ bail:
return -ENOMEM;
}
-static struct file_operations debug_state_fops = {
+static const struct file_operations debug_state_fops = {
.open = debug_state_open,
.release = debug_buffer_release,
.read = debug_buffer_read,
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 4cc3c890a2c..c0e48aeebb1 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -373,7 +373,7 @@ static ssize_t ocfs2_debug_read(struct file *file, char __user *buf,
}
#endif /* CONFIG_DEBUG_FS */
-static struct file_operations ocfs2_osb_debug_fops = {
+static const struct file_operations ocfs2_osb_debug_fops = {
.open = ocfs2_osb_debug_open,
.release = ocfs2_debug_release,
.read = ocfs2_debug_read,
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index 3680bae335b..b42d6241903 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -498,7 +498,7 @@ const struct inode_operations omfs_dir_inops = {
.rmdir = omfs_rmdir,
};
-struct file_operations omfs_dir_operations = {
+const struct file_operations omfs_dir_operations = {
.read = generic_read_dir,
.readdir = omfs_readdir,
.llseek = generic_file_llseek,
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 4845fbb18e6..399487c0936 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -322,7 +322,7 @@ static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
return generic_block_bmap(mapping, block, omfs_get_block);
}
-struct file_operations omfs_file_operations = {
+const struct file_operations omfs_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.write = do_sync_write,
diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h
index df71039945a..ebe2fdbe535 100644
--- a/fs/omfs/omfs.h
+++ b/fs/omfs/omfs.h
@@ -44,14 +44,14 @@ extern int omfs_allocate_range(struct super_block *sb, int min_request,
extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
/* dir.c */
-extern struct file_operations omfs_dir_operations;
+extern const struct file_operations omfs_dir_operations;
extern const struct inode_operations omfs_dir_inops;
extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header,
u64 fsblock);
/* file.c */
-extern struct file_operations omfs_file_operations;
+extern const struct file_operations omfs_file_operations;
extern const struct inode_operations omfs_file_inops;
extern const struct address_space_operations omfs_aops;
extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 7b685e10cba..f38fee0311a 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -248,19 +248,11 @@ ssize_t part_stat_show(struct device *dev,
part_stat_read(p, merges[WRITE]),
(unsigned long long)part_stat_read(p, sectors[WRITE]),
jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
- part_in_flight(p),
+ p->in_flight,
jiffies_to_msecs(part_stat_read(p, io_ticks)),
jiffies_to_msecs(part_stat_read(p, time_in_queue)));
}
-ssize_t part_inflight_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct hd_struct *p = dev_to_part(dev);
-
- return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]);
-}
-
#ifdef CONFIG_FAIL_MAKE_REQUEST
ssize_t part_fail_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -289,7 +281,6 @@ static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL);
static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
-static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
#ifdef CONFIG_FAIL_MAKE_REQUEST
static struct device_attribute dev_attr_fail =
__ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
@@ -301,7 +292,6 @@ static struct attribute *part_attrs[] = {
&dev_attr_size.attr,
&dev_attr_alignment_offset.attr,
&dev_attr_stat.attr,
- &dev_attr_inflight.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
&dev_attr_fail.attr,
#endif
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 56013371f9f..a44a7897fd4 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -23,7 +23,6 @@
#include <asm/io.h>
#include <linux/list.h>
#include <linux/ioport.h>
-#include <linux/mm.h>
#include <linux/memory.h>
#include <asm/sections.h>
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 2281c2cbfe2..5033ce0d254 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -94,6 +94,7 @@ static const struct file_operations proc_kpagecount_operations = {
#define KPF_COMPOUND_TAIL 16
#define KPF_HUGE 17
#define KPF_UNEVICTABLE 18
+#define KPF_HWPOISON 19
#define KPF_NOPAGE 20
#define KPF_KSM 21
@@ -180,6 +181,10 @@ static u64 get_uflags(struct page *page)
u |= kpf_copy_bit(k, KPF_UNEVICTABLE, PG_unevictable);
u |= kpf_copy_bit(k, KPF_MLOCKED, PG_mlocked);
+#ifdef CONFIG_MEMORY_FAILURE
+ u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
+#endif
+
#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached);
#endif
diff --git a/fs/select.c b/fs/select.c
index a201fc37022..fd38ce2e32e 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -15,6 +15,7 @@
*/
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 381854461b2..c2e30eea74d 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -186,19 +186,37 @@ xfs_destroy_ioend(
}
/*
+ * If the end of the current ioend is beyond the current EOF,
+ * return the new EOF value, otherwise zero.
+ */
+STATIC xfs_fsize_t
+xfs_ioend_new_eof(
+ xfs_ioend_t *ioend)
+{
+ xfs_inode_t *ip = XFS_I(ioend->io_inode);
+ xfs_fsize_t isize;
+ xfs_fsize_t bsize;
+
+ bsize = ioend->io_offset + ioend->io_size;
+ isize = MAX(ip->i_size, ip->i_new_size);
+ isize = MIN(isize, bsize);
+ return isize > ip->i_d.di_size ? isize : 0;
+}
+
+/*
* Update on-disk file size now that data has been written to disk.
* The current in-memory file size is i_size. If a write is beyond
* eof i_new_size will be the intended file size until i_size is
* updated. If this write does not extend all the way to the valid
* file size then restrict this update to the end of the write.
*/
+
STATIC void
xfs_setfilesize(
xfs_ioend_t *ioend)
{
xfs_inode_t *ip = XFS_I(ioend->io_inode);
xfs_fsize_t isize;
- xfs_fsize_t bsize;
ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
ASSERT(ioend->io_type != IOMAP_READ);
@@ -206,16 +224,10 @@ xfs_setfilesize(
if (unlikely(ioend->io_error))
return;
- bsize = ioend->io_offset + ioend->io_size;
-
xfs_ilock(ip, XFS_ILOCK_EXCL);
-
- isize = MAX(ip->i_size, ip->i_new_size);
- isize = MIN(isize, bsize);
-
- if (ip->i_d.di_size < isize) {
+ isize = xfs_ioend_new_eof(ioend);
+ if (isize) {
ip->i_d.di_size = isize;
- ip->i_update_core = 1;
xfs_mark_inode_dirty_sync(ip);
}
@@ -404,10 +416,16 @@ xfs_submit_ioend_bio(
struct bio *bio)
{
atomic_inc(&ioend->io_remaining);
-
bio->bi_private = ioend;
bio->bi_end_io = xfs_end_bio;
+ /*
+ * If the I/O is beyond EOF we mark the inode dirty immediately
+ * but don't update the inode size until I/O completion.
+ */
+ if (xfs_ioend_new_eof(ioend))
+ xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode));
+
submit_bio(WRITE, bio);
ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP));
bio_put(bio);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 629370974e5..eff61e2732a 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -176,14 +176,7 @@ xfs_file_fsync(
struct dentry *dentry,
int datasync)
{
- struct inode *inode = dentry->d_inode;
- struct xfs_inode *ip = XFS_I(inode);
- int error;
-
- /* capture size updates in I/O completion before writing the inode. */
- error = filemap_fdatawait(inode->i_mapping);
- if (error)
- return error;
+ struct xfs_inode *ip = XFS_I(dentry->d_inode);
xfs_iflags_clear(ip, XFS_ITRUNCATED);
return -xfs_fsync(ip);
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index da0159d99f8..cd42ef78f6b 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -57,19 +57,22 @@
#include <linux/fiemap.h>
/*
- * Bring the atime in the XFS inode uptodate.
- * Used before logging the inode to disk or when the Linux inode goes away.
+ * Bring the timestamps in the XFS inode uptodate.
+ *
+ * Used before writing the inode to disk.
*/
void
-xfs_synchronize_atime(
+xfs_synchronize_times(
xfs_inode_t *ip)
{
struct inode *inode = VFS_I(ip);
- if (!(inode->i_state & I_CLEAR)) {
- ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
- ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
- }
+ ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
+ ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
+ ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec;
+ ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec;
+ ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec;
+ ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec;
}
/*
@@ -106,32 +109,20 @@ xfs_ichgtime(
if ((flags & XFS_ICHGTIME_MOD) &&
!timespec_equal(&inode->i_mtime, &tv)) {
inode->i_mtime = tv;
- ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
sync_it = 1;
}
if ((flags & XFS_ICHGTIME_CHG) &&
!timespec_equal(&inode->i_ctime, &tv)) {
inode->i_ctime = tv;
- ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
- ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
sync_it = 1;
}
/*
- * We update the i_update_core field _after_ changing
- * the timestamps in order to coordinate properly with
- * xfs_iflush() so that we don't lose timestamp updates.
- * This keeps us from having to hold the inode lock
- * while doing this. We use the SYNCHRONIZE macro to
- * ensure that the compiler does not reorder the update
- * of i_update_core above the timestamp updates above.
+ * Update complete - now make sure everyone knows that the inode
+ * is dirty.
*/
- if (sync_it) {
- SYNCHRONIZE();
- ip->i_update_core = 1;
+ if (sync_it)
xfs_mark_inode_dirty_sync(ip);
- }
}
/*
@@ -506,10 +497,8 @@ xfs_vn_getattr(
stat->gid = ip->i_d.di_gid;
stat->ino = ip->i_ino;
stat->atime = inode->i_atime;
- stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec;
- stat->mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
- stat->ctime.tv_sec = ip->i_d.di_ctime.t_sec;
- stat->ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
+ stat->mtime = inode->i_mtime;
+ stat->ctime = inode->i_ctime;
stat->blocks =
XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 49e4a6aea73..072050f8d34 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -667,7 +667,7 @@ start:
xip->i_new_size = new_size;
if (likely(!(ioflags & IO_INVIS)))
- xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
+ file_update_time(file);
/*
* If the offset is beyond the size of the file, we have a couple
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index bdd41c8c342..18a4b8e11df 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -977,6 +977,28 @@ xfs_fs_inode_init_once(
}
/*
+ * Dirty the XFS inode when mark_inode_dirty_sync() is called so that
+ * we catch unlogged VFS level updates to the inode. Care must be taken
+ * here - the transaction code calls mark_inode_dirty_sync() to mark the
+ * VFS inode dirty in a transaction and clears the i_update_core field;
+ * it must clear the field after calling mark_inode_dirty_sync() to
+ * correctly indicate that the dirty state has been propagated into the
+ * inode log item.
+ *
+ * We need the barrier() to maintain correct ordering between unlogged
+ * updates and the transaction commit code that clears the i_update_core
+ * field. This requires all updates to be completed before marking the
+ * inode dirty.
+ */
+STATIC void
+xfs_fs_dirty_inode(
+ struct inode *inode)
+{
+ barrier();
+ XFS_I(inode)->i_update_core = 1;
+}
+
+/*
* Attempt to flush the inode, this will actually fail
* if the inode is pinned, but we dirty the inode again
* at the point when it is unpinned after a log write,
@@ -1126,7 +1148,7 @@ xfs_fs_put_super(
}
STATIC int
-xfs_fs_sync_super(
+xfs_fs_sync_fs(
struct super_block *sb,
int wait)
{
@@ -1134,23 +1156,23 @@ xfs_fs_sync_super(
int error;
/*
- * Treat a sync operation like a freeze. This is to work
- * around a race in sync_inodes() which works in two phases
- * - an asynchronous flush, which can write out an inode
- * without waiting for file size updates to complete, and a
- * synchronous flush, which wont do anything because the
- * async flush removed the inode's dirty flag. Also
- * sync_inodes() will not see any files that just have
- * outstanding transactions to be flushed because we don't
- * dirty the Linux inode until after the transaction I/O
- * completes.
+ * Not much we can do for the first async pass. Writing out the
+ * superblock would be counter-productive as we are going to redirty
+ * when writing out other data and metadata (and writing out a single
+ * block is quite fast anyway).
+ *
+ * Try to asynchronously kick off quota syncing at least.
*/
- if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE))
- error = xfs_quiesce_data(mp);
- else
- error = xfs_sync_fsdata(mp, 0);
+ if (!wait) {
+ xfs_qm_sync(mp, SYNC_TRYLOCK);
+ return 0;
+ }
+
+ error = xfs_quiesce_data(mp);
+ if (error)
+ return -error;
- if (unlikely(laptop_mode)) {
+ if (laptop_mode) {
int prev_sync_seq = mp->m_sync_seq;
/*
@@ -1169,7 +1191,7 @@ xfs_fs_sync_super(
mp->m_sync_seq != prev_sync_seq);
}
- return -error;
+ return 0;
}
STATIC int
@@ -1539,10 +1561,11 @@ xfs_fs_get_sb(
static const struct super_operations xfs_super_operations = {
.alloc_inode = xfs_fs_alloc_inode,
.destroy_inode = xfs_fs_destroy_inode,
+ .dirty_inode = xfs_fs_dirty_inode,
.write_inode = xfs_fs_write_inode,
.clear_inode = xfs_fs_clear_inode,
.put_super = xfs_fs_put_super,
- .sync_fs = xfs_fs_sync_super,
+ .sync_fs = xfs_fs_sync_fs,
.freeze_fs = xfs_fs_freeze,
.statfs = xfs_fs_statfs,
.remount_fs = xfs_fs_remount,
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 320be6aea49..961df0a22c7 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -309,11 +309,15 @@ xfs_sync_attr(
STATIC int
xfs_commit_dummy_trans(
struct xfs_mount *mp,
- uint log_flags)
+ uint flags)
{
struct xfs_inode *ip = mp->m_rootip;
struct xfs_trans *tp;
int error;
+ int log_flags = XFS_LOG_FORCE;
+
+ if (flags & SYNC_WAIT)
+ log_flags |= XFS_LOG_SYNC;
/*
* Put a dummy transaction in the log to tell recovery
@@ -331,13 +335,12 @@ xfs_commit_dummy_trans(
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- /* XXX(hch): ignoring the error here.. */
error = xfs_trans_commit(tp, 0);
-
xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ /* the log force ensures this transaction is pushed to disk */
xfs_log_force(mp, 0, log_flags);
- return 0;
+ return error;
}
int
@@ -385,7 +388,20 @@ xfs_sync_fsdata(
else
XFS_BUF_ASYNC(bp);
- return xfs_bwrite(mp, bp);
+ error = xfs_bwrite(mp, bp);
+ if (error)
+ return error;
+
+ /*
+ * If this is a data integrity sync make sure all pending buffers
+ * are flushed out for the log coverage check below.
+ */
+ if (flags & SYNC_WAIT)
+ xfs_flush_buftarg(mp->m_ddev_targp, 1);
+
+ if (xfs_log_need_covered(mp))
+ error = xfs_commit_dummy_trans(mp, flags);
+ return error;
out_brelse:
xfs_buf_relse(bp);
@@ -419,14 +435,16 @@ xfs_quiesce_data(
/* push non-blocking */
xfs_sync_data(mp, 0);
xfs_qm_sync(mp, SYNC_TRYLOCK);
- xfs_filestream_flush(mp);
- /* push and block */
+ /* push and block till complete */
xfs_sync_data(mp, SYNC_WAIT);
xfs_qm_sync(mp, SYNC_WAIT);
+ /* drop inode references pinned by filestreams */
+ xfs_filestream_flush(mp);
+
/* write superblock and hoover up shutdown errors */
- error = xfs_sync_fsdata(mp, 0);
+ error = xfs_sync_fsdata(mp, SYNC_WAIT);
/* flush data-only devices */
if (mp->m_rtdev_targp)
@@ -570,8 +588,6 @@ xfs_sync_worker(
/* dgc: errors ignored here */
error = xfs_qm_sync(mp, SYNC_TRYLOCK);
error = xfs_sync_fsdata(mp, SYNC_TRYLOCK);
- if (xfs_log_need_covered(mp))
- error = xfs_commit_dummy_trans(mp, XFS_LOG_FORCE);
}
mp->m_sync_seq++;
wake_up(&mp->m_wait_single_sync_task);
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 7465f9ee125..ab89a7e94a0 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -206,10 +206,10 @@ xfs_swap_extents(
* process that the file was not changed out from
* under it.
*/
- if ((sbp->bs_ctime.tv_sec != ip->i_d.di_ctime.t_sec) ||
- (sbp->bs_ctime.tv_nsec != ip->i_d.di_ctime.t_nsec) ||
- (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) ||
- (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) {
+ if ((sbp->bs_ctime.tv_sec != VFS_I(ip)->i_ctime.tv_sec) ||
+ (sbp->bs_ctime.tv_nsec != VFS_I(ip)->i_ctime.tv_nsec) ||
+ (sbp->bs_mtime.tv_sec != VFS_I(ip)->i_mtime.tv_sec) ||
+ (sbp->bs_mtime.tv_nsec != VFS_I(ip)->i_mtime.tv_nsec)) {
error = XFS_ERROR(EBUSY);
goto out_unlock;
}
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index fa913e45944..41ad537c49e 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -854,6 +854,7 @@ xfs_dir2_leaf_getdents(
*/
ra_want = howmany(bufsize + mp->m_dirblksize,
mp->m_sb.sb_blocksize) - 1;
+ ASSERT(ra_want >= 0);
/*
* If we don't have as many as we want, and we haven't
@@ -1088,7 +1089,8 @@ xfs_dir2_leaf_getdents(
*/
ptr += length;
curoff += length;
- bufsize -= length;
+ /* bufsize may have just been a guess; don't go negative */
+ bufsize = bufsize > length ? bufsize - length : 0;
}
/*
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c1dc7ef5a1d..b92a4fa2a0a 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -3068,9 +3068,9 @@ xfs_iflush_int(
SYNCHRONIZE();
/*
- * Make sure to get the latest atime from the Linux inode.
+ * Make sure to get the latest timestamps from the Linux inode.
*/
- xfs_synchronize_atime(ip);
+ xfs_synchronize_times(ip);
if (XFS_TEST_ERROR(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC,
mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 0b38b9a869e..41555de1d1d 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -504,7 +504,7 @@ void xfs_ichgtime(xfs_inode_t *, int);
void xfs_lock_inodes(xfs_inode_t **, int, uint);
void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint);
-void xfs_synchronize_atime(xfs_inode_t *);
+void xfs_synchronize_times(xfs_inode_t *);
void xfs_mark_inode_dirty_sync(xfs_inode_t *);
#if defined(XFS_INODE_TRACE)
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 47d5b663c37..9794b876d6f 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -232,6 +232,15 @@ xfs_inode_item_format(
nvecs = 1;
/*
+ * Make sure the linux inode is dirty. We do this before
+ * clearing i_update_core as the VFS will call back into
+ * XFS here and set i_update_core, so we need to dirty the
+ * inode first so that the ordering of i_update_core and
+ * unlogged modifications still works as described below.
+ */
+ xfs_mark_inode_dirty_sync(ip);
+
+ /*
* Clear i_update_core if the timestamps (or any other
* non-transactional modification) need flushing/logging
* and we're about to log them with the rest of the core.
@@ -263,14 +272,9 @@ xfs_inode_item_format(
}
/*
- * Make sure to get the latest atime from the Linux inode.
+ * Make sure to get the latest timestamps from the Linux inode.
*/
- xfs_synchronize_atime(ip);
-
- /*
- * make sure the linux inode is dirty
- */
- xfs_mark_inode_dirty_sync(ip);
+ xfs_synchronize_times(ip);
vecp->i_addr = (xfs_caddr_t)&ip->i_d;
vecp->i_len = sizeof(struct xfs_icdinode);
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index b68f9107e26..62efab2f383 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -59,6 +59,7 @@ xfs_bulkstat_one_iget(
{
xfs_icdinode_t *dic; /* dinode core info pointer */
xfs_inode_t *ip; /* incore inode pointer */
+ struct inode *inode;
int error;
error = xfs_iget(mp, NULL, ino,
@@ -72,6 +73,7 @@ xfs_bulkstat_one_iget(
ASSERT(ip->i_imap.im_blkno != 0);
dic = &ip->i_d;
+ inode = VFS_I(ip);
/* xfs_iget returns the following without needing
* further change.
@@ -83,16 +85,19 @@ xfs_bulkstat_one_iget(
buf->bs_uid = dic->di_uid;
buf->bs_gid = dic->di_gid;
buf->bs_size = dic->di_size;
+
/*
- * We are reading the atime from the Linux inode because the
- * dinode might not be uptodate.
+ * We need to read the timestamps from the Linux inode because
+ * the VFS keeps writing directly into the inode structure instead
+ * of telling us about the updates.
*/
- buf->bs_atime.tv_sec = VFS_I(ip)->i_atime.tv_sec;
- buf->bs_atime.tv_nsec = VFS_I(ip)->i_atime.tv_nsec;
- buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
- buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
- buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
- buf->bs_ctime.tv_nsec = dic->di_ctime.t_nsec;
+ buf->bs_atime.tv_sec = inode->i_atime.tv_sec;
+ buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec;
+ buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec;
+ buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec;
+ buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec;
+ buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec;
+
buf->bs_xflags = xfs_ip2xflags(ip);
buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog;
buf->bs_extents = dic->di_nextents;
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index a434f287962..b572f7e840e 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -2476,12 +2476,6 @@ xfs_reclaim(
ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
/*
- * Make sure the atime in the XFS inode is correct before freeing the
- * Linux inode.
- */
- xfs_synchronize_atime(ip);
-
- /*
* If we have nothing to flush with this inode then complete the
* teardown now, otherwise break the link between the xfs inode and the
* linux inode and clean up the xfs inode later. This avoids flushing
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 9cca3785cab..66d6106a206 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -1,6 +1,7 @@
#ifndef _ASM_GENERIC_GPIO_H
#define _ASM_GENERIC_GPIO_H
+#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
diff --git a/include/asm-generic/hardirq.h b/include/asm-generic/hardirq.h
index 23bb4dad496..62f59080e5c 100644
--- a/include/asm-generic/hardirq.h
+++ b/include/asm-generic/hardirq.h
@@ -6,7 +6,7 @@
#include <linux/irq.h>
typedef struct {
- unsigned long __softirq_pending;
+ unsigned int __softirq_pending;
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index ef47dfd8e5e..b29e20168b5 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -61,6 +61,9 @@ struct drm_crtc_helper_funcs {
/* Move the crtc on the current fb to the given position *optional* */
int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb);
+
+ /* reload the current crtc LUT */
+ void (*load_lut)(struct drm_crtc *crtc);
};
struct drm_encoder_helper_funcs {
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 4aa5740ce59..58c892a2cbf 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -39,6 +39,8 @@ struct drm_fb_helper_crtc {
struct drm_fb_helper_funcs {
void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno);
+ void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno);
};
/* mode specified on the command line */
@@ -71,6 +73,7 @@ struct drm_fb_helper {
};
int drm_fb_helper_single_fb_probe(struct drm_device *dev,
+ int preferred_bpp,
int (*fb_create)(struct drm_device *dev,
uint32_t fb_width,
uint32_t fb_height,
@@ -98,9 +101,11 @@ int drm_fb_helper_setcolreg(unsigned regno,
void drm_fb_helper_restore(void);
void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
uint32_t fb_width, uint32_t fb_height);
-void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch);
+void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
+ uint32_t depth);
int drm_fb_helper_add_connector(struct drm_connector *connector);
int drm_fb_helper_parse_command_line(struct drm_device *dev);
+int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
#endif
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index 3f6e545609b..e6f3b120f51 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -80,7 +80,7 @@
{0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
{0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
{0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
- {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+ {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_SINGLE_CRTC}, \
{0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
@@ -113,7 +113,7 @@
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
- {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+ {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_SINGLE_CRTC}, \
{0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \
{0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index cff4a101f26..3f384d4b163 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -126,6 +126,7 @@ header-y += nfs_mount.h
header-y += nl80211.h
header-y += param.h
header-y += pci_regs.h
+header-y += perf_event.h
header-y += pfkeyv2.h
header-y += pg.h
header-y += phantom.h
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 6299a259ed1..4fb357312b3 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -334,9 +334,12 @@ enum {
SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */
/* SETFEATURE Sector counts for SATA features */
- SATA_AN = 0x05, /* Asynchronous Notification */
- SATA_DIPM = 0x03, /* Device Initiated Power Management */
- SATA_FPDMA_AA = 0x02, /* DMA Setup FIS Auto-Activate */
+ SATA_FPDMA_OFFSET = 0x01, /* FPDMA non-zero buffer offsets */
+ SATA_FPDMA_AA = 0x02, /* FPDMA Setup FIS Auto-Activate */
+ SATA_DIPM = 0x03, /* Device Initiated Power Management */
+ SATA_FPDMA_IN_ORDER = 0x04, /* FPDMA in-order data delivery */
+ SATA_AN = 0x05, /* Asynchronous Notification */
+ SATA_SSP = 0x06, /* Software Settings Preservation */
/* feature values for SET_MAX */
ATA_SET_MAX_ADDR = 0x00,
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 086e5c362d3..817b23705c9 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -397,7 +397,7 @@ struct atmdev_ops { /* only send is required */
int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
void __user *optval,int optlen);
int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen);
+ void __user *optval,unsigned int optlen);
int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
void (*phy_put)(struct atm_dev *dev,unsigned char value,
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e23a86cae5a..25119041e03 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -82,7 +82,6 @@ enum rq_cmd_type_bits {
enum {
REQ_LB_OP_EJECT = 0x40, /* eject request */
REQ_LB_OP_FLUSH = 0x41, /* flush request */
- REQ_LB_OP_DISCARD = 0x42, /* discard sectors */
};
/*
@@ -261,7 +260,6 @@ typedef void (request_fn_proc) (struct request_queue *q);
typedef int (make_request_fn) (struct request_queue *q, struct bio *bio);
typedef int (prep_rq_fn) (struct request_queue *, struct request *);
typedef void (unplug_fn) (struct request_queue *);
-typedef int (prepare_discard_fn) (struct request_queue *, struct request *);
struct bio_vec;
struct bvec_merge_data {
@@ -313,6 +311,7 @@ struct queue_limits {
unsigned int alignment_offset;
unsigned int io_min;
unsigned int io_opt;
+ unsigned int max_discard_sectors;
unsigned short logical_block_size;
unsigned short max_hw_segments;
@@ -340,7 +339,6 @@ struct request_queue
make_request_fn *make_request_fn;
prep_rq_fn *prep_rq_fn;
unplug_fn *unplug_fn;
- prepare_discard_fn *prepare_discard_fn;
merge_bvec_fn *merge_bvec_fn;
prepare_flush_fn *prepare_flush_fn;
softirq_done_fn *softirq_done_fn;
@@ -460,6 +458,7 @@ struct request_queue
#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */
#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */
#define QUEUE_FLAG_CQ 16 /* hardware does queuing */
+#define QUEUE_FLAG_DISCARD 17 /* supports DISCARD */
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
(1 << QUEUE_FLAG_CLUSTER) | \
@@ -591,6 +590,7 @@ enum {
#define blk_queue_flushing(q) ((q)->ordseq)
#define blk_queue_stackable(q) \
test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
+#define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
#define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS)
#define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
@@ -929,6 +929,8 @@ extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
+extern void blk_queue_max_discard_sectors(struct request_queue *q,
+ unsigned int max_discard_sectors);
extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
extern void blk_queue_physical_block_size(struct request_queue *, unsigned short);
extern void blk_queue_alignment_offset(struct request_queue *q,
@@ -955,7 +957,6 @@ extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
extern void blk_queue_dma_alignment(struct request_queue *, int);
extern void blk_queue_update_dma_alignment(struct request_queue *, int);
extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
-extern void blk_queue_set_discard(struct request_queue *, prepare_discard_fn *);
extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *);
extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);
extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
@@ -1080,25 +1081,37 @@ static inline unsigned int queue_physical_block_size(struct request_queue *q)
return q->limits.physical_block_size;
}
+static inline int bdev_physical_block_size(struct block_device *bdev)
+{
+ return queue_physical_block_size(bdev_get_queue(bdev));
+}
+
static inline unsigned int queue_io_min(struct request_queue *q)
{
return q->limits.io_min;
}
+static inline int bdev_io_min(struct block_device *bdev)
+{
+ return queue_io_min(bdev_get_queue(bdev));
+}
+
static inline unsigned int queue_io_opt(struct request_queue *q)
{
return q->limits.io_opt;
}
+static inline int bdev_io_opt(struct block_device *bdev)
+{
+ return queue_io_opt(bdev_get_queue(bdev));
+}
+
static inline int queue_alignment_offset(struct request_queue *q)
{
- if (q && q->limits.misaligned)
+ if (q->limits.misaligned)
return -1;
- if (q && q->limits.alignment_offset)
- return q->limits.alignment_offset;
-
- return 0;
+ return q->limits.alignment_offset;
}
static inline int queue_sector_alignment_offset(struct request_queue *q,
@@ -1108,6 +1121,19 @@ static inline int queue_sector_alignment_offset(struct request_queue *q,
& (q->limits.io_min - 1);
}
+static inline int bdev_alignment_offset(struct block_device *bdev)
+{
+ struct request_queue *q = bdev_get_queue(bdev);
+
+ if (q->limits.misaligned)
+ return -1;
+
+ if (bdev != bdev->bd_contains)
+ return bdev->bd_part->alignment_offset;
+
+ return q->limits.alignment_offset;
+}
+
static inline int queue_dma_alignment(struct request_queue *q)
{
return q ? q->dma_alignment : 511;
@@ -1146,7 +1172,11 @@ static inline void put_dev_sector(Sector p)
}
struct work_struct;
+struct delayed_work;
int kblockd_schedule_work(struct request_queue *q, struct work_struct *work);
+int kblockd_schedule_delayed_work(struct request_queue *q,
+ struct delayed_work *work,
+ unsigned long delay);
#define MODULE_ALIAS_BLOCKDEV(major,minor) \
MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 7e4350ece0f..3b73b9992b2 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -198,6 +198,7 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
+extern void blk_trace_remove_sysfs(struct device *dev);
extern int blk_trace_init_sysfs(struct device *dev);
extern struct attribute_group blk_trace_attr_group;
@@ -211,6 +212,7 @@ extern struct attribute_group blk_trace_attr_group;
# define blk_trace_startstop(q, start) (-ENOTTY)
# define blk_trace_remove(q) (-ENOTTY)
# define blk_add_trace_msg(q, fmt, ...) do { } while (0)
+# define blk_trace_remove_sysfs(dev) do { } while (0)
static inline int blk_trace_init_sysfs(struct device *dev)
{
return 0;
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index b62bb9294d0..0008dee6651 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -37,7 +37,7 @@ extern void cgroup_exit(struct task_struct *p, int run_callbacks);
extern int cgroupstats_build(struct cgroupstats *stats,
struct dentry *dentry);
-extern struct file_operations proc_cgroup_operations;
+extern const struct file_operations proc_cgroup_operations;
/* Define the enumeration of all cgroup subsystems */
#define SUBSYS(_x) _x ## _subsys_id,
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 47ebf416f51..3a14615fd35 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -132,11 +132,8 @@ struct cn_callback_id {
};
struct cn_callback_data {
- void (*destruct_data) (void *);
- void *ddata;
-
- void *callback_priv;
- void (*callback) (struct cn_msg *);
+ struct sk_buff *skb;
+ void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
void *free;
};
@@ -167,11 +164,11 @@ struct cn_dev {
struct cn_queue_dev *cbdev;
};
-int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *));
+int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
void cn_del_callback(struct cb_id *);
int cn_netlink_send(struct cn_msg *, u32, gfp_t);
-int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *));
+int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2adaa2529f1..2620a8c6357 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -300,6 +300,10 @@ struct inodes_stat_t {
#define BLKTRACESTOP _IO(0x12,117)
#define BLKTRACETEARDOWN _IO(0x12,118)
#define BLKDISCARD _IO(0x12,119)
+#define BLKIOMIN _IO(0x12,120)
+#define BLKIOOPT _IO(0x12,121)
+#define BLKALIGNOFF _IO(0x12,122)
+#define BLKPBSZGET _IO(0x12,123)
#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
#define FIBMAP _IO(0x00,1) /* bmap access */
@@ -2446,7 +2450,7 @@ static int __fops ## _open(struct inode *inode, struct file *file) \
__simple_attr_check_format(__fmt, 0ull); \
return simple_attr_open(inode, file, __get, __set, __fmt); \
} \
-static struct file_operations __fops = { \
+static const struct file_operations __fops = { \
.owner = THIS_MODULE, \
.open = __fops ## _open, \
.release = simple_attr_release, \
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index cd3d2abaf30..0b4f97d24d7 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -241,7 +241,7 @@ extern void ftrace_enable_daemon(void);
# define ftrace_set_filter(buf, len, reset) do { } while (0)
# define ftrace_disable_daemon() do { } while (0)
# define ftrace_enable_daemon() do { } while (0)
-static inline void ftrace_release(void *start, unsigned long size) { }
+static inline void ftrace_release_mod(struct module *mod) {}
static inline int register_ftrace_command(struct ftrace_func_command *cmd)
{
return -EINVAL;
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 8ec17997d94..1e5a26d7923 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -33,8 +33,8 @@
#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
-#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITS | FUTEX_PRIVATE_FLAG)
-#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITS | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
+#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \
FUTEX_PRIVATE_FLAG)
#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 297df45ffd0..7beaa21b388 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -98,7 +98,7 @@ struct hd_struct {
int make_it_fail;
#endif
unsigned long stamp;
- int in_flight[2];
+ int in_flight;
#ifdef CONFIG_SMP
struct disk_stats *dkstats;
#else
@@ -322,23 +322,18 @@ static inline void free_part_stats(struct hd_struct *part)
#define part_stat_sub(cpu, gendiskp, field, subnd) \
part_stat_add(cpu, gendiskp, field, -subnd)
-static inline void part_inc_in_flight(struct hd_struct *part, int rw)
+static inline void part_inc_in_flight(struct hd_struct *part)
{
- part->in_flight[rw]++;
+ part->in_flight++;
if (part->partno)
- part_to_disk(part)->part0.in_flight[rw]++;
+ part_to_disk(part)->part0.in_flight++;
}
-static inline void part_dec_in_flight(struct hd_struct *part, int rw)
+static inline void part_dec_in_flight(struct hd_struct *part)
{
- part->in_flight[rw]--;
+ part->in_flight--;
if (part->partno)
- part_to_disk(part)->part0.in_flight[rw]--;
-}
-
-static inline int part_in_flight(struct hd_struct *part)
-{
- return part->in_flight[0] + part->in_flight[1];
+ part_to_disk(part)->part0.in_flight--;
}
/* block/blk-core.c */
@@ -551,8 +546,6 @@ extern ssize_t part_size_show(struct device *dev,
struct device_attribute *attr, char *buf);
extern ssize_t part_stat_show(struct device *dev,
struct device_attribute *attr, char *buf);
-extern ssize_t part_inflight_show(struct device *dev,
- struct device_attribute *attr, char *buf);
#ifdef CONFIG_FAIL_MAKE_REQUEST
extern ssize_t part_fail_show(struct device *dev,
struct device_attribute *attr, char *buf);
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
index 2d02dfd7076..508824ee35e 100644
--- a/include/linux/i2c/twl4030.h
+++ b/include/linux/i2c/twl4030.h
@@ -349,11 +349,11 @@ struct twl4030_madc_platform_data {
int irq_line;
};
-/* Boards have uniqe mappings of {col, row} --> keycode.
- * Column and row are 4 bits, but range only from 0..7.
+/* Boards have uniqe mappings of {row, col} --> keycode.
+ * Column and row are 8 bits each, but range only from 0..7.
* a PERSISTENT_KEY is "always on" and never reported.
*/
-#define PERSISTENT_KEY(c, r) KEY((c), (r), KEY_RESERVED)
+#define PERSISTENT_KEY(r, c) KEY((r), (c), KEY_RESERVED)
struct twl4030_keypad_data {
const struct matrix_keymap_data *keymap_data;
diff --git a/include/linux/init.h b/include/linux/init.h
index 400adbb4541..ff8bde520d0 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -271,6 +271,7 @@ void __init parse_early_options(char *cmdline);
#else /* MODULE */
/* Don't use these in modules, but some people do... */
+#define early_initcall(fn) module_init(fn)
#define core_initcall(fn) module_init(fn)
#define postcore_initcall(fn) module_init(fn)
#define arch_initcall(fn) module_init(fn)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 76319bf03e3..87698640c09 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -418,6 +418,17 @@ enum {
ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER |
ATA_TIMING_DMACK_HOLD | ATA_TIMING_CYCLE |
ATA_TIMING_UDMA,
+
+ /* ACPI constants */
+ ATA_ACPI_FILTER_SETXFER = 1 << 0,
+ ATA_ACPI_FILTER_LOCK = 1 << 1,
+ ATA_ACPI_FILTER_DIPM = 1 << 2,
+ ATA_ACPI_FILTER_FPDMA_OFFSET = 1 << 3, /* FPDMA non-zero offset */
+ ATA_ACPI_FILTER_FPDMA_AA = 1 << 4, /* FPDMA auto activate */
+
+ ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER |
+ ATA_ACPI_FILTER_LOCK |
+ ATA_ACPI_FILTER_DIPM,
};
enum ata_xfer_mask {
@@ -587,6 +598,7 @@ struct ata_device {
#ifdef CONFIG_ATA_ACPI
acpi_handle acpi_handle;
union acpi_object *gtf_cache;
+ unsigned int gtf_filter;
#endif
/* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */
u64 n_sectors; /* size of device, if ATA */
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index 0d45b4e8d36..08bc776d05e 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -145,14 +145,14 @@ static inline int ip_mroute_opt(int opt)
#endif
#ifdef CONFIG_IP_MROUTE
-extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
+extern int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
extern int ip_mr_init(void);
#else
static inline
int ip_mroute_setsockopt(struct sock *sock,
- int optname, char __user *optval, int optlen)
+ int optname, char __user *optval, unsigned int optlen)
{
return -ENOPROTOOPT;
}
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index 43dc97e3218..b191865a6ca 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -134,7 +134,7 @@ static inline int ip6_mroute_opt(int opt)
struct sock;
#ifdef CONFIG_IPV6_MROUTE
-extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, int);
+extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
extern int ip6_mr_input(struct sk_buff *skb);
extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
@@ -143,7 +143,7 @@ extern void ip6_mr_cleanup(void);
#else
static inline
int ip6_mroute_setsockopt(struct sock *sock,
- int optname, char __user *optval, int optlen)
+ int optname, char __user *optval, unsigned int optlen)
{
return -ENOPROTOOPT;
}
diff --git a/include/linux/net.h b/include/linux/net.h
index 9040a10584f..529a0931711 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -178,11 +178,11 @@ struct proto_ops {
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
- int optname, char __user *optval, int optlen);
+ int optname, char __user *optval, unsigned int optlen);
int (*getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
int (*compat_setsockopt)(struct socket *sock, int level,
- int optname, char __user *optval, int optlen);
+ int optname, char __user *optval, unsigned int optlen);
int (*compat_getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
@@ -256,7 +256,7 @@ extern int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
extern int kernel_getsockopt(struct socket *sock, int level, int optname,
char *optval, int *optlen);
extern int kernel_setsockopt(struct socket *sock, int level, int optname,
- char *optval, int optlen);
+ char *optval, unsigned int optlen);
extern int kernel_sendpage(struct socket *sock, struct page *page, int offset,
size_t size, int flags);
extern int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg);
@@ -313,7 +313,7 @@ SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \
SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \
SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \
SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \
- char __user *optval, int optlen), (sock, level, optname, optval, optlen)) \
+ char __user *optval, unsigned int optlen), (sock, level, optname, optval, optlen)) \
SOCKCALL_WRAP(name, getsockopt, (struct socket *sock, int level, int optname, \
char __user *optval, int __user *optlen), (sock, level, optname, optval, optlen)) \
SOCKCALL_WRAP(name, sendmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t len), \
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 48cfe51bfdd..6132b5e6d9d 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -221,12 +221,12 @@ __ret;})
/* Call setsockopt() */
int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
- int len);
+ unsigned int len);
int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
int *len);
int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval,
- char __user *opt, int len);
+ char __user *opt, unsigned int len);
int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval,
char __user *opt, int *len);
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 3a9d36d1e92..2e6d95f9741 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -442,6 +442,7 @@ enum perf_callchain_context {
#include <linux/hrtimer.h>
#include <linux/fs.h>
#include <linux/pid_namespace.h>
+#include <linux/workqueue.h>
#include <asm/atomic.h>
#define PERF_MAX_STACK_DEPTH 255
@@ -513,6 +514,10 @@ struct file;
struct perf_mmap_data {
struct rcu_head rcu_head;
+#ifdef CONFIG_PERF_USE_VMALLOC
+ struct work_struct work;
+#endif
+ int data_order;
int nr_pages; /* nr of data pages */
int writable; /* are we writable */
int nr_locked; /* nr pages mlocked */
diff --git a/include/linux/poll.h b/include/linux/poll.h
index fa287f25138..6673743946f 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -6,10 +6,10 @@
#ifdef __KERNEL__
#include <linux/compiler.h>
+#include <linux/ktime.h>
#include <linux/wait.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/sched.h>
#include <asm/uaccess.h>
/* ~832 bytes of stack space used max in sys_select/sys_poll before allocating
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 6fe0363724e..3ebd0b7bcb0 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -77,7 +77,7 @@ extern int rcu_scheduler_active;
#error "Unknown RCU implementation specified to kernel configuration"
#endif
-#define RCU_HEAD_INIT { .next = NULL, .func = NULL }
+#define RCU_HEAD_INIT { .next = NULL, .func = NULL }
#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT
#define INIT_RCU_HEAD(ptr) do { \
(ptr)->next = NULL; (ptr)->func = NULL; \
@@ -129,12 +129,6 @@ static inline void rcu_read_lock(void)
rcu_read_acquire();
}
-/**
- * rcu_read_unlock - marks the end of an RCU read-side critical section.
- *
- * See rcu_read_lock() for more information.
- */
-
/*
* So where is rcu_write_lock()? It does not exist, as there is no
* way for writers to lock out RCU readers. This is a feature, not
@@ -144,6 +138,12 @@ static inline void rcu_read_lock(void)
* used as well. RCU does not care how the writers keep out of each
* others' way, as long as they do so.
*/
+
+/**
+ * rcu_read_unlock - marks the end of an RCU read-side critical section.
+ *
+ * See rcu_read_lock() for more information.
+ */
static inline void rcu_read_unlock(void)
{
rcu_read_release();
@@ -196,6 +196,8 @@ static inline void rcu_read_lock_sched(void)
__acquire(RCU_SCHED);
rcu_read_acquire();
}
+
+/* Used by lockdep and tracing: cannot be traced, cannot call lockdep. */
static inline notrace void rcu_read_lock_sched_notrace(void)
{
preempt_disable_notrace();
@@ -213,6 +215,8 @@ static inline void rcu_read_unlock_sched(void)
__release(RCU_SCHED);
preempt_enable();
}
+
+/* Used by lockdep and tracing: cannot be traced, cannot call lockdep. */
static inline notrace void rcu_read_unlock_sched_notrace(void)
{
__release(RCU_SCHED);
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index 37682770e9d..46e9ab3ee6e 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -30,10 +30,14 @@
#ifndef __LINUX_RCUTREE_H
#define __LINUX_RCUTREE_H
+struct notifier_block;
+
extern void rcu_sched_qs(int cpu);
extern void rcu_bh_qs(int cpu);
-
+extern int rcu_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu);
extern int rcu_needs_cpu(int cpu);
+extern int rcu_expedited_torture_stats(char *page);
#ifdef CONFIG_TREE_PREEMPT_RCU
@@ -85,16 +89,11 @@ static inline void synchronize_rcu_bh_expedited(void)
extern void __rcu_init(void);
extern void rcu_check_callbacks(int cpu, int user);
-extern void rcu_restart_cpu(int cpu);
extern long rcu_batches_completed(void);
extern long rcu_batches_completed_bh(void);
extern long rcu_batches_completed_sched(void);
-static inline void rcu_init_sched(void)
-{
-}
-
#ifdef CONFIG_NO_HZ
void rcu_enter_nohz(void);
void rcu_exit_nohz(void);
@@ -107,7 +106,7 @@ static inline void rcu_exit_nohz(void)
}
#endif /* CONFIG_NO_HZ */
-/* A context switch is a grace period for rcutree. */
+/* A context switch is a grace period for RCU-sched and RCU-bh. */
static inline int rcu_blocking_is_gp(void)
{
return num_online_cpus() == 1;
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 731af71cddc..fcb9884df61 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -114,8 +114,7 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent);
int __must_check res_counter_charge_locked(struct res_counter *counter,
unsigned long val);
int __must_check res_counter_charge(struct res_counter *counter,
- unsigned long val, struct res_counter **limit_fail_at,
- struct res_counter **soft_limit_at);
+ unsigned long val, struct res_counter **limit_fail_at);
/*
* uncharge - tell that some portion of the resource is released
@@ -128,8 +127,7 @@ int __must_check res_counter_charge(struct res_counter *counter,
*/
void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val);
-void res_counter_uncharge(struct res_counter *counter, unsigned long val,
- bool *was_soft_limit_excess);
+void res_counter_uncharge(struct res_counter *counter, unsigned long val);
static inline bool res_counter_limit_check_locked(struct res_counter *cnt)
{
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 3b461dffe24..3273a0c5043 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -16,7 +16,7 @@ struct __kernel_sockaddr_storage {
/* _SS_MAXSIZE value minus size of ss_family */
} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+#ifdef __KERNEL__
#include <asm/socket.h> /* arch-dependent defines */
#include <linux/sockios.h> /* the SIOCxxx I/O controls */
@@ -101,21 +101,6 @@ struct cmsghdr {
((char *)(cmsg) - (char *)(mhdr)->msg_control)))
/*
- * This mess will go away with glibc
- */
-
-#ifdef __KERNEL__
-#define __KINLINE static inline
-#elif defined(__GNUC__)
-#define __KINLINE static __inline__
-#elif defined(__cplusplus)
-#define __KINLINE static inline
-#else
-#define __KINLINE static
-#endif
-
-
-/*
* Get the next cmsg header
*
* PLEASE, do not touch this function. If you think, that it is
@@ -128,7 +113,7 @@ struct cmsghdr {
* ancillary object DATA. --ANK (980731)
*/
-__KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
+static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
struct cmsghdr *__cmsg)
{
struct cmsghdr * __ptr;
@@ -140,7 +125,7 @@ __KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
return __ptr;
}
-__KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
+static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
{
return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
}
diff --git a/include/net/compat.h b/include/net/compat.h
index 5bbf8bf9efe..7c3002832d0 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -40,8 +40,8 @@ extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);
-extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, int,
- int (*)(struct sock *, int, int, char __user *, int));
+extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, unsigned int,
+ int (*)(struct sock *, int, int, char __user *, unsigned int));
extern int compat_mc_getsockopt(struct sock *, int, int, char __user *,
int __user *, int (*)(struct sock *, int, int, char __user *,
int __user *));
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 03cffd9f64e..696d6e4ce68 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -48,13 +48,13 @@ struct inet_connection_sock_af_ops {
u16 net_header_len;
u16 sockaddr_len;
int (*setsockopt)(struct sock *sk, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
int (*getsockopt)(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
#ifdef CONFIG_COMPAT
int (*compat_setsockopt)(struct sock *sk,
int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
int (*compat_getsockopt)(struct sock *sk,
int level, int optname,
char __user *optval, int __user *optlen);
@@ -332,5 +332,5 @@ extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
#endif /* _INET_CONNECTION_SOCK_H */
diff --git a/include/net/ip.h b/include/net/ip.h
index 5b26a0bd178..2f47e5482b5 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -381,10 +381,10 @@ extern int ip_options_rcv_srr(struct sk_buff *skb);
extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb);
extern int ip_cmsg_send(struct net *net,
struct msghdr *msg, struct ipcm_cookie *ipc);
-extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen);
+extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen);
extern int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);
extern int compat_ip_setsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int optlen);
+ int optname, char __user *optval, unsigned int optlen);
extern int compat_ip_getsockopt(struct sock *sk, int level,
int optname, char __user *optval, int __user *optlen);
extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index ad9a5113025..8c31d8a0c1f 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -550,7 +550,7 @@ extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
extern int ipv6_setsockopt(struct sock *sk, int level,
int optname,
char __user *optval,
- int optlen);
+ unsigned int optlen);
extern int ipv6_getsockopt(struct sock *sk, int level,
int optname,
char __user *optval,
@@ -559,7 +559,7 @@ extern int compat_ipv6_setsockopt(struct sock *sk,
int level,
int optname,
char __user *optval,
- int optlen);
+ unsigned int optlen);
extern int compat_ipv6_getsockopt(struct sock *sk,
int level,
int optname,
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 42d00ced5eb..6e5f0e0c796 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -544,7 +544,7 @@ struct sctp_af {
int level,
int optname,
char __user *optval,
- int optlen);
+ unsigned int optlen);
int (*getsockopt) (struct sock *sk,
int level,
int optname,
@@ -554,7 +554,7 @@ struct sctp_af {
int level,
int optname,
char __user *optval,
- int optlen);
+ unsigned int optlen);
int (*compat_getsockopt) (struct sock *sk,
int level,
int optname,
diff --git a/include/net/sock.h b/include/net/sock.h
index 950409dcec3..1621935aad5 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -624,7 +624,7 @@ struct proto {
void (*shutdown)(struct sock *sk, int how);
int (*setsockopt)(struct sock *sk, int level,
int optname, char __user *optval,
- int optlen);
+ unsigned int optlen);
int (*getsockopt)(struct sock *sk, int level,
int optname, char __user *optval,
int __user *option);
@@ -632,7 +632,7 @@ struct proto {
int (*compat_setsockopt)(struct sock *sk,
int level,
int optname, char __user *optval,
- int optlen);
+ unsigned int optlen);
int (*compat_getsockopt)(struct sock *sk,
int level,
int optname, char __user *optval,
@@ -951,7 +951,7 @@ extern void sock_rfree(struct sk_buff *skb);
extern int sock_setsockopt(struct socket *sock, int level,
int op, char __user *optval,
- int optlen);
+ unsigned int optlen);
extern int sock_getsockopt(struct socket *sock, int level,
int op, char __user *optval,
@@ -993,7 +993,7 @@ extern int sock_no_shutdown(struct socket *, int);
extern int sock_no_getsockopt(struct socket *, int , int,
char __user *, int __user *);
extern int sock_no_setsockopt(struct socket *, int, int,
- char __user *, int);
+ char __user *, unsigned int);
extern int sock_no_sendmsg(struct kiocb *, struct socket *,
struct msghdr *, size_t);
extern int sock_no_recvmsg(struct kiocb *, struct socket *,
@@ -1015,11 +1015,11 @@ extern int sock_common_getsockopt(struct socket *sock, int level, int optname,
extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags);
extern int sock_common_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
extern int compat_sock_common_getsockopt(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
extern int compat_sock_common_setsockopt(struct socket *sock, int level,
- int optname, char __user *optval, int optlen);
+ int optname, char __user *optval, unsigned int optlen);
extern void sk_common_release(struct sock *sk);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 56b76027b85..03a49c70337 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -394,13 +394,13 @@ extern int tcp_getsockopt(struct sock *sk, int level,
int __user *optlen);
extern int tcp_setsockopt(struct sock *sk, int level,
int optname, char __user *optval,
- int optlen);
+ unsigned int optlen);
extern int compat_tcp_getsockopt(struct sock *sk,
int level, int optname,
char __user *optval, int __user *optlen);
extern int compat_tcp_setsockopt(struct sock *sk,
int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
extern void tcp_set_keepalive(struct sock *sk, int val);
extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg,
diff --git a/include/net/udp.h b/include/net/udp.h
index 5fb029f817a..f98abd2ce70 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -144,7 +144,7 @@ extern unsigned int udp_poll(struct file *file, struct socket *sock,
extern int udp_lib_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
extern int udp_lib_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen,
+ char __user *optval, unsigned int optlen,
int (*push_pending_frames)(struct sock *));
extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index d86af94691c..00405b5f624 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -488,6 +488,39 @@ TRACE_EVENT(block_remap,
(unsigned long long)__entry->old_sector)
);
+TRACE_EVENT(block_rq_remap,
+
+ TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
+ sector_t from),
+
+ TP_ARGS(q, rq, dev, from),
+
+ TP_STRUCT__entry(
+ __field( dev_t, dev )
+ __field( sector_t, sector )
+ __field( unsigned int, nr_sector )
+ __field( dev_t, old_dev )
+ __field( sector_t, old_sector )
+ __array( char, rwbs, 6 )
+ ),
+
+ TP_fast_assign(
+ __entry->dev = disk_devt(rq->rq_disk);
+ __entry->sector = blk_rq_pos(rq);
+ __entry->nr_sector = blk_rq_sectors(rq);
+ __entry->old_dev = dev;
+ __entry->old_sector = from;
+ blk_fill_rwbs_rq(__entry->rwbs, rq);
+ ),
+
+ TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
+ MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+ (unsigned long long)__entry->sector,
+ __entry->nr_sector,
+ MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
+ (unsigned long long)__entry->old_sector)
+);
+
#endif /* _TRACE_BLOCK_H */
/* This part must be outside protection */
diff --git a/init/Kconfig b/init/Kconfig
index c7bac39d6c6..09c5c6431f4 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -921,6 +921,11 @@ config HAVE_PERF_EVENTS
help
See tools/perf/design.txt for details.
+config PERF_USE_VMALLOC
+ bool
+ help
+ See tools/perf/design.txt for details
+
menu "Kernel Performance Events And Counters"
config PERF_EVENTS
@@ -976,6 +981,19 @@ config PERF_COUNTERS
Say N if unsure.
+config DEBUG_PERF_USE_VMALLOC
+ default n
+ bool "Debug: use vmalloc to back perf mmap() buffers"
+ depends on PERF_EVENTS && DEBUG_KERNEL
+ select PERF_USE_VMALLOC
+ help
+ Use vmalloc memory to back perf mmap() buffers.
+
+ Mostly useful for debugging the vmalloc code on platforms
+ that don't require it.
+
+ Say N if unsure.
+
endmenu
config VM_EVENT_COUNTERS
diff --git a/init/main.c b/init/main.c
index 7449819a480..5988debfc50 100644
--- a/init/main.c
+++ b/init/main.c
@@ -778,7 +778,6 @@ static void __init do_initcalls(void)
*/
static void __init do_basic_setup(void)
{
- rcu_init_sched(); /* needed by module_init stage. */
init_workqueues();
cpuset_init_smp();
usermodehelper_init();
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 7ccba4bc5e3..ca83b73fba1 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -703,7 +703,7 @@ static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
static int cgroup_populate_dir(struct cgroup *cgrp);
static const struct inode_operations cgroup_dir_inode_operations;
-static struct file_operations proc_cgroupstats_operations;
+static const struct file_operations proc_cgroupstats_operations;
static struct backing_dev_info cgroup_backing_dev_info = {
.name = "cgroup",
@@ -1863,7 +1863,7 @@ static int cgroup_seqfile_release(struct inode *inode, struct file *file)
return single_release(inode, file);
}
-static struct file_operations cgroup_seqfile_operations = {
+static const struct file_operations cgroup_seqfile_operations = {
.read = seq_read,
.write = cgroup_file_write,
.llseek = seq_lseek,
@@ -1922,7 +1922,7 @@ static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry,
return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
}
-static struct file_operations cgroup_file_operations = {
+static const struct file_operations cgroup_file_operations = {
.read = cgroup_file_read,
.write = cgroup_file_write,
.llseek = generic_file_llseek,
@@ -3369,7 +3369,7 @@ static int cgroup_open(struct inode *inode, struct file *file)
return single_open(file, proc_cgroup_show, pid);
}
-struct file_operations proc_cgroup_operations = {
+const struct file_operations proc_cgroup_operations = {
.open = cgroup_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -3398,7 +3398,7 @@ static int cgroupstats_open(struct inode *inode, struct file *file)
return single_open(file, proc_cgroupstats_show, NULL);
}
-static struct file_operations proc_cgroupstats_operations = {
+static const struct file_operations proc_cgroupstats_operations = {
.open = cgroupstats_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -3708,8 +3708,10 @@ static void check_for_release(struct cgroup *cgrp)
void __css_put(struct cgroup_subsys_state *css)
{
struct cgroup *cgrp = css->cgroup;
+ int val;
rcu_read_lock();
- if (atomic_dec_return(&css->refcnt) == 1) {
+ val = atomic_dec_return(&css->refcnt);
+ if (val == 1) {
if (notify_on_release(cgrp)) {
set_bit(CGRP_RELEASABLE, &cgrp->flags);
check_for_release(cgrp);
@@ -3717,6 +3719,7 @@ void __css_put(struct cgroup_subsys_state *css)
cgroup_wakeup_rmdir_waiter(cgrp);
}
rcu_read_unlock();
+ WARN_ON_ONCE(val < 1);
}
/*
diff --git a/kernel/exit.c b/kernel/exit.c
index 5859f598c95..e61891f8012 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -991,8 +991,6 @@ NORET_TYPE void do_exit(long code)
tsk->mempolicy = NULL;
#endif
#ifdef CONFIG_FUTEX
- if (unlikely(!list_empty(&tsk->pi_state_list)))
- exit_pi_state_list(tsk);
if (unlikely(current->pi_state_cache))
kfree(current->pi_state_cache);
#endif
diff --git a/kernel/fork.c b/kernel/fork.c
index 266c6af6ef1..4c20fff8c13 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -570,12 +570,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
/* Get rid of any futexes when releasing the mm */
#ifdef CONFIG_FUTEX
- if (unlikely(tsk->robust_list))
+ if (unlikely(tsk->robust_list)) {
exit_robust_list(tsk);
+ tsk->robust_list = NULL;
+ }
#ifdef CONFIG_COMPAT
- if (unlikely(tsk->compat_robust_list))
+ if (unlikely(tsk->compat_robust_list)) {
compat_exit_robust_list(tsk);
+ tsk->compat_robust_list = NULL;
+ }
#endif
+ if (unlikely(!list_empty(&tsk->pi_state_list)))
+ exit_pi_state_list(tsk);
#endif
/* Get rid of any cached register state */
diff --git a/kernel/futex.c b/kernel/futex.c
index b911adceb2c..4949d336d88 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -916,8 +916,8 @@ retry:
hb1 = hash_futex(&key1);
hb2 = hash_futex(&key2);
- double_lock_hb(hb1, hb2);
retry_private:
+ double_lock_hb(hb1, hb2);
op_ret = futex_atomic_op_inuser(op, uaddr2);
if (unlikely(op_ret < 0)) {
@@ -2117,7 +2117,6 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
* Unqueue the futex_q and determine which it was.
*/
plist_del(&q->list, &q->list.plist);
- drop_futex_key_refs(&q->key);
if (timeout && !timeout->task)
ret = -ETIMEDOUT;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 6d7020490f9..3e1c36e7998 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -726,8 +726,6 @@ static int hrtimer_switch_to_hres(void)
/* "Retrigger" the interrupt to get things going */
retrigger_next_event(NULL);
local_irq_restore(flags);
- printk(KERN_DEBUG "Switched to high resolution mode on CPU %d\n",
- smp_processor_id());
return 1;
}
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index cfadc1291d0..5240d75f4c6 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1333,7 +1333,7 @@ static int __kprobes kprobes_open(struct inode *inode, struct file *filp)
return seq_open(filp, &kprobes_seq_ops);
}
-static struct file_operations debugfs_kprobes_operations = {
+static const struct file_operations debugfs_kprobes_operations = {
.open = kprobes_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -1515,7 +1515,7 @@ static ssize_t write_enabled_file_bool(struct file *file,
return count;
}
-static struct file_operations fops_kp = {
+static const struct file_operations fops_kp = {
.read = read_enabled_file_bool,
.write = write_enabled_file_bool,
};
diff --git a/kernel/module.c b/kernel/module.c
index fe748a86d45..8b7d8805819 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1992,12 +1992,14 @@ static inline unsigned long layout_symtab(struct module *mod,
Elf_Shdr *sechdrs,
unsigned int symindex,
unsigned int strindex,
- const Elf_Hdr *hdr,
+ const Elf_Ehdr *hdr,
const char *secstrings,
unsigned long *pstroffs,
unsigned long *strmap)
{
+ return 0;
}
+
static inline void add_kallsyms(struct module *mod,
Elf_Shdr *sechdrs,
unsigned int shnum,
@@ -2081,9 +2083,8 @@ static noinline struct module *load_module(void __user *umod,
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
-#ifdef CONFIG_KALLSYMS
unsigned long symoffs, stroffs, *strmap;
-#endif
+
mm_segment_t old_fs;
DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
diff --git a/kernel/panic.c b/kernel/panic.c
index bcdef26e333..96b45d0b4ba 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -90,6 +90,8 @@ NORET_TYPE void panic(const char * fmt, ...)
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
+ bust_spinlocks(0);
+
if (!panic_blink)
panic_blink = no_blink;
@@ -136,7 +138,6 @@ NORET_TYPE void panic(const char * fmt, ...)
mdelay(1);
i++;
}
- bust_spinlocks(0);
}
EXPORT_SYMBOL(panic);
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 0f86feb6db0..9d0b5c66588 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -20,6 +20,7 @@
#include <linux/percpu.h>
#include <linux/ptrace.h>
#include <linux/vmstat.h>
+#include <linux/vmalloc.h>
#include <linux/hardirq.h>
#include <linux/rculist.h>
#include <linux/uaccess.h>
@@ -1030,14 +1031,10 @@ void __perf_event_sched_out(struct perf_event_context *ctx,
update_context_time(ctx);
perf_disable();
- if (ctx->nr_active) {
- list_for_each_entry(event, &ctx->group_list, group_entry) {
- if (event != event->group_leader)
- event_sched_out(event, cpuctx, ctx);
- else
- group_sched_out(event, cpuctx, ctx);
- }
- }
+ if (ctx->nr_active)
+ list_for_each_entry(event, &ctx->group_list, group_entry)
+ group_sched_out(event, cpuctx, ctx);
+
perf_enable();
out:
spin_unlock(&ctx->lock);
@@ -1258,12 +1255,8 @@ __perf_event_sched_in(struct perf_event_context *ctx,
if (event->cpu != -1 && event->cpu != cpu)
continue;
- if (event != event->group_leader)
- event_sched_in(event, cpuctx, ctx, cpu);
- else {
- if (group_can_go_on(event, cpuctx, 1))
- group_sched_in(event, cpuctx, ctx, cpu);
- }
+ if (group_can_go_on(event, cpuctx, 1))
+ group_sched_in(event, cpuctx, ctx, cpu);
/*
* If this pinned group hasn't been scheduled,
@@ -1291,15 +1284,9 @@ __perf_event_sched_in(struct perf_event_context *ctx,
if (event->cpu != -1 && event->cpu != cpu)
continue;
- if (event != event->group_leader) {
- if (event_sched_in(event, cpuctx, ctx, cpu))
+ if (group_can_go_on(event, cpuctx, can_add_hw))
+ if (group_sched_in(event, cpuctx, ctx, cpu))
can_add_hw = 0;
- } else {
- if (group_can_go_on(event, cpuctx, can_add_hw)) {
- if (group_sched_in(event, cpuctx, ctx, cpu))
- can_add_hw = 0;
- }
- }
}
perf_enable();
out:
@@ -2105,49 +2092,31 @@ unlock:
rcu_read_unlock();
}
-static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+static unsigned long perf_data_size(struct perf_mmap_data *data)
{
- struct perf_event *event = vma->vm_file->private_data;
- struct perf_mmap_data *data;
- int ret = VM_FAULT_SIGBUS;
-
- if (vmf->flags & FAULT_FLAG_MKWRITE) {
- if (vmf->pgoff == 0)
- ret = 0;
- return ret;
- }
-
- rcu_read_lock();
- data = rcu_dereference(event->data);
- if (!data)
- goto unlock;
-
- if (vmf->pgoff == 0) {
- vmf->page = virt_to_page(data->user_page);
- } else {
- int nr = vmf->pgoff - 1;
-
- if ((unsigned)nr > data->nr_pages)
- goto unlock;
+ return data->nr_pages << (PAGE_SHIFT + data->data_order);
+}
- if (vmf->flags & FAULT_FLAG_WRITE)
- goto unlock;
+#ifndef CONFIG_PERF_USE_VMALLOC
- vmf->page = virt_to_page(data->data_pages[nr]);
- }
+/*
+ * Back perf_mmap() with regular GFP_KERNEL-0 pages.
+ */
- get_page(vmf->page);
- vmf->page->mapping = vma->vm_file->f_mapping;
- vmf->page->index = vmf->pgoff;
+static struct page *
+perf_mmap_to_page(struct perf_mmap_data *data, unsigned long pgoff)
+{
+ if (pgoff > data->nr_pages)
+ return NULL;
- ret = 0;
-unlock:
- rcu_read_unlock();
+ if (pgoff == 0)
+ return virt_to_page(data->user_page);
- return ret;
+ return virt_to_page(data->data_pages[pgoff - 1]);
}
-static int perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
+static struct perf_mmap_data *
+perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
{
struct perf_mmap_data *data;
unsigned long size;
@@ -2172,19 +2141,10 @@ static int perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
goto fail_data_pages;
}
+ data->data_order = 0;
data->nr_pages = nr_pages;
- atomic_set(&data->lock, -1);
-
- if (event->attr.watermark) {
- data->watermark = min_t(long, PAGE_SIZE * nr_pages,
- event->attr.wakeup_watermark);
- }
- if (!data->watermark)
- data->watermark = max(PAGE_SIZE, PAGE_SIZE * nr_pages / 4);
- rcu_assign_pointer(event->data, data);
-
- return 0;
+ return data;
fail_data_pages:
for (i--; i >= 0; i--)
@@ -2196,7 +2156,7 @@ fail_user_page:
kfree(data);
fail:
- return -ENOMEM;
+ return NULL;
}
static void perf_mmap_free_page(unsigned long addr)
@@ -2207,28 +2167,169 @@ static void perf_mmap_free_page(unsigned long addr)
__free_page(page);
}
-static void __perf_mmap_data_free(struct rcu_head *rcu_head)
+static void perf_mmap_data_free(struct perf_mmap_data *data)
{
- struct perf_mmap_data *data;
int i;
- data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
-
perf_mmap_free_page((unsigned long)data->user_page);
for (i = 0; i < data->nr_pages; i++)
perf_mmap_free_page((unsigned long)data->data_pages[i]);
+}
+
+#else
+
+/*
+ * Back perf_mmap() with vmalloc memory.
+ *
+ * Required for architectures that have d-cache aliasing issues.
+ */
+
+static struct page *
+perf_mmap_to_page(struct perf_mmap_data *data, unsigned long pgoff)
+{
+ if (pgoff > (1UL << data->data_order))
+ return NULL;
+
+ return vmalloc_to_page((void *)data->user_page + pgoff * PAGE_SIZE);
+}
+
+static void perf_mmap_unmark_page(void *addr)
+{
+ struct page *page = vmalloc_to_page(addr);
+
+ page->mapping = NULL;
+}
+
+static void perf_mmap_data_free_work(struct work_struct *work)
+{
+ struct perf_mmap_data *data;
+ void *base;
+ int i, nr;
+
+ data = container_of(work, struct perf_mmap_data, work);
+ nr = 1 << data->data_order;
+
+ base = data->user_page;
+ for (i = 0; i < nr + 1; i++)
+ perf_mmap_unmark_page(base + (i * PAGE_SIZE));
+
+ vfree(base);
+}
+static void perf_mmap_data_free(struct perf_mmap_data *data)
+{
+ schedule_work(&data->work);
+}
+
+static struct perf_mmap_data *
+perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
+{
+ struct perf_mmap_data *data;
+ unsigned long size;
+ void *all_buf;
+
+ WARN_ON(atomic_read(&event->mmap_count));
+
+ size = sizeof(struct perf_mmap_data);
+ size += sizeof(void *);
+
+ data = kzalloc(size, GFP_KERNEL);
+ if (!data)
+ goto fail;
+
+ INIT_WORK(&data->work, perf_mmap_data_free_work);
+
+ all_buf = vmalloc_user((nr_pages + 1) * PAGE_SIZE);
+ if (!all_buf)
+ goto fail_all_buf;
+
+ data->user_page = all_buf;
+ data->data_pages[0] = all_buf + PAGE_SIZE;
+ data->data_order = ilog2(nr_pages);
+ data->nr_pages = 1;
+
+ return data;
+
+fail_all_buf:
+ kfree(data);
+
+fail:
+ return NULL;
+}
+
+#endif
+
+static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct perf_event *event = vma->vm_file->private_data;
+ struct perf_mmap_data *data;
+ int ret = VM_FAULT_SIGBUS;
+
+ if (vmf->flags & FAULT_FLAG_MKWRITE) {
+ if (vmf->pgoff == 0)
+ ret = 0;
+ return ret;
+ }
+
+ rcu_read_lock();
+ data = rcu_dereference(event->data);
+ if (!data)
+ goto unlock;
+
+ if (vmf->pgoff && (vmf->flags & FAULT_FLAG_WRITE))
+ goto unlock;
+
+ vmf->page = perf_mmap_to_page(data, vmf->pgoff);
+ if (!vmf->page)
+ goto unlock;
+
+ get_page(vmf->page);
+ vmf->page->mapping = vma->vm_file->f_mapping;
+ vmf->page->index = vmf->pgoff;
+
+ ret = 0;
+unlock:
+ rcu_read_unlock();
+
+ return ret;
+}
+
+static void
+perf_mmap_data_init(struct perf_event *event, struct perf_mmap_data *data)
+{
+ long max_size = perf_data_size(data);
+
+ atomic_set(&data->lock, -1);
+
+ if (event->attr.watermark) {
+ data->watermark = min_t(long, max_size,
+ event->attr.wakeup_watermark);
+ }
+
+ if (!data->watermark)
+ data->watermark = max_t(long, PAGE_SIZE, max_size / 2);
+
+
+ rcu_assign_pointer(event->data, data);
+}
+
+static void perf_mmap_data_free_rcu(struct rcu_head *rcu_head)
+{
+ struct perf_mmap_data *data;
+
+ data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
+ perf_mmap_data_free(data);
kfree(data);
}
-static void perf_mmap_data_free(struct perf_event *event)
+static void perf_mmap_data_release(struct perf_event *event)
{
struct perf_mmap_data *data = event->data;
WARN_ON(atomic_read(&event->mmap_count));
rcu_assign_pointer(event->data, NULL);
- call_rcu(&data->rcu_head, __perf_mmap_data_free);
+ call_rcu(&data->rcu_head, perf_mmap_data_free_rcu);
}
static void perf_mmap_open(struct vm_area_struct *vma)
@@ -2244,11 +2345,12 @@ static void perf_mmap_close(struct vm_area_struct *vma)
WARN_ON_ONCE(event->ctx->parent_ctx);
if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) {
+ unsigned long size = perf_data_size(event->data);
struct user_struct *user = current_user();
- atomic_long_sub(event->data->nr_pages + 1, &user->locked_vm);
+ atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm);
vma->vm_mm->locked_vm -= event->data->nr_locked;
- perf_mmap_data_free(event);
+ perf_mmap_data_release(event);
mutex_unlock(&event->mmap_mutex);
}
}
@@ -2266,6 +2368,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
unsigned long user_locked, user_lock_limit;
struct user_struct *user = current_user();
unsigned long locked, lock_limit;
+ struct perf_mmap_data *data;
unsigned long vma_size;
unsigned long nr_pages;
long user_extra, extra;
@@ -2328,10 +2431,15 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
}
WARN_ON(event->data);
- ret = perf_mmap_data_alloc(event, nr_pages);
- if (ret)
+
+ data = perf_mmap_data_alloc(event, nr_pages);
+ ret = -ENOMEM;
+ if (!data)
goto unlock;
+ ret = 0;
+ perf_mmap_data_init(event, data);
+
atomic_set(&event->mmap_count, 1);
atomic_long_add(user_extra, &user->locked_vm);
vma->vm_mm->locked_vm += extra;
@@ -2519,7 +2627,7 @@ static bool perf_output_space(struct perf_mmap_data *data, unsigned long tail,
if (!data->writable)
return true;
- mask = (data->nr_pages << PAGE_SHIFT) - 1;
+ mask = perf_data_size(data) - 1;
offset = (offset - tail) & mask;
head = (head - tail) & mask;
@@ -2624,7 +2732,7 @@ void perf_output_copy(struct perf_output_handle *handle,
const void *buf, unsigned int len)
{
unsigned int pages_mask;
- unsigned int offset;
+ unsigned long offset;
unsigned int size;
void **pages;
@@ -2633,12 +2741,14 @@ void perf_output_copy(struct perf_output_handle *handle,
pages = handle->data->data_pages;
do {
- unsigned int page_offset;
+ unsigned long page_offset;
+ unsigned long page_size;
int nr;
nr = (offset >> PAGE_SHIFT) & pages_mask;
- page_offset = offset & (PAGE_SIZE - 1);
- size = min_t(unsigned int, PAGE_SIZE - page_offset, len);
+ page_size = 1UL << (handle->data->data_order + PAGE_SHIFT);
+ page_offset = offset & (page_size - 1);
+ size = min_t(unsigned int, page_size - page_offset, len);
memcpy(pages[nr] + page_offset, buf, size);
@@ -4781,9 +4891,7 @@ int perf_event_init_task(struct task_struct *child)
* We dont have to disable NMIs - we are only looking at
* the list, not manipulating it:
*/
- list_for_each_entry_rcu(event, &parent_ctx->event_list, event_entry) {
- if (event != event->group_leader)
- continue;
+ list_for_each_entry(event, &parent_ctx->group_list, group_entry) {
if (!event->attr.inherit) {
inherited_all = 0;
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 37ac4548308..400183346ad 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -46,22 +46,15 @@
#include <linux/module.h>
#include <linux/kernel_stat.h>
-enum rcu_barrier {
- RCU_BARRIER_STD,
- RCU_BARRIER_BH,
- RCU_BARRIER_SCHED,
-};
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+static struct lock_class_key rcu_lock_key;
+struct lockdep_map rcu_lock_map =
+ STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key);
+EXPORT_SYMBOL_GPL(rcu_lock_map);
+#endif
-static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
-static atomic_t rcu_barrier_cpu_count;
-static DEFINE_MUTEX(rcu_barrier_mutex);
-static struct completion rcu_barrier_completion;
int rcu_scheduler_active __read_mostly;
-static atomic_t rcu_migrate_type_count = ATOMIC_INIT(0);
-static struct rcu_head rcu_migrate_head[3];
-static DECLARE_WAIT_QUEUE_HEAD(rcu_migrate_wq);
-
/*
* Awaken the corresponding synchronize_rcu() instance now that a
* grace period has elapsed.
@@ -164,129 +157,10 @@ void synchronize_rcu_bh(void)
}
EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
-static void rcu_barrier_callback(struct rcu_head *notused)
-{
- if (atomic_dec_and_test(&rcu_barrier_cpu_count))
- complete(&rcu_barrier_completion);
-}
-
-/*
- * Called with preemption disabled, and from cross-cpu IRQ context.
- */
-static void rcu_barrier_func(void *type)
-{
- int cpu = smp_processor_id();
- struct rcu_head *head = &per_cpu(rcu_barrier_head, cpu);
-
- atomic_inc(&rcu_barrier_cpu_count);
- switch ((enum rcu_barrier)type) {
- case RCU_BARRIER_STD:
- call_rcu(head, rcu_barrier_callback);
- break;
- case RCU_BARRIER_BH:
- call_rcu_bh(head, rcu_barrier_callback);
- break;
- case RCU_BARRIER_SCHED:
- call_rcu_sched(head, rcu_barrier_callback);
- break;
- }
-}
-
-static inline void wait_migrated_callbacks(void)
-{
- wait_event(rcu_migrate_wq, !atomic_read(&rcu_migrate_type_count));
- smp_mb(); /* In case we didn't sleep. */
-}
-
-/*
- * Orchestrate the specified type of RCU barrier, waiting for all
- * RCU callbacks of the specified type to complete.
- */
-static void _rcu_barrier(enum rcu_barrier type)
-{
- BUG_ON(in_interrupt());
- /* Take cpucontrol mutex to protect against CPU hotplug */
- mutex_lock(&rcu_barrier_mutex);
- init_completion(&rcu_barrier_completion);
- /*
- * Initialize rcu_barrier_cpu_count to 1, then invoke
- * rcu_barrier_func() on each CPU, so that each CPU also has
- * incremented rcu_barrier_cpu_count. Only then is it safe to
- * decrement rcu_barrier_cpu_count -- otherwise the first CPU
- * might complete its grace period before all of the other CPUs
- * did their increment, causing this function to return too
- * early.
- */
- atomic_set(&rcu_barrier_cpu_count, 1);
- on_each_cpu(rcu_barrier_func, (void *)type, 1);
- if (atomic_dec_and_test(&rcu_barrier_cpu_count))
- complete(&rcu_barrier_completion);
- wait_for_completion(&rcu_barrier_completion);
- mutex_unlock(&rcu_barrier_mutex);
- wait_migrated_callbacks();
-}
-
-/**
- * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete.
- */
-void rcu_barrier(void)
-{
- _rcu_barrier(RCU_BARRIER_STD);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier);
-
-/**
- * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
- */
-void rcu_barrier_bh(void)
-{
- _rcu_barrier(RCU_BARRIER_BH);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier_bh);
-
-/**
- * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks.
- */
-void rcu_barrier_sched(void)
-{
- _rcu_barrier(RCU_BARRIER_SCHED);
-}
-EXPORT_SYMBOL_GPL(rcu_barrier_sched);
-
-static void rcu_migrate_callback(struct rcu_head *notused)
-{
- if (atomic_dec_and_test(&rcu_migrate_type_count))
- wake_up(&rcu_migrate_wq);
-}
-
-extern int rcu_cpu_notify(struct notifier_block *self,
- unsigned long action, void *hcpu);
-
static int __cpuinit rcu_barrier_cpu_hotplug(struct notifier_block *self,
unsigned long action, void *hcpu)
{
- rcu_cpu_notify(self, action, hcpu);
- if (action == CPU_DYING) {
- /*
- * preempt_disable() in on_each_cpu() prevents stop_machine(),
- * so when "on_each_cpu(rcu_barrier_func, (void *)type, 1);"
- * returns, all online cpus have queued rcu_barrier_func(),
- * and the dead cpu(if it exist) queues rcu_migrate_callback()s.
- *
- * These callbacks ensure _rcu_barrier() waits for all
- * RCU callbacks of the specified type to complete.
- */
- atomic_set(&rcu_migrate_type_count, 3);
- call_rcu_bh(rcu_migrate_head, rcu_migrate_callback);
- call_rcu_sched(rcu_migrate_head + 1, rcu_migrate_callback);
- call_rcu(rcu_migrate_head + 2, rcu_migrate_callback);
- } else if (action == CPU_DOWN_PREPARE) {
- /* Don't need to wait until next removal operation. */
- /* rcu_migrate_head is protected by cpu_add_remove_lock */
- wait_migrated_callbacks();
- }
-
- return NOTIFY_OK;
+ return rcu_cpu_notify(self, action, hcpu);
}
void __init rcu_init(void)
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 233768f21f9..697c0a0229d 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -606,8 +606,6 @@ static struct rcu_torture_ops sched_ops_sync = {
.name = "sched_sync"
};
-extern int rcu_expedited_torture_stats(char *page);
-
static struct rcu_torture_ops sched_expedited_ops = {
.init = rcu_sync_torture_init,
.cleanup = NULL,
@@ -650,7 +648,7 @@ rcu_torture_writer(void *arg)
old_rp = rcu_torture_current;
rp->rtort_mbtest = 1;
rcu_assign_pointer(rcu_torture_current, rp);
- smp_wmb();
+ smp_wmb(); /* Mods to old_rp must follow rcu_assign_pointer() */
if (old_rp) {
i = old_rp->rtort_pipe_count;
if (i > RCU_TORTURE_PIPE_LEN)
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 52b06f6e158..705f02ac743 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -49,13 +49,6 @@
#include "rcutree.h"
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-static struct lock_class_key rcu_lock_key;
-struct lockdep_map rcu_lock_map =
- STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key);
-EXPORT_SYMBOL_GPL(rcu_lock_map);
-#endif
-
/* Data structures. */
#define RCU_STATE_INITIALIZER(name) { \
@@ -70,6 +63,9 @@ EXPORT_SYMBOL_GPL(rcu_lock_map);
.gpnum = -300, \
.completed = -300, \
.onofflock = __SPIN_LOCK_UNLOCKED(&name.onofflock), \
+ .orphan_cbs_list = NULL, \
+ .orphan_cbs_tail = &name.orphan_cbs_list, \
+ .orphan_qlen = 0, \
.fqslock = __SPIN_LOCK_UNLOCKED(&name.fqslock), \
.n_force_qs = 0, \
.n_force_qs_ngp = 0, \
@@ -81,24 +77,16 @@ DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
-extern long rcu_batches_completed_sched(void);
-static struct rcu_node *rcu_get_root(struct rcu_state *rsp);
-static void cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp,
- struct rcu_node *rnp, unsigned long flags);
-static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags);
-#ifdef CONFIG_HOTPLUG_CPU
-static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp);
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-static void __rcu_process_callbacks(struct rcu_state *rsp,
- struct rcu_data *rdp);
-static void __call_rcu(struct rcu_head *head,
- void (*func)(struct rcu_head *rcu),
- struct rcu_state *rsp);
-static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp);
-static void __cpuinit rcu_init_percpu_data(int cpu, struct rcu_state *rsp,
- int preemptable);
-#include "rcutree_plugin.h"
+/*
+ * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s
+ * permit this function to be invoked without holding the root rcu_node
+ * structure's ->lock, but of course results can be subject to change.
+ */
+static int rcu_gp_in_progress(struct rcu_state *rsp)
+{
+ return ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum);
+}
/*
* Note a quiescent state. Because we do not need to know
@@ -137,6 +125,10 @@ static int blimit = 10; /* Maximum callbacks per softirq. */
static int qhimark = 10000; /* If this many pending, ignore blimit. */
static int qlowmark = 100; /* Once only this many pending, use blimit. */
+module_param(blimit, int, 0);
+module_param(qhimark, int, 0);
+module_param(qlowmark, int, 0);
+
static void force_quiescent_state(struct rcu_state *rsp, int relaxed);
static int rcu_pending(int cpu);
@@ -173,9 +165,7 @@ cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
static int
cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
{
- /* ACCESS_ONCE() because we are accessing outside of lock. */
- return *rdp->nxttail[RCU_DONE_TAIL] &&
- ACCESS_ONCE(rsp->completed) == ACCESS_ONCE(rsp->gpnum);
+ return *rdp->nxttail[RCU_DONE_TAIL] && !rcu_gp_in_progress(rsp);
}
/*
@@ -369,7 +359,7 @@ static long dyntick_recall_completed(struct rcu_state *rsp)
/*
* Snapshot the specified CPU's dynticks counter so that we can later
* credit them with an implicit quiescent state. Return 1 if this CPU
- * is already in a quiescent state courtesy of dynticks idle mode.
+ * is in dynticks idle mode, which is an extended quiescent state.
*/
static int dyntick_save_progress_counter(struct rcu_data *rdp)
{
@@ -475,30 +465,34 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
long delta;
unsigned long flags;
struct rcu_node *rnp = rcu_get_root(rsp);
- struct rcu_node *rnp_cur = rsp->level[NUM_RCU_LVLS - 1];
- struct rcu_node *rnp_end = &rsp->node[NUM_RCU_NODES];
/* Only let one CPU complain about others per time interval. */
spin_lock_irqsave(&rnp->lock, flags);
delta = jiffies - rsp->jiffies_stall;
- if (delta < RCU_STALL_RAT_DELAY || rsp->gpnum == rsp->completed) {
+ if (delta < RCU_STALL_RAT_DELAY || !rcu_gp_in_progress(rsp)) {
spin_unlock_irqrestore(&rnp->lock, flags);
return;
}
rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_RECHECK;
+
+ /*
+ * Now rat on any tasks that got kicked up to the root rcu_node
+ * due to CPU offlining.
+ */
+ rcu_print_task_stall(rnp);
spin_unlock_irqrestore(&rnp->lock, flags);
/* OK, time to rat on our buddy... */
printk(KERN_ERR "INFO: RCU detected CPU stalls:");
- for (; rnp_cur < rnp_end; rnp_cur++) {
+ rcu_for_each_leaf_node(rsp, rnp) {
rcu_print_task_stall(rnp);
- if (rnp_cur->qsmask == 0)
+ if (rnp->qsmask == 0)
continue;
- for (cpu = 0; cpu <= rnp_cur->grphi - rnp_cur->grplo; cpu++)
- if (rnp_cur->qsmask & (1UL << cpu))
- printk(" %d", rnp_cur->grplo + cpu);
+ for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
+ if (rnp->qsmask & (1UL << cpu))
+ printk(" %d", rnp->grplo + cpu);
}
printk(" (detected by %d, t=%ld jiffies)\n",
smp_processor_id(), (long)(jiffies - rsp->gp_start));
@@ -537,8 +531,7 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
/* We haven't checked in, so go dump stack. */
print_cpu_stall(rsp);
- } else if (rsp->gpnum != rsp->completed &&
- delta >= RCU_STALL_RAT_DELAY) {
+ } else if (rcu_gp_in_progress(rsp) && delta >= RCU_STALL_RAT_DELAY) {
/* They had two time units to dump stack, so complain. */
print_other_cpu_stall(rsp);
@@ -617,9 +610,15 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
note_new_gpnum(rsp, rdp);
/*
- * Because we are first, we know that all our callbacks will
- * be covered by this upcoming grace period, even the ones
- * that were registered arbitrarily recently.
+ * Because this CPU just now started the new grace period, we know
+ * that all of its callbacks will be covered by this upcoming grace
+ * period, even the ones that were registered arbitrarily recently.
+ * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL.
+ *
+ * Other CPUs cannot be sure exactly when the grace period started.
+ * Therefore, their recently registered callbacks must pass through
+ * an additional RCU_NEXT_READY stage, so that they will be handled
+ * by the next RCU grace period.
*/
rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
@@ -657,7 +656,7 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
* one corresponding to this CPU, due to the fact that we have
* irqs disabled.
*/
- for (rnp = &rsp->node[0]; rnp < &rsp->node[NUM_RCU_NODES]; rnp++) {
+ rcu_for_each_node_breadth_first(rsp, rnp) {
spin_lock(&rnp->lock); /* irqs already disabled. */
rcu_preempt_check_blocked_tasks(rnp);
rnp->qsmask = rnp->qsmaskinit;
@@ -703,9 +702,9 @@ rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
* hold rnp->lock, as required by rcu_start_gp(), which will release it.
*/
static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags)
- __releases(rnp->lock)
+ __releases(rcu_get_root(rsp)->lock)
{
- WARN_ON_ONCE(rsp->completed == rsp->gpnum);
+ WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
rsp->completed = rsp->gpnum;
rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]);
rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */
@@ -842,17 +841,63 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
#ifdef CONFIG_HOTPLUG_CPU
/*
+ * Move a dying CPU's RCU callbacks to the ->orphan_cbs_list for the
+ * specified flavor of RCU. The callbacks will be adopted by the next
+ * _rcu_barrier() invocation or by the CPU_DEAD notifier, whichever
+ * comes first. Because this is invoked from the CPU_DYING notifier,
+ * irqs are already disabled.
+ */
+static void rcu_send_cbs_to_orphanage(struct rcu_state *rsp)
+{
+ int i;
+ struct rcu_data *rdp = rsp->rda[smp_processor_id()];
+
+ if (rdp->nxtlist == NULL)
+ return; /* irqs disabled, so comparison is stable. */
+ spin_lock(&rsp->onofflock); /* irqs already disabled. */
+ *rsp->orphan_cbs_tail = rdp->nxtlist;
+ rsp->orphan_cbs_tail = rdp->nxttail[RCU_NEXT_TAIL];
+ rdp->nxtlist = NULL;
+ for (i = 0; i < RCU_NEXT_SIZE; i++)
+ rdp->nxttail[i] = &rdp->nxtlist;
+ rsp->orphan_qlen += rdp->qlen;
+ rdp->qlen = 0;
+ spin_unlock(&rsp->onofflock); /* irqs remain disabled. */
+}
+
+/*
+ * Adopt previously orphaned RCU callbacks.
+ */
+static void rcu_adopt_orphan_cbs(struct rcu_state *rsp)
+{
+ unsigned long flags;
+ struct rcu_data *rdp;
+
+ spin_lock_irqsave(&rsp->onofflock, flags);
+ rdp = rsp->rda[smp_processor_id()];
+ if (rsp->orphan_cbs_list == NULL) {
+ spin_unlock_irqrestore(&rsp->onofflock, flags);
+ return;
+ }
+ *rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_cbs_list;
+ rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_cbs_tail;
+ rdp->qlen += rsp->orphan_qlen;
+ rsp->orphan_cbs_list = NULL;
+ rsp->orphan_cbs_tail = &rsp->orphan_cbs_list;
+ rsp->orphan_qlen = 0;
+ spin_unlock_irqrestore(&rsp->onofflock, flags);
+}
+
+/*
* Remove the outgoing CPU from the bitmasks in the rcu_node hierarchy
* and move all callbacks from the outgoing CPU to the current one.
*/
static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
{
- int i;
unsigned long flags;
long lastcomp;
unsigned long mask;
struct rcu_data *rdp = rsp->rda[cpu];
- struct rcu_data *rdp_me;
struct rcu_node *rnp;
/* Exclude any attempts to start a new grace period. */
@@ -875,32 +920,9 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
} while (rnp != NULL);
lastcomp = rsp->completed;
- spin_unlock(&rsp->onofflock); /* irqs remain disabled. */
+ spin_unlock_irqrestore(&rsp->onofflock, flags);
- /*
- * Move callbacks from the outgoing CPU to the running CPU.
- * Note that the outgoing CPU is now quiscent, so it is now
- * (uncharacteristically) safe to access its rcu_data structure.
- * Note also that we must carefully retain the order of the
- * outgoing CPU's callbacks in order for rcu_barrier() to work
- * correctly. Finally, note that we start all the callbacks
- * afresh, even those that have passed through a grace period
- * and are therefore ready to invoke. The theory is that hotplug
- * events are rare, and that if they are frequent enough to
- * indefinitely delay callbacks, you have far worse things to
- * be worrying about.
- */
- rdp_me = rsp->rda[smp_processor_id()];
- if (rdp->nxtlist != NULL) {
- *rdp_me->nxttail[RCU_NEXT_TAIL] = rdp->nxtlist;
- rdp_me->nxttail[RCU_NEXT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
- rdp->nxtlist = NULL;
- for (i = 0; i < RCU_NEXT_SIZE; i++)
- rdp->nxttail[i] = &rdp->nxtlist;
- rdp_me->qlen += rdp->qlen;
- rdp->qlen = 0;
- }
- local_irq_restore(flags);
+ rcu_adopt_orphan_cbs(rsp);
}
/*
@@ -918,6 +940,14 @@ static void rcu_offline_cpu(int cpu)
#else /* #ifdef CONFIG_HOTPLUG_CPU */
+static void rcu_send_cbs_to_orphanage(struct rcu_state *rsp)
+{
+}
+
+static void rcu_adopt_orphan_cbs(struct rcu_state *rsp)
+{
+}
+
static void rcu_offline_cpu(int cpu)
{
}
@@ -1050,33 +1080,32 @@ static int rcu_process_dyntick(struct rcu_state *rsp, long lastcomp,
int cpu;
unsigned long flags;
unsigned long mask;
- struct rcu_node *rnp_cur = rsp->level[NUM_RCU_LVLS - 1];
- struct rcu_node *rnp_end = &rsp->node[NUM_RCU_NODES];
+ struct rcu_node *rnp;
- for (; rnp_cur < rnp_end; rnp_cur++) {
+ rcu_for_each_leaf_node(rsp, rnp) {
mask = 0;
- spin_lock_irqsave(&rnp_cur->lock, flags);
+ spin_lock_irqsave(&rnp->lock, flags);
if (rsp->completed != lastcomp) {
- spin_unlock_irqrestore(&rnp_cur->lock, flags);
+ spin_unlock_irqrestore(&rnp->lock, flags);
return 1;
}
- if (rnp_cur->qsmask == 0) {
- spin_unlock_irqrestore(&rnp_cur->lock, flags);
+ if (rnp->qsmask == 0) {
+ spin_unlock_irqrestore(&rnp->lock, flags);
continue;
}
- cpu = rnp_cur->grplo;
+ cpu = rnp->grplo;
bit = 1;
- for (; cpu <= rnp_cur->grphi; cpu++, bit <<= 1) {
- if ((rnp_cur->qsmask & bit) != 0 && f(rsp->rda[cpu]))
+ for (; cpu <= rnp->grphi; cpu++, bit <<= 1) {
+ if ((rnp->qsmask & bit) != 0 && f(rsp->rda[cpu]))
mask |= bit;
}
if (mask != 0 && rsp->completed == lastcomp) {
- /* cpu_quiet_msk() releases rnp_cur->lock. */
- cpu_quiet_msk(mask, rsp, rnp_cur, flags);
+ /* cpu_quiet_msk() releases rnp->lock. */
+ cpu_quiet_msk(mask, rsp, rnp, flags);
continue;
}
- spin_unlock_irqrestore(&rnp_cur->lock, flags);
+ spin_unlock_irqrestore(&rnp->lock, flags);
}
return 0;
}
@@ -1092,7 +1121,7 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
struct rcu_node *rnp = rcu_get_root(rsp);
u8 signaled;
- if (ACCESS_ONCE(rsp->completed) == ACCESS_ONCE(rsp->gpnum))
+ if (!rcu_gp_in_progress(rsp))
return; /* No grace period in progress, nothing to force. */
if (!spin_trylock_irqsave(&rsp->fqslock, flags)) {
rsp->n_force_qs_lh++; /* Inexact, can lose counts. Tough! */
@@ -1251,7 +1280,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
rdp->nxttail[RCU_NEXT_TAIL] = &head->next;
/* Start a new grace period if one not already started. */
- if (ACCESS_ONCE(rsp->completed) == ACCESS_ONCE(rsp->gpnum)) {
+ if (!rcu_gp_in_progress(rsp)) {
unsigned long nestflag;
struct rcu_node *rnp_root = rcu_get_root(rsp);
@@ -1331,7 +1360,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
}
/* Has an RCU GP gone long enough to send resched IPIs &c? */
- if (ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum) &&
+ if (rcu_gp_in_progress(rsp) &&
((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)) {
rdp->n_rp_need_fqs++;
return 1;
@@ -1368,6 +1397,82 @@ int rcu_needs_cpu(int cpu)
rcu_preempt_needs_cpu(cpu);
}
+static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
+static atomic_t rcu_barrier_cpu_count;
+static DEFINE_MUTEX(rcu_barrier_mutex);
+static struct completion rcu_barrier_completion;
+
+static void rcu_barrier_callback(struct rcu_head *notused)
+{
+ if (atomic_dec_and_test(&rcu_barrier_cpu_count))
+ complete(&rcu_barrier_completion);
+}
+
+/*
+ * Called with preemption disabled, and from cross-cpu IRQ context.
+ */
+static void rcu_barrier_func(void *type)
+{
+ int cpu = smp_processor_id();
+ struct rcu_head *head = &per_cpu(rcu_barrier_head, cpu);
+ void (*call_rcu_func)(struct rcu_head *head,
+ void (*func)(struct rcu_head *head));
+
+ atomic_inc(&rcu_barrier_cpu_count);
+ call_rcu_func = type;
+ call_rcu_func(head, rcu_barrier_callback);
+}
+
+/*
+ * Orchestrate the specified type of RCU barrier, waiting for all
+ * RCU callbacks of the specified type to complete.
+ */
+static void _rcu_barrier(struct rcu_state *rsp,
+ void (*call_rcu_func)(struct rcu_head *head,
+ void (*func)(struct rcu_head *head)))
+{
+ BUG_ON(in_interrupt());
+ /* Take mutex to serialize concurrent rcu_barrier() requests. */
+ mutex_lock(&rcu_barrier_mutex);
+ init_completion(&rcu_barrier_completion);
+ /*
+ * Initialize rcu_barrier_cpu_count to 1, then invoke
+ * rcu_barrier_func() on each CPU, so that each CPU also has
+ * incremented rcu_barrier_cpu_count. Only then is it safe to
+ * decrement rcu_barrier_cpu_count -- otherwise the first CPU
+ * might complete its grace period before all of the other CPUs
+ * did their increment, causing this function to return too
+ * early.
+ */
+ atomic_set(&rcu_barrier_cpu_count, 1);
+ preempt_disable(); /* stop CPU_DYING from filling orphan_cbs_list */
+ rcu_adopt_orphan_cbs(rsp);
+ on_each_cpu(rcu_barrier_func, (void *)call_rcu_func, 1);
+ preempt_enable(); /* CPU_DYING can again fill orphan_cbs_list */
+ if (atomic_dec_and_test(&rcu_barrier_cpu_count))
+ complete(&rcu_barrier_completion);
+ wait_for_completion(&rcu_barrier_completion);
+ mutex_unlock(&rcu_barrier_mutex);
+}
+
+/**
+ * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
+ */
+void rcu_barrier_bh(void)
+{
+ _rcu_barrier(&rcu_bh_state, call_rcu_bh);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_bh);
+
+/**
+ * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks.
+ */
+void rcu_barrier_sched(void)
+{
+ _rcu_barrier(&rcu_sched_state, call_rcu_sched);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_sched);
+
/*
* Do boot-time initialization of a CPU's per-CPU RCU data.
*/
@@ -1464,6 +1569,22 @@ int __cpuinit rcu_cpu_notify(struct notifier_block *self,
case CPU_UP_PREPARE_FROZEN:
rcu_online_cpu(cpu);
break;
+ case CPU_DYING:
+ case CPU_DYING_FROZEN:
+ /*
+ * preempt_disable() in _rcu_barrier() prevents stop_machine(),
+ * so when "on_each_cpu(rcu_barrier_func, (void *)type, 1);"
+ * returns, all online cpus have queued rcu_barrier_func().
+ * The dying CPU clears its cpu_online_mask bit and
+ * moves all of its RCU callbacks to ->orphan_cbs_list
+ * in the context of stop_machine(), so subsequent calls
+ * to _rcu_barrier() will adopt these callbacks and only
+ * then queue rcu_barrier_func() on all remaining CPUs.
+ */
+ rcu_send_cbs_to_orphanage(&rcu_bh_state);
+ rcu_send_cbs_to_orphanage(&rcu_sched_state);
+ rcu_preempt_send_cbs_to_orphanage();
+ break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
case CPU_UP_CANCELED:
@@ -1526,7 +1647,8 @@ static void __init rcu_init_one(struct rcu_state *rsp)
cpustride *= rsp->levelspread[i];
rnp = rsp->level[i];
for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) {
- spin_lock_init(&rnp->lock);
+ if (rnp != rcu_get_root(rsp))
+ spin_lock_init(&rnp->lock);
rnp->gpnum = 0;
rnp->qsmask = 0;
rnp->qsmaskinit = 0;
@@ -1549,6 +1671,7 @@ static void __init rcu_init_one(struct rcu_state *rsp)
INIT_LIST_HEAD(&rnp->blocked_tasks[1]);
}
}
+ spin_lock_init(&rcu_get_root(rsp)->lock);
}
/*
@@ -1558,6 +1681,10 @@ static void __init rcu_init_one(struct rcu_state *rsp)
*/
#define RCU_INIT_FLAVOR(rsp, rcu_data) \
do { \
+ int i; \
+ int j; \
+ struct rcu_node *rnp; \
+ \
rcu_init_one(rsp); \
rnp = (rsp)->level[NUM_RCU_LVLS - 1]; \
j = 0; \
@@ -1570,31 +1697,8 @@ do { \
} \
} while (0)
-#ifdef CONFIG_TREE_PREEMPT_RCU
-
-void __init __rcu_init_preempt(void)
-{
- int i; /* All used by RCU_INIT_FLAVOR(). */
- int j;
- struct rcu_node *rnp;
-
- RCU_INIT_FLAVOR(&rcu_preempt_state, rcu_preempt_data);
-}
-
-#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
-
-void __init __rcu_init_preempt(void)
-{
-}
-
-#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
-
void __init __rcu_init(void)
{
- int i; /* All used by RCU_INIT_FLAVOR(). */
- int j;
- struct rcu_node *rnp;
-
rcu_bootup_announce();
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
@@ -1605,6 +1709,4 @@ void __init __rcu_init(void)
open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
}
-module_param(blimit, int, 0);
-module_param(qhimark, int, 0);
-module_param(qlowmark, int, 0);
+#include "rcutree_plugin.h"
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index 8e8287a983c..b40ac570604 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -48,14 +48,14 @@
#elif NR_CPUS <= RCU_FANOUT_SQ
# define NUM_RCU_LVLS 2
# define NUM_RCU_LVL_0 1
-# define NUM_RCU_LVL_1 (((NR_CPUS) + RCU_FANOUT - 1) / RCU_FANOUT)
+# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
# define NUM_RCU_LVL_2 (NR_CPUS)
# define NUM_RCU_LVL_3 0
#elif NR_CPUS <= RCU_FANOUT_CUBE
# define NUM_RCU_LVLS 3
# define NUM_RCU_LVL_0 1
-# define NUM_RCU_LVL_1 (((NR_CPUS) + RCU_FANOUT_SQ - 1) / RCU_FANOUT_SQ)
-# define NUM_RCU_LVL_2 (((NR_CPUS) + (RCU_FANOUT) - 1) / (RCU_FANOUT))
+# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_SQ)
+# define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
# define NUM_RCU_LVL_3 NR_CPUS
#else
# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS"
@@ -79,15 +79,21 @@ struct rcu_dynticks {
* Definition for node within the RCU grace-period-detection hierarchy.
*/
struct rcu_node {
- spinlock_t lock;
+ spinlock_t lock; /* Root rcu_node's lock protects some */
+ /* rcu_state fields as well as following. */
long gpnum; /* Current grace period for this node. */
/* This will either be equal to or one */
/* behind the root rcu_node's gpnum. */
unsigned long qsmask; /* CPUs or groups that need to switch in */
/* order for current grace period to proceed.*/
+ /* In leaf rcu_node, each bit corresponds to */
+ /* an rcu_data structure, otherwise, each */
+ /* bit corresponds to a child rcu_node */
+ /* structure. */
unsigned long qsmaskinit;
/* Per-GP initialization for qsmask. */
unsigned long grpmask; /* Mask to apply to parent qsmask. */
+ /* Only one bit will be set in this mask. */
int grplo; /* lowest-numbered CPU or group here. */
int grphi; /* highest-numbered CPU or group here. */
u8 grpnum; /* CPU/group number for next level up. */
@@ -95,8 +101,23 @@ struct rcu_node {
struct rcu_node *parent;
struct list_head blocked_tasks[2];
/* Tasks blocked in RCU read-side critsect. */
+ /* Grace period number (->gpnum) x blocked */
+ /* by tasks on the (x & 0x1) element of the */
+ /* blocked_tasks[] array. */
} ____cacheline_internodealigned_in_smp;
+/*
+ * Do a full breadth-first scan of the rcu_node structures for the
+ * specified rcu_state structure.
+ */
+#define rcu_for_each_node_breadth_first(rsp, rnp) \
+ for ((rnp) = &(rsp)->node[0]; \
+ (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++)
+
+#define rcu_for_each_leaf_node(rsp, rnp) \
+ for ((rnp) = (rsp)->level[NUM_RCU_LVLS - 1]; \
+ (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++)
+
/* Index values for nxttail array in struct rcu_data. */
#define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */
#define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */
@@ -126,19 +147,22 @@ struct rcu_data {
* Any of the partitions might be empty, in which case the
* pointer to that partition will be equal to the pointer for
* the following partition. When the list is empty, all of
- * the nxttail elements point to nxtlist, which is NULL.
+ * the nxttail elements point to the ->nxtlist pointer itself,
+ * which in that case is NULL.
*
- * [*nxttail[RCU_NEXT_READY_TAIL], NULL = *nxttail[RCU_NEXT_TAIL]):
- * Entries that might have arrived after current GP ended
- * [*nxttail[RCU_WAIT_TAIL], *nxttail[RCU_NEXT_READY_TAIL]):
- * Entries known to have arrived before current GP ended
- * [*nxttail[RCU_DONE_TAIL], *nxttail[RCU_WAIT_TAIL]):
- * Entries that batch # <= ->completed - 1: waiting for current GP
* [nxtlist, *nxttail[RCU_DONE_TAIL]):
* Entries that batch # <= ->completed
* The grace period for these entries has completed, and
* the other grace-period-completed entries may be moved
* here temporarily in rcu_process_callbacks().
+ * [*nxttail[RCU_DONE_TAIL], *nxttail[RCU_WAIT_TAIL]):
+ * Entries that batch # <= ->completed - 1: waiting for current GP
+ * [*nxttail[RCU_WAIT_TAIL], *nxttail[RCU_NEXT_READY_TAIL]):
+ * Entries known to have arrived before current GP ended
+ * [*nxttail[RCU_NEXT_READY_TAIL], *nxttail[RCU_NEXT_TAIL]):
+ * Entries that might have arrived after current GP ended
+ * Note that the value of *nxttail[RCU_NEXT_TAIL] will
+ * always be NULL, as this is the end of the list.
*/
struct rcu_head *nxtlist;
struct rcu_head **nxttail[RCU_NEXT_SIZE];
@@ -216,8 +240,19 @@ struct rcu_state {
/* Force QS state. */
long gpnum; /* Current gp number. */
long completed; /* # of last completed gp. */
+
+ /* End of fields guarded by root rcu_node's lock. */
+
spinlock_t onofflock; /* exclude on/offline and */
- /* starting new GP. */
+ /* starting new GP. Also */
+ /* protects the following */
+ /* orphan_cbs fields. */
+ struct rcu_head *orphan_cbs_list; /* list of rcu_head structs */
+ /* orphaned by all CPUs in */
+ /* a given leaf rcu_node */
+ /* going offline. */
+ struct rcu_head **orphan_cbs_tail; /* And tail pointer. */
+ long orphan_qlen; /* Number of orphaned cbs. */
spinlock_t fqslock; /* Only one task forcing */
/* quiescent states. */
unsigned long jiffies_force_qs; /* Time at which to invoke */
@@ -255,5 +290,30 @@ extern struct rcu_state rcu_preempt_state;
DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
-#endif /* #ifdef RCU_TREE_NONCORE */
+#else /* #ifdef RCU_TREE_NONCORE */
+
+/* Forward declarations for rcutree_plugin.h */
+static inline void rcu_bootup_announce(void);
+long rcu_batches_completed(void);
+static void rcu_preempt_note_context_switch(int cpu);
+static int rcu_preempted_readers(struct rcu_node *rnp);
+#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
+static void rcu_print_task_stall(struct rcu_node *rnp);
+#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
+static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
+#ifdef CONFIG_HOTPLUG_CPU
+static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
+ struct rcu_node *rnp,
+ struct rcu_data *rdp);
+static void rcu_preempt_offline_cpu(int cpu);
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+static void rcu_preempt_check_callbacks(int cpu);
+static void rcu_preempt_process_callbacks(void);
+void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
+static int rcu_preempt_pending(int cpu);
+static int rcu_preempt_needs_cpu(int cpu);
+static void __cpuinit rcu_preempt_init_percpu_data(int cpu);
+static void rcu_preempt_send_cbs_to_orphanage(void);
+static void __init __rcu_init_preempt(void);
+#endif /* #else #ifdef RCU_TREE_NONCORE */
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index 1cee04f627e..c0cb783aa16 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -150,6 +150,16 @@ void __rcu_read_lock(void)
}
EXPORT_SYMBOL_GPL(__rcu_read_lock);
+/*
+ * Check for preempted RCU readers blocking the current grace period
+ * for the specified rcu_node structure. If the caller needs a reliable
+ * answer, it must hold the rcu_node's ->lock.
+ */
+static int rcu_preempted_readers(struct rcu_node *rnp)
+{
+ return !list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]);
+}
+
static void rcu_read_unlock_special(struct task_struct *t)
{
int empty;
@@ -196,7 +206,7 @@ static void rcu_read_unlock_special(struct task_struct *t)
break;
spin_unlock(&rnp->lock); /* irqs remain disabled. */
}
- empty = list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]);
+ empty = !rcu_preempted_readers(rnp);
list_del_init(&t->rcu_node_entry);
t->rcu_blocked_node = NULL;
@@ -207,7 +217,7 @@ static void rcu_read_unlock_special(struct task_struct *t)
* drop rnp->lock and restore irq.
*/
if (!empty && rnp->qsmask == 0 &&
- list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1])) {
+ !rcu_preempted_readers(rnp)) {
struct rcu_node *rnp_p;
if (rnp->parent == NULL) {
@@ -257,12 +267,12 @@ static void rcu_print_task_stall(struct rcu_node *rnp)
{
unsigned long flags;
struct list_head *lp;
- int phase = rnp->gpnum & 0x1;
+ int phase;
struct task_struct *t;
- if (!list_empty(&rnp->blocked_tasks[phase])) {
+ if (rcu_preempted_readers(rnp)) {
spin_lock_irqsave(&rnp->lock, flags);
- phase = rnp->gpnum & 0x1; /* re-read under lock. */
+ phase = rnp->gpnum & 0x1;
lp = &rnp->blocked_tasks[phase];
list_for_each_entry(t, lp, rcu_node_entry)
printk(" P%d", t->pid);
@@ -281,20 +291,10 @@ static void rcu_print_task_stall(struct rcu_node *rnp)
*/
static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
{
- WARN_ON_ONCE(!list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]));
+ WARN_ON_ONCE(rcu_preempted_readers(rnp));
WARN_ON_ONCE(rnp->qsmask);
}
-/*
- * Check for preempted RCU readers for the specified rcu_node structure.
- * If the caller needs a reliable answer, it must hold the rcu_node's
- * >lock.
- */
-static int rcu_preempted_readers(struct rcu_node *rnp)
-{
- return !list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]);
-}
-
#ifdef CONFIG_HOTPLUG_CPU
/*
@@ -410,6 +410,15 @@ static int rcu_preempt_needs_cpu(int cpu)
return !!per_cpu(rcu_preempt_data, cpu).nxtlist;
}
+/**
+ * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete.
+ */
+void rcu_barrier(void)
+{
+ _rcu_barrier(&rcu_preempt_state, call_rcu);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier);
+
/*
* Initialize preemptable RCU's per-CPU data.
*/
@@ -419,6 +428,22 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu)
}
/*
+ * Move preemptable RCU's callbacks to ->orphan_cbs_list.
+ */
+static void rcu_preempt_send_cbs_to_orphanage(void)
+{
+ rcu_send_cbs_to_orphanage(&rcu_preempt_state);
+}
+
+/*
+ * Initialize preemptable RCU's state structures.
+ */
+static void __init __rcu_init_preempt(void)
+{
+ RCU_INIT_FLAVOR(&rcu_preempt_state, rcu_preempt_data);
+}
+
+/*
* Check for a task exiting while in a preemptable-RCU read-side
* critical section, clean up if so. No need to issue warnings,
* as debug_check_no_locks_held() already does this if lockdep
@@ -461,6 +486,15 @@ static void rcu_preempt_note_context_switch(int cpu)
{
}
+/*
+ * Because preemptable RCU does not exist, there are never any preempted
+ * RCU readers.
+ */
+static int rcu_preempted_readers(struct rcu_node *rnp)
+{
+ return 0;
+}
+
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
/*
@@ -483,15 +517,6 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
WARN_ON_ONCE(rnp->qsmask);
}
-/*
- * Because preemptable RCU does not exist, there are never any preempted
- * RCU readers.
- */
-static int rcu_preempted_readers(struct rcu_node *rnp)
-{
- return 0;
-}
-
#ifdef CONFIG_HOTPLUG_CPU
/*
@@ -518,7 +543,7 @@ static void rcu_preempt_offline_cpu(int cpu)
* Because preemptable RCU does not exist, it never has any callbacks
* to check.
*/
-void rcu_preempt_check_callbacks(int cpu)
+static void rcu_preempt_check_callbacks(int cpu)
{
}
@@ -526,7 +551,7 @@ void rcu_preempt_check_callbacks(int cpu)
* Because preemptable RCU does not exist, it never has any callbacks
* to process.
*/
-void rcu_preempt_process_callbacks(void)
+static void rcu_preempt_process_callbacks(void)
{
}
@@ -556,6 +581,16 @@ static int rcu_preempt_needs_cpu(int cpu)
}
/*
+ * Because preemptable RCU does not exist, rcu_barrier() is just
+ * another name for rcu_barrier_sched().
+ */
+void rcu_barrier(void)
+{
+ rcu_barrier_sched();
+}
+EXPORT_SYMBOL_GPL(rcu_barrier);
+
+/*
* Because preemptable RCU does not exist, there is no per-CPU
* data to initialize.
*/
@@ -563,4 +598,18 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu)
{
}
+/*
+ * Because there is no preemptable RCU, there are no callbacks to move.
+ */
+static void rcu_preempt_send_cbs_to_orphanage(void)
+{
+}
+
+/*
+ * Because preemptable RCU does not exist, it need not be initialized.
+ */
+static void __init __rcu_init_preempt(void)
+{
+}
+
#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index c89f5e9fd17..4b31c779e62 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -93,7 +93,7 @@ static int rcudata_open(struct inode *inode, struct file *file)
return single_open(file, show_rcudata, NULL);
}
-static struct file_operations rcudata_fops = {
+static const struct file_operations rcudata_fops = {
.owner = THIS_MODULE,
.open = rcudata_open,
.read = seq_read,
@@ -145,7 +145,7 @@ static int rcudata_csv_open(struct inode *inode, struct file *file)
return single_open(file, show_rcudata_csv, NULL);
}
-static struct file_operations rcudata_csv_fops = {
+static const struct file_operations rcudata_csv_fops = {
.owner = THIS_MODULE,
.open = rcudata_csv_open,
.read = seq_read,
@@ -159,13 +159,13 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
struct rcu_node *rnp;
seq_printf(m, "c=%ld g=%ld s=%d jfq=%ld j=%x "
- "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu\n",
+ "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld\n",
rsp->completed, rsp->gpnum, rsp->signaled,
(long)(rsp->jiffies_force_qs - jiffies),
(int)(jiffies & 0xffff),
rsp->n_force_qs, rsp->n_force_qs_ngp,
rsp->n_force_qs - rsp->n_force_qs_ngp,
- rsp->n_force_qs_lh);
+ rsp->n_force_qs_lh, rsp->orphan_qlen);
for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < NUM_RCU_NODES; rnp++) {
if (rnp->level != level) {
seq_puts(m, "\n");
@@ -196,7 +196,7 @@ static int rcuhier_open(struct inode *inode, struct file *file)
return single_open(file, show_rcuhier, NULL);
}
-static struct file_operations rcuhier_fops = {
+static const struct file_operations rcuhier_fops = {
.owner = THIS_MODULE,
.open = rcuhier_open,
.read = seq_read,
@@ -222,7 +222,7 @@ static int rcugp_open(struct inode *inode, struct file *file)
return single_open(file, show_rcugp, NULL);
}
-static struct file_operations rcugp_fops = {
+static const struct file_operations rcugp_fops = {
.owner = THIS_MODULE,
.open = rcugp_open,
.read = seq_read,
@@ -276,7 +276,7 @@ static int rcu_pending_open(struct inode *inode, struct file *file)
return single_open(file, show_rcu_pending, NULL);
}
-static struct file_operations rcu_pending_fops = {
+static const struct file_operations rcu_pending_fops = {
.owner = THIS_MODULE,
.open = rcu_pending_open,
.read = seq_read,
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index 88faec23e83..bcdabf37c40 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -37,27 +37,17 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
}
int res_counter_charge(struct res_counter *counter, unsigned long val,
- struct res_counter **limit_fail_at,
- struct res_counter **soft_limit_fail_at)
+ struct res_counter **limit_fail_at)
{
int ret;
unsigned long flags;
struct res_counter *c, *u;
*limit_fail_at = NULL;
- if (soft_limit_fail_at)
- *soft_limit_fail_at = NULL;
local_irq_save(flags);
for (c = counter; c != NULL; c = c->parent) {
spin_lock(&c->lock);
ret = res_counter_charge_locked(c, val);
- /*
- * With soft limits, we return the highest ancestor
- * that exceeds its soft limit
- */
- if (soft_limit_fail_at &&
- !res_counter_soft_limit_check_locked(c))
- *soft_limit_fail_at = c;
spin_unlock(&c->lock);
if (ret < 0) {
*limit_fail_at = c;
@@ -85,8 +75,7 @@ void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val)
counter->usage -= val;
}
-void res_counter_uncharge(struct res_counter *counter, unsigned long val,
- bool *was_soft_limit_excess)
+void res_counter_uncharge(struct res_counter *counter, unsigned long val)
{
unsigned long flags;
struct res_counter *c;
@@ -94,9 +83,6 @@ void res_counter_uncharge(struct res_counter *counter, unsigned long val,
local_irq_save(flags);
for (c = counter; c != NULL; c = c->parent) {
spin_lock(&c->lock);
- if (was_soft_limit_excess)
- *was_soft_limit_excess =
- !res_counter_soft_limit_check_locked(c);
res_counter_uncharge_locked(c, val);
spin_unlock(&c->lock);
}
diff --git a/kernel/sched.c b/kernel/sched.c
index ee61f454a98..76c0e9691fc 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -780,7 +780,7 @@ static int sched_feat_open(struct inode *inode, struct file *filp)
return single_open(filp, sched_feat_show, NULL);
}
-static struct file_operations sched_feat_fops = {
+static const struct file_operations sched_feat_fops = {
.open = sched_feat_open,
.write = sched_feat_write,
.read = seq_read,
@@ -2515,22 +2515,17 @@ void sched_fork(struct task_struct *p, int clone_flags)
__sched_fork(p);
/*
- * Make sure we do not leak PI boosting priority to the child.
- */
- p->prio = current->normal_prio;
-
- /*
* Revert to default priority/policy on fork if requested.
*/
if (unlikely(p->sched_reset_on_fork)) {
- if (p->policy == SCHED_FIFO || p->policy == SCHED_RR)
+ if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) {
p->policy = SCHED_NORMAL;
-
- if (p->normal_prio < DEFAULT_PRIO)
- p->prio = DEFAULT_PRIO;
+ p->normal_prio = p->static_prio;
+ }
if (PRIO_TO_NICE(p->static_prio) < 0) {
p->static_prio = NICE_TO_PRIO(0);
+ p->normal_prio = p->static_prio;
set_load_weight(p);
}
@@ -2541,6 +2536,11 @@ void sched_fork(struct task_struct *p, int clone_flags)
p->sched_reset_on_fork = 0;
}
+ /*
+ * Make sure we do not leak PI boosting priority to the child.
+ */
+ p->prio = current->normal_prio;
+
if (!rt_prio(p->prio))
p->sched_class = &fair_sched_class;
@@ -2581,8 +2581,6 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
BUG_ON(p->state != TASK_RUNNING);
update_rq_clock(rq);
- p->prio = effective_prio(p);
-
if (!p->sched_class->task_new || !current->se.on_rq) {
activate_task(rq, p, 0);
} else {
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
index ac2e1dc708b..479ce5682d7 100644
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -127,7 +127,7 @@ again:
clock = wrap_max(clock, min_clock);
clock = wrap_min(clock, max_clock);
- if (cmpxchg(&scd->clock, old_clock, clock) != old_clock)
+ if (cmpxchg64(&scd->clock, old_clock, clock) != old_clock)
goto again;
return clock;
@@ -163,7 +163,7 @@ again:
val = remote_clock;
}
- if (cmpxchg(ptr, old_val, val) != old_val)
+ if (cmpxchg64(ptr, old_val, val) != old_val)
goto again;
return val;
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index e0f59a21c06..89aed5933ed 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -231,6 +231,13 @@ void tick_nohz_stop_sched_tick(int inidle)
if (!inidle && !ts->inidle)
goto end;
+ /*
+ * Set ts->inidle unconditionally. Even if the system did not
+ * switch to NOHZ mode the cpu frequency governers rely on the
+ * update of the idle time accounting in tick_nohz_start_idle().
+ */
+ ts->inidle = 1;
+
now = tick_nohz_start_idle(ts);
/*
@@ -248,8 +255,6 @@ void tick_nohz_stop_sched_tick(int inidle)
if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
goto end;
- ts->inidle = 1;
-
if (need_resched())
goto end;
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index fddd69d16e0..1b5b7aa2fdf 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -275,7 +275,7 @@ static int timer_list_open(struct inode *inode, struct file *filp)
return single_open(filp, timer_list_show, NULL);
}
-static struct file_operations timer_list_fops = {
+static const struct file_operations timer_list_fops = {
.open = timer_list_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
index 4cde8b9c716..ee5681f8d7e 100644
--- a/kernel/time/timer_stats.c
+++ b/kernel/time/timer_stats.c
@@ -395,7 +395,7 @@ static int tstats_open(struct inode *inode, struct file *filp)
return single_open(filp, tstats_show, NULL);
}
-static struct file_operations tstats_fops = {
+static const struct file_operations tstats_fops = {
.open = tstats_open,
.read = seq_read,
.write = tstats_write,
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 3eb159c277c..d9d6206e0b1 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -856,6 +856,37 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
}
/**
+ * blk_add_trace_rq_remap - Add a trace for a request-remap operation
+ * @q: queue the io is for
+ * @rq: the source request
+ * @dev: target device
+ * @from: source sector
+ *
+ * Description:
+ * Device mapper remaps request to other devices.
+ * Add a trace for that action.
+ *
+ **/
+static void blk_add_trace_rq_remap(struct request_queue *q,
+ struct request *rq, dev_t dev,
+ sector_t from)
+{
+ struct blk_trace *bt = q->blk_trace;
+ struct blk_io_trace_remap r;
+
+ if (likely(!bt))
+ return;
+
+ r.device_from = cpu_to_be32(dev);
+ r.device_to = cpu_to_be32(disk_devt(rq->rq_disk));
+ r.sector_from = cpu_to_be64(from);
+
+ __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
+ rq_data_dir(rq), BLK_TA_REMAP, !!rq->errors,
+ sizeof(r), &r);
+}
+
+/**
* blk_add_driver_data - Add binary message with driver-specific data
* @q: queue the io is for
* @rq: io request
@@ -922,10 +953,13 @@ static void blk_register_tracepoints(void)
WARN_ON(ret);
ret = register_trace_block_remap(blk_add_trace_remap);
WARN_ON(ret);
+ ret = register_trace_block_rq_remap(blk_add_trace_rq_remap);
+ WARN_ON(ret);
}
static void blk_unregister_tracepoints(void)
{
+ unregister_trace_block_rq_remap(blk_add_trace_rq_remap);
unregister_trace_block_remap(blk_add_trace_remap);
unregister_trace_block_split(blk_add_trace_split);
unregister_trace_block_unplug_io(blk_add_trace_unplug_io);
@@ -1657,6 +1691,11 @@ int blk_trace_init_sysfs(struct device *dev)
return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
}
+void blk_trace_remove_sysfs(struct device *dev)
+{
+ sysfs_remove_group(&dev->kobj, &blk_trace_attr_group);
+}
+
#endif /* CONFIG_BLK_DEV_IO_TRACE */
#ifdef CONFIG_EVENT_TRACING
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 46592feab5a..37ba67e3326 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -225,7 +225,11 @@ static void ftrace_update_pid_func(void)
if (ftrace_trace_function == ftrace_stub)
return;
+#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
func = ftrace_trace_function;
+#else
+ func = __ftrace_trace_function;
+#endif
if (ftrace_pid_trace) {
set_ftrace_pid_function(func);
@@ -1074,14 +1078,9 @@ static void ftrace_replace_code(int enable)
failed = __ftrace_replace_code(rec, enable);
if (failed) {
rec->flags |= FTRACE_FL_FAILED;
- if ((system_state == SYSTEM_BOOTING) ||
- !core_kernel_text(rec->ip)) {
- ftrace_free_rec(rec);
- } else {
- ftrace_bug(failed, rec->ip);
- /* Stop processing */
- return;
- }
+ ftrace_bug(failed, rec->ip);
+ /* Stop processing */
+ return;
}
} while_for_each_ftrace_rec();
}
@@ -2658,19 +2657,17 @@ static int ftrace_convert_nops(struct module *mod,
}
#ifdef CONFIG_MODULES
-void ftrace_release(void *start, void *end)
+void ftrace_release_mod(struct module *mod)
{
struct dyn_ftrace *rec;
struct ftrace_page *pg;
- unsigned long s = (unsigned long)start;
- unsigned long e = (unsigned long)end;
- if (ftrace_disabled || !start || start == end)
+ if (ftrace_disabled)
return;
mutex_lock(&ftrace_lock);
do_for_each_ftrace_rec(pg, rec) {
- if ((rec->ip >= s) && (rec->ip < e)) {
+ if (within_module_core(rec->ip, mod)) {
/*
* rec->ip is changed in ftrace_free_rec()
* It should not between s and e if record was freed.
@@ -2702,9 +2699,7 @@ static int ftrace_module_notify(struct notifier_block *self,
mod->num_ftrace_callsites);
break;
case MODULE_STATE_GOING:
- ftrace_release(mod->ftrace_callsites,
- mod->ftrace_callsites +
- mod->num_ftrace_callsites);
+ ftrace_release_mod(mod);
break;
}
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
index 81b1645c854..a91da69f153 100644
--- a/kernel/trace/kmemtrace.c
+++ b/kernel/trace/kmemtrace.c
@@ -501,7 +501,7 @@ static int __init init_kmem_tracer(void)
return 1;
}
- if (!register_tracer(&kmem_tracer)) {
+ if (register_tracer(&kmem_tracer) != 0) {
pr_warning("Warning: could not register the kmem tracer\n");
return 1;
}
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 7a7a9fd249a..4a194f08f88 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -34,6 +34,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
struct trace_array *tr = branch_tracer;
struct ring_buffer_event *event;
struct trace_branch *entry;
+ struct ring_buffer *buffer;
unsigned long flags;
int cpu, pc;
const char *p;
@@ -54,7 +55,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
goto out;
pc = preempt_count();
- event = trace_buffer_lock_reserve(tr, TRACE_BRANCH,
+ buffer = tr->buffer;
+ event = trace_buffer_lock_reserve(buffer, TRACE_BRANCH,
sizeof(*entry), flags, pc);
if (!event)
goto out;
@@ -74,8 +76,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
entry->line = f->line;
entry->correct = val == expect;
- if (!filter_check_discard(call, entry, tr->buffer, event))
- ring_buffer_unlock_commit(tr->buffer, event);
+ if (!filter_check_discard(call, entry, buffer, event))
+ ring_buffer_unlock_commit(buffer, event);
out:
atomic_dec(&tr->data[cpu]->disabled);
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c
index dd44b876886..8d5c171cc99 100644
--- a/kernel/trace/trace_event_profile.c
+++ b/kernel/trace/trace_event_profile.c
@@ -31,7 +31,7 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event)
if (atomic_inc_return(&event->profile_count))
return 0;
- if (!total_profile_count++) {
+ if (!total_profile_count) {
buf = (char *)alloc_percpu(profile_buf_t);
if (!buf)
goto fail_buf;
@@ -46,14 +46,19 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event)
}
ret = event->profile_enable();
- if (!ret)
+ if (!ret) {
+ total_profile_count++;
return 0;
+ }
- kfree(trace_profile_buf_nmi);
fail_buf_nmi:
- kfree(trace_profile_buf);
+ if (!total_profile_count) {
+ free_percpu(trace_profile_buf_nmi);
+ free_percpu(trace_profile_buf);
+ trace_profile_buf_nmi = NULL;
+ trace_profile_buf = NULL;
+ }
fail_buf:
- total_profile_count--;
atomic_dec(&event->profile_count);
return ret;
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
index 23b63859130..69543a905cd 100644
--- a/kernel/trace/trace_hw_branches.c
+++ b/kernel/trace/trace_hw_branches.c
@@ -165,6 +165,7 @@ void trace_hw_branch(u64 from, u64 to)
struct ftrace_event_call *call = &event_hw_branch;
struct trace_array *tr = hw_branch_trace;
struct ring_buffer_event *event;
+ struct ring_buffer *buf;
struct hw_branch_entry *entry;
unsigned long irq1;
int cpu;
@@ -180,7 +181,8 @@ void trace_hw_branch(u64 from, u64 to)
if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
goto out;
- event = trace_buffer_lock_reserve(tr, TRACE_HW_BRANCHES,
+ buf = tr->buffer;
+ event = trace_buffer_lock_reserve(buf, TRACE_HW_BRANCHES,
sizeof(*entry), 0, 0);
if (!event)
goto out;
@@ -189,8 +191,8 @@ void trace_hw_branch(u64 from, u64 to)
entry->ent.type = TRACE_HW_BRANCHES;
entry->from = from;
entry->to = to;
- if (!filter_check_discard(call, entry, tr->buffer, event))
- trace_buffer_unlock_commit(tr, event, 0, 0);
+ if (!filter_check_discard(call, entry, buf, event))
+ trace_buffer_unlock_commit(buf, event, 0, 0);
out:
atomic_dec(&tr->data[cpu]->disabled);
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index f572f44c6e1..ed17565826b 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -486,16 +486,18 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
hardirq ? 'h' : softirq ? 's' : '.'))
return 0;
- if (entry->lock_depth < 0)
- ret = trace_seq_putc(s, '.');
+ if (entry->preempt_count)
+ ret = trace_seq_printf(s, "%x", entry->preempt_count);
else
- ret = trace_seq_printf(s, "%d", entry->lock_depth);
+ ret = trace_seq_putc(s, '.');
+
if (!ret)
return 0;
- if (entry->preempt_count)
- return trace_seq_printf(s, "%x", entry->preempt_count);
- return trace_seq_putc(s, '.');
+ if (entry->lock_depth < 0)
+ return trace_seq_putc(s, '.');
+
+ return trace_seq_printf(s, "%d", entry->lock_depth);
}
static int
@@ -883,7 +885,7 @@ static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
trace_assign_type(field, iter->ent);
if (!S)
- task_state_char(field->prev_state);
+ S = task_state_char(field->prev_state);
T = task_state_char(field->next_state);
if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
field->prev_pid,
@@ -918,7 +920,7 @@ static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
trace_assign_type(field, iter->ent);
if (!S)
- task_state_char(field->prev_state);
+ S = task_state_char(field->prev_state);
T = task_state_char(field->next_state);
SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 9fbce6c9d2e..527e17eae57 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -166,7 +166,7 @@ int syscall_exit_format(struct ftrace_event_call *call, struct trace_seq *s)
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n",
SYSCALL_FIELD(int, nr),
- SYSCALL_FIELD(unsigned long, ret));
+ SYSCALL_FIELD(long, ret));
if (!ret)
return 0;
@@ -212,7 +212,7 @@ int syscall_exit_define_fields(struct ftrace_event_call *call)
if (ret)
return ret;
- ret = trace_define_field(call, SYSCALL_FIELD(unsigned long, ret), 0,
+ ret = trace_define_field(call, SYSCALL_FIELD(long, ret), 0,
FILTER_OTHER);
return ret;
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index b91839e9e89..33bed5e67a2 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1771,7 +1771,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
* advance both strings to next white space
*/
if (*fmt == '*') {
- while (!isspace(*fmt) && *fmt)
+ while (!isspace(*fmt) && *fmt != '%' && *fmt)
fmt++;
while (!isspace(*str) && *str)
str++;
diff --git a/mm/Kconfig b/mm/Kconfig
index edd300aca17..57963c6063d 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -224,7 +224,9 @@ config KSM
the many instances by a single resident page with that content, so
saving memory until one or another app needs to modify the content.
Recommended for use with KVM, or with other duplicative applications.
- See Documentation/vm/ksm.txt for more information.
+ See Documentation/vm/ksm.txt for more information: KSM is inactive
+ until a program has madvised that an area is MADV_MERGEABLE, and
+ root has set /sys/kernel/mm/ksm/run to 1 (if CONFIG_SYSFS is set).
config DEFAULT_MMAP_MIN_ADDR
int "Low address space to protect from user allocation"
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 4ea4510e299..8bf765c4f58 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -833,12 +833,15 @@ static void early_alloc(struct early_log *log)
*/
rcu_read_lock();
object = create_object((unsigned long)log->ptr, log->size,
- log->min_count, GFP_KERNEL);
+ log->min_count, GFP_ATOMIC);
+ if (!object)
+ goto out;
spin_lock_irqsave(&object->lock, flags);
for (i = 0; i < log->trace_len; i++)
object->trace[i] = log->trace[i];
object->trace_len = log->trace_len;
spin_unlock_irqrestore(&object->lock, flags);
+out:
rcu_read_unlock();
}
diff --git a/mm/ksm.c b/mm/ksm.c
index f7edac356f4..bef1af4f77e 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -184,11 +184,6 @@ static DEFINE_SPINLOCK(ksm_mmlist_lock);
sizeof(struct __struct), __alignof__(struct __struct),\
(__flags), NULL)
-static void __init ksm_init_max_kernel_pages(void)
-{
- ksm_max_kernel_pages = nr_free_buffer_pages() / 4;
-}
-
static int __init ksm_slab_init(void)
{
rmap_item_cache = KSM_KMEM_CACHE(rmap_item, 0);
@@ -1673,7 +1668,7 @@ static int __init ksm_init(void)
struct task_struct *ksm_thread;
int err;
- ksm_init_max_kernel_pages();
+ ksm_max_kernel_pages = totalram_pages / 4;
err = ksm_slab_init();
if (err)
@@ -1697,6 +1692,9 @@ static int __init ksm_init(void)
kthread_stop(ksm_thread);
goto out_free2;
}
+#else
+ ksm_run = KSM_RUN_MERGE; /* no way for user to start it */
+
#endif /* CONFIG_SYSFS */
return 0;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index e2b98a6875c..f99f5991d6b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -313,7 +313,8 @@ soft_limit_tree_from_page(struct page *page)
static void
__mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
struct mem_cgroup_per_zone *mz,
- struct mem_cgroup_tree_per_zone *mctz)
+ struct mem_cgroup_tree_per_zone *mctz,
+ unsigned long long new_usage_in_excess)
{
struct rb_node **p = &mctz->rb_root.rb_node;
struct rb_node *parent = NULL;
@@ -322,7 +323,9 @@ __mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
if (mz->on_tree)
return;
- mz->usage_in_excess = res_counter_soft_limit_excess(&mem->res);
+ mz->usage_in_excess = new_usage_in_excess;
+ if (!mz->usage_in_excess)
+ return;
while (*p) {
parent = *p;
mz_node = rb_entry(parent, struct mem_cgroup_per_zone,
@@ -353,16 +356,6 @@ __mem_cgroup_remove_exceeded(struct mem_cgroup *mem,
}
static void
-mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
- struct mem_cgroup_per_zone *mz,
- struct mem_cgroup_tree_per_zone *mctz)
-{
- spin_lock(&mctz->lock);
- __mem_cgroup_insert_exceeded(mem, mz, mctz);
- spin_unlock(&mctz->lock);
-}
-
-static void
mem_cgroup_remove_exceeded(struct mem_cgroup *mem,
struct mem_cgroup_per_zone *mz,
struct mem_cgroup_tree_per_zone *mctz)
@@ -392,34 +385,36 @@ static bool mem_cgroup_soft_limit_check(struct mem_cgroup *mem)
static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page)
{
- unsigned long long prev_usage_in_excess, new_usage_in_excess;
- bool updated_tree = false;
+ unsigned long long excess;
struct mem_cgroup_per_zone *mz;
struct mem_cgroup_tree_per_zone *mctz;
-
- mz = mem_cgroup_zoneinfo(mem, page_to_nid(page), page_zonenum(page));
+ int nid = page_to_nid(page);
+ int zid = page_zonenum(page);
mctz = soft_limit_tree_from_page(page);
/*
- * We do updates in lazy mode, mem's are removed
- * lazily from the per-zone, per-node rb tree
+ * Necessary to update all ancestors when hierarchy is used.
+ * because their event counter is not touched.
*/
- prev_usage_in_excess = mz->usage_in_excess;
-
- new_usage_in_excess = res_counter_soft_limit_excess(&mem->res);
- if (prev_usage_in_excess) {
- mem_cgroup_remove_exceeded(mem, mz, mctz);
- updated_tree = true;
- }
- if (!new_usage_in_excess)
- goto done;
- mem_cgroup_insert_exceeded(mem, mz, mctz);
-
-done:
- if (updated_tree) {
- spin_lock(&mctz->lock);
- mz->usage_in_excess = new_usage_in_excess;
- spin_unlock(&mctz->lock);
+ for (; mem; mem = parent_mem_cgroup(mem)) {
+ mz = mem_cgroup_zoneinfo(mem, nid, zid);
+ excess = res_counter_soft_limit_excess(&mem->res);
+ /*
+ * We have to update the tree if mz is on RB-tree or
+ * mem is over its softlimit.
+ */
+ if (excess || mz->on_tree) {
+ spin_lock(&mctz->lock);
+ /* if on-tree, remove it */
+ if (mz->on_tree)
+ __mem_cgroup_remove_exceeded(mem, mz, mctz);
+ /*
+ * Insert again. mz->usage_in_excess will be updated.
+ * If excess is 0, no tree ops.
+ */
+ __mem_cgroup_insert_exceeded(mem, mz, mctz, excess);
+ spin_unlock(&mctz->lock);
+ }
}
}
@@ -447,9 +442,10 @@ static struct mem_cgroup_per_zone *
__mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz)
{
struct rb_node *rightmost = NULL;
- struct mem_cgroup_per_zone *mz = NULL;
+ struct mem_cgroup_per_zone *mz;
retry:
+ mz = NULL;
rightmost = rb_last(&mctz->rb_root);
if (!rightmost)
goto done; /* Nothing to reclaim from */
@@ -1270,9 +1266,9 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
gfp_t gfp_mask, struct mem_cgroup **memcg,
bool oom, struct page *page)
{
- struct mem_cgroup *mem, *mem_over_limit, *mem_over_soft_limit;
+ struct mem_cgroup *mem, *mem_over_limit;
int nr_retries = MEM_CGROUP_RECLAIM_RETRIES;
- struct res_counter *fail_res, *soft_fail_res = NULL;
+ struct res_counter *fail_res;
if (unlikely(test_thread_flag(TIF_MEMDIE))) {
/* Don't account this! */
@@ -1304,17 +1300,16 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
if (mem_cgroup_is_root(mem))
goto done;
- ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res,
- &soft_fail_res);
+ ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res);
if (likely(!ret)) {
if (!do_swap_account)
break;
ret = res_counter_charge(&mem->memsw, PAGE_SIZE,
- &fail_res, NULL);
+ &fail_res);
if (likely(!ret))
break;
/* mem+swap counter fails */
- res_counter_uncharge(&mem->res, PAGE_SIZE, NULL);
+ res_counter_uncharge(&mem->res, PAGE_SIZE);
flags |= MEM_CGROUP_RECLAIM_NOSWAP;
mem_over_limit = mem_cgroup_from_res_counter(fail_res,
memsw);
@@ -1353,16 +1348,11 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
}
}
/*
- * Insert just the ancestor, we should trickle down to the correct
- * cgroup for reclaim, since the other nodes will be below their
- * soft limit
+ * Insert ancestor (and ancestor's ancestors), to softlimit RB-tree.
+ * if they exceeds softlimit.
*/
- if (soft_fail_res) {
- mem_over_soft_limit =
- mem_cgroup_from_res_counter(soft_fail_res, res);
- if (mem_cgroup_soft_limit_check(mem_over_soft_limit))
- mem_cgroup_update_tree(mem_over_soft_limit, page);
- }
+ if (mem_cgroup_soft_limit_check(mem))
+ mem_cgroup_update_tree(mem, page);
done:
return 0;
nomem:
@@ -1437,10 +1427,9 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *mem,
if (unlikely(PageCgroupUsed(pc))) {
unlock_page_cgroup(pc);
if (!mem_cgroup_is_root(mem)) {
- res_counter_uncharge(&mem->res, PAGE_SIZE, NULL);
+ res_counter_uncharge(&mem->res, PAGE_SIZE);
if (do_swap_account)
- res_counter_uncharge(&mem->memsw, PAGE_SIZE,
- NULL);
+ res_counter_uncharge(&mem->memsw, PAGE_SIZE);
}
css_put(&mem->css);
return;
@@ -1519,7 +1508,7 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
goto out;
if (!mem_cgroup_is_root(from))
- res_counter_uncharge(&from->res, PAGE_SIZE, NULL);
+ res_counter_uncharge(&from->res, PAGE_SIZE);
mem_cgroup_charge_statistics(from, pc, false);
page = pc->page;
@@ -1539,7 +1528,7 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
}
if (do_swap_account && !mem_cgroup_is_root(from))
- res_counter_uncharge(&from->memsw, PAGE_SIZE, NULL);
+ res_counter_uncharge(&from->memsw, PAGE_SIZE);
css_put(&from->css);
css_get(&to->css);
@@ -1610,9 +1599,9 @@ uncharge:
css_put(&parent->css);
/* uncharge if move fails */
if (!mem_cgroup_is_root(parent)) {
- res_counter_uncharge(&parent->res, PAGE_SIZE, NULL);
+ res_counter_uncharge(&parent->res, PAGE_SIZE);
if (do_swap_account)
- res_counter_uncharge(&parent->memsw, PAGE_SIZE, NULL);
+ res_counter_uncharge(&parent->memsw, PAGE_SIZE);
}
return ret;
}
@@ -1803,8 +1792,7 @@ __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr,
* calling css_tryget
*/
if (!mem_cgroup_is_root(memcg))
- res_counter_uncharge(&memcg->memsw, PAGE_SIZE,
- NULL);
+ res_counter_uncharge(&memcg->memsw, PAGE_SIZE);
mem_cgroup_swap_statistics(memcg, false);
mem_cgroup_put(memcg);
}
@@ -1831,9 +1819,9 @@ void mem_cgroup_cancel_charge_swapin(struct mem_cgroup *mem)
if (!mem)
return;
if (!mem_cgroup_is_root(mem)) {
- res_counter_uncharge(&mem->res, PAGE_SIZE, NULL);
+ res_counter_uncharge(&mem->res, PAGE_SIZE);
if (do_swap_account)
- res_counter_uncharge(&mem->memsw, PAGE_SIZE, NULL);
+ res_counter_uncharge(&mem->memsw, PAGE_SIZE);
}
css_put(&mem->css);
}
@@ -1848,7 +1836,6 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
struct page_cgroup *pc;
struct mem_cgroup *mem = NULL;
struct mem_cgroup_per_zone *mz;
- bool soft_limit_excess = false;
if (mem_cgroup_disabled())
return NULL;
@@ -1888,10 +1875,10 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
}
if (!mem_cgroup_is_root(mem)) {
- res_counter_uncharge(&mem->res, PAGE_SIZE, &soft_limit_excess);
+ res_counter_uncharge(&mem->res, PAGE_SIZE);
if (do_swap_account &&
(ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT))
- res_counter_uncharge(&mem->memsw, PAGE_SIZE, NULL);
+ res_counter_uncharge(&mem->memsw, PAGE_SIZE);
}
if (ctype == MEM_CGROUP_CHARGE_TYPE_SWAPOUT)
mem_cgroup_swap_statistics(mem, true);
@@ -1908,7 +1895,7 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
mz = page_cgroup_zoneinfo(pc);
unlock_page_cgroup(pc);
- if (soft_limit_excess && mem_cgroup_soft_limit_check(mem))
+ if (mem_cgroup_soft_limit_check(mem))
mem_cgroup_update_tree(mem, page);
/* at swapout, this memcg will be accessed to record to swap */
if (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT)
@@ -1986,7 +1973,7 @@ void mem_cgroup_uncharge_swap(swp_entry_t ent)
* This memcg can be obsolete one. We avoid calling css_tryget
*/
if (!mem_cgroup_is_root(memcg))
- res_counter_uncharge(&memcg->memsw, PAGE_SIZE, NULL);
+ res_counter_uncharge(&memcg->memsw, PAGE_SIZE);
mem_cgroup_swap_statistics(memcg, false);
mem_cgroup_put(memcg);
}
@@ -2233,6 +2220,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
unsigned long reclaimed;
int loop = 0;
struct mem_cgroup_tree_per_zone *mctz;
+ unsigned long long excess;
if (order > 0)
return 0;
@@ -2284,9 +2272,8 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
break;
} while (1);
}
- mz->usage_in_excess =
- res_counter_soft_limit_excess(&mz->mem->res);
__mem_cgroup_remove_exceeded(mz->mem, mz, mctz);
+ excess = res_counter_soft_limit_excess(&mz->mem->res);
/*
* One school of thought says that we should not add
* back the node to the tree if reclaim returns 0.
@@ -2295,8 +2282,8 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
* memory to reclaim from. Consider this as a longer
* term TODO.
*/
- if (mz->usage_in_excess)
- __mem_cgroup_insert_exceeded(mz->mem, mz, mctz);
+ /* If excess == 0, no tree ops */
+ __mem_cgroup_insert_exceeded(mz->mem, mz, mctz, excess);
spin_unlock(&mctz->lock);
css_put(&mz->mem->css);
loop++;
diff --git a/mm/rmap.c b/mm/rmap.c
index 28aafe2b530..dd43373a483 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -242,8 +242,8 @@ vma_address(struct page *page, struct vm_area_struct *vma)
}
/*
- * At what user virtual address is page expected in vma? checking that the
- * page matches the vma: currently only used on anon pages, by unuse_vma;
+ * At what user virtual address is page expected in vma?
+ * checking that the page matches the vma.
*/
unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
{
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 4de7f02f820..a1bc6b9af9a 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1974,12 +1974,14 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
goto bad_swap;
}
- if (blk_queue_nonrot(bdev_get_queue(p->bdev))) {
- p->flags |= SWP_SOLIDSTATE;
- p->cluster_next = 1 + (random32() % p->highest_bit);
+ if (p->bdev) {
+ if (blk_queue_nonrot(bdev_get_queue(p->bdev))) {
+ p->flags |= SWP_SOLIDSTATE;
+ p->cluster_next = 1 + (random32() % p->highest_bit);
+ }
+ if (discard_swap(p) == 0)
+ p->flags |= SWP_DISCARDABLE;
}
- if (discard_swap(p) == 0)
- p->flags |= SWP_DISCARDABLE;
mutex_lock(&swapon_mutex);
spin_lock(&swap_lock);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 69511e66323..5e7aed0802b 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -25,10 +25,10 @@
#include <linux/rcupdate.h>
#include <linux/pfn.h>
#include <linux/kmemleak.h>
-#include <linux/highmem.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include <asm/tlbflush.h>
+#include <asm/shmparam.h>
/*** Page table manipulation functions ***/
@@ -1156,12 +1156,11 @@ static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
}
static struct vm_struct *__get_vm_area_node(unsigned long size,
- unsigned long flags, unsigned long start, unsigned long end,
- int node, gfp_t gfp_mask, void *caller)
+ unsigned long align, unsigned long flags, unsigned long start,
+ unsigned long end, int node, gfp_t gfp_mask, void *caller)
{
static struct vmap_area *va;
struct vm_struct *area;
- unsigned long align = 1;
BUG_ON(in_interrupt());
if (flags & VM_IOREMAP) {
@@ -1201,7 +1200,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end)
{
- return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL,
+ return __get_vm_area_node(size, 1, flags, start, end, -1, GFP_KERNEL,
__builtin_return_address(0));
}
EXPORT_SYMBOL_GPL(__get_vm_area);
@@ -1210,7 +1209,7 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end,
void *caller)
{
- return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL,
+ return __get_vm_area_node(size, 1, flags, start, end, -1, GFP_KERNEL,
caller);
}
@@ -1225,22 +1224,22 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags,
*/
struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
{
- return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END,
+ return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
-1, GFP_KERNEL, __builtin_return_address(0));
}
struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags,
void *caller)
{
- return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END,
+ return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
-1, GFP_KERNEL, caller);
}
struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags,
int node, gfp_t gfp_mask)
{
- return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node,
- gfp_mask, __builtin_return_address(0));
+ return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
+ node, gfp_mask, __builtin_return_address(0));
}
static struct vm_struct *find_vm_area(const void *addr)
@@ -1403,7 +1402,8 @@ void *vmap(struct page **pages, unsigned int count,
}
EXPORT_SYMBOL(vmap);
-static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
+static void *__vmalloc_node(unsigned long size, unsigned long align,
+ gfp_t gfp_mask, pgprot_t prot,
int node, void *caller);
static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
pgprot_t prot, int node, void *caller)
@@ -1417,7 +1417,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
area->nr_pages = nr_pages;
/* Please note that the recursion is strictly bounded. */
if (array_size > PAGE_SIZE) {
- pages = __vmalloc_node(array_size, gfp_mask | __GFP_ZERO,
+ pages = __vmalloc_node(array_size, 1, gfp_mask | __GFP_ZERO,
PAGE_KERNEL, node, caller);
area->flags |= VM_VPAGES;
} else {
@@ -1476,6 +1476,7 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
/**
* __vmalloc_node - allocate virtually contiguous memory
* @size: allocation size
+ * @align: desired alignment
* @gfp_mask: flags for the page level allocator
* @prot: protection mask for the allocated pages
* @node: node to use for allocation or -1
@@ -1485,8 +1486,9 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
* allocator with @gfp_mask flags. Map them into contiguous
* kernel virtual space, using a pagetable protection of @prot.
*/
-static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
- int node, void *caller)
+static void *__vmalloc_node(unsigned long size, unsigned long align,
+ gfp_t gfp_mask, pgprot_t prot,
+ int node, void *caller)
{
struct vm_struct *area;
void *addr;
@@ -1496,8 +1498,8 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
if (!size || (size >> PAGE_SHIFT) > totalram_pages)
return NULL;
- area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
- node, gfp_mask, caller);
+ area = __get_vm_area_node(size, align, VM_ALLOC, VMALLOC_START,
+ VMALLOC_END, node, gfp_mask, caller);
if (!area)
return NULL;
@@ -1516,7 +1518,7 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
{
- return __vmalloc_node(size, gfp_mask, prot, -1,
+ return __vmalloc_node(size, 1, gfp_mask, prot, -1,
__builtin_return_address(0));
}
EXPORT_SYMBOL(__vmalloc);
@@ -1532,7 +1534,7 @@ EXPORT_SYMBOL(__vmalloc);
*/
void *vmalloc(unsigned long size)
{
- return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
+ return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
-1, __builtin_return_address(0));
}
EXPORT_SYMBOL(vmalloc);
@@ -1549,7 +1551,8 @@ void *vmalloc_user(unsigned long size)
struct vm_struct *area;
void *ret;
- ret = __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
+ ret = __vmalloc_node(size, SHMLBA,
+ GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
PAGE_KERNEL, -1, __builtin_return_address(0));
if (ret) {
area = find_vm_area(ret);
@@ -1572,7 +1575,7 @@ EXPORT_SYMBOL(vmalloc_user);
*/
void *vmalloc_node(unsigned long size, int node)
{
- return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
+ return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
node, __builtin_return_address(0));
}
EXPORT_SYMBOL(vmalloc_node);
@@ -1595,7 +1598,7 @@ EXPORT_SYMBOL(vmalloc_node);
void *vmalloc_exec(unsigned long size)
{
- return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
+ return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
-1, __builtin_return_address(0));
}
@@ -1616,7 +1619,7 @@ void *vmalloc_exec(unsigned long size)
*/
void *vmalloc_32(unsigned long size)
{
- return __vmalloc_node(size, GFP_VMALLOC32, PAGE_KERNEL,
+ return __vmalloc_node(size, 1, GFP_VMALLOC32, PAGE_KERNEL,
-1, __builtin_return_address(0));
}
EXPORT_SYMBOL(vmalloc_32);
@@ -1633,7 +1636,7 @@ void *vmalloc_32_user(unsigned long size)
struct vm_struct *area;
void *ret;
- ret = __vmalloc_node(size, GFP_VMALLOC32 | __GFP_ZERO, PAGE_KERNEL,
+ ret = __vmalloc_node(size, 1, GFP_VMALLOC32 | __GFP_ZERO, PAGE_KERNEL,
-1, __builtin_return_address(0));
if (ret) {
area = find_vm_area(ret);
diff --git a/net/atm/common.c b/net/atm/common.c
index 8c4d843eb17..950bd16d238 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -679,7 +679,7 @@ static int check_qos(const struct atm_qos *qos)
}
int vcc_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct atm_vcc *vcc;
unsigned long value;
diff --git a/net/atm/common.h b/net/atm/common.h
index 92e2981f479..f48a76b6cdf 100644
--- a/net/atm/common.h
+++ b/net/atm/common.h
@@ -21,7 +21,7 @@ unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
int vcc_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen);
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index e1d22d9430d..d4c024504f9 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -59,7 +59,7 @@ static int pvc_connect(struct socket *sock,struct sockaddr *sockaddr,
}
static int pvc_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int error;
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 7b831b526d0..f90d143c4b2 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -446,7 +446,7 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
static int svc_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct atm_vcc *vcc = ATM_SD(sock);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 4102de1022e..f4546073037 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -534,7 +534,7 @@ ax25_cb *ax25_create_cb(void)
*/
static int ax25_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
ax25_cb *ax25;
@@ -901,7 +901,6 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
sock_init_data(NULL, sk);
- sk->sk_destruct = ax25_free_sock;
sk->sk_type = osk->sk_type;
sk->sk_priority = osk->sk_priority;
sk->sk_protocol = osk->sk_protocol;
@@ -939,6 +938,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
}
sk->sk_protinfo = ax25;
+ sk->sk_destruct = ax25_free_sock;
ax25->sk = sk;
return sk;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 4f9621f759a..75302a98606 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -466,7 +466,7 @@ drop:
goto done;
}
-static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
+static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
{
struct hci_ufilter uf = { .opcode = 0 };
struct sock *sk = sock->sk;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index b0301256464..555d9da1869 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1698,7 +1698,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
return bt_sock_recvmsg(iocb, sock, msg, len, flags);
}
-static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen)
+static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct l2cap_options opts;
@@ -1755,7 +1755,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
return err;
}
-static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct bt_security sec;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 0b85e811685..8a20aaf1f23 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -730,7 +730,7 @@ out:
return copied ? : err;
}
-static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen)
+static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int err = 0;
@@ -766,7 +766,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
return err;
}
-static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct bt_security sec;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 13c27f17192..77f4153bdb5 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -644,7 +644,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return err;
}
-static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int err = 0;
diff --git a/net/can/raw.c b/net/can/raw.c
index db3152df7d2..b5e897922d3 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -411,7 +411,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
}
static int raw_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct raw_sock *ro = raw_sk(sk);
diff --git a/net/compat.c b/net/compat.c
index 12728b17a22..a407c3addba 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -331,7 +331,7 @@ struct compat_sock_fprog {
};
static int do_set_attach_filter(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
@@ -351,7 +351,7 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname,
}
static int do_set_sock_timeout(struct socket *sock, int level,
- int optname, char __user *optval, int optlen)
+ int optname, char __user *optval, unsigned int optlen)
{
struct compat_timeval __user *up = (struct compat_timeval __user *) optval;
struct timeval ktime;
@@ -373,7 +373,7 @@ static int do_set_sock_timeout(struct socket *sock, int level,
}
static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (optname == SO_ATTACH_FILTER)
return do_set_attach_filter(sock, level, optname,
@@ -385,7 +385,7 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
}
asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
int err;
struct socket *sock;
@@ -558,8 +558,8 @@ struct compat_group_filter {
int compat_mc_setsockopt(struct sock *sock, int level, int optname,
- char __user *optval, int optlen,
- int (*setsockopt)(struct sock *,int,int,char __user *,int))
+ char __user *optval, unsigned int optlen,
+ int (*setsockopt)(struct sock *,int,int,char __user *,unsigned int))
{
char __user *koptval = optval;
int koptlen = optlen;
diff --git a/net/core/dev.c b/net/core/dev.c
index 560c8c9c03a..b8f74cfb1bf 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2288,6 +2288,9 @@ int netif_receive_skb(struct sk_buff *skb)
int ret = NET_RX_DROP;
__be16 type;
+ if (!skb->tstamp.tv64)
+ net_timestamp(skb);
+
if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
return NET_RX_SUCCESS;
@@ -2295,9 +2298,6 @@ int netif_receive_skb(struct sk_buff *skb)
if (netpoll_receive_skb(skb))
return NET_RX_DROP;
- if (!skb->tstamp.tv64)
- net_timestamp(skb);
-
if (!skb->iif)
skb->iif = skb->dev->ifindex;
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 821d30918cf..427ded84122 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -366,13 +366,13 @@ static ssize_t wireless_show(struct device *d, char *buf,
const struct iw_statistics *iw;
ssize_t ret = -EINVAL;
- read_lock(&dev_base_lock);
+ rtnl_lock();
if (dev_isalive(dev)) {
iw = get_wireless_stats(dev);
if (iw)
ret = (*format)(iw, buf);
}
- read_unlock(&dev_base_lock);
+ rtnl_unlock();
return ret;
}
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 4d11c28ca8c..86acdba0a97 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -964,7 +964,7 @@ static ssize_t pktgen_if_write(struct file *file,
if (value == 0x7FFFFFFF)
pkt_dev->delay = ULLONG_MAX;
else
- pkt_dev->delay = (u64)value * NSEC_PER_USEC;
+ pkt_dev->delay = (u64)value;
sprintf(pg_result, "OK: delay=%llu",
(unsigned long long) pkt_dev->delay);
@@ -2105,15 +2105,17 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
{
ktime_t start_time, end_time;
- s32 remaining;
+ s64 remaining;
struct hrtimer_sleeper t;
hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
hrtimer_set_expires(&t.timer, spin_until);
remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer));
- if (remaining <= 0)
+ if (remaining <= 0) {
+ pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay);
return;
+ }
start_time = ktime_now();
if (remaining < 100)
@@ -2210,7 +2212,7 @@ static void set_cur_queue_map(struct pktgen_dev *pkt_dev)
if (pkt_dev->flags & F_QUEUE_MAP_CPU)
pkt_dev->cur_queue_map = smp_processor_id();
- else if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) {
+ else if (pkt_dev->queue_map_min <= pkt_dev->queue_map_max) {
__u16 t;
if (pkt_dev->flags & F_QUEUE_MAP_RND) {
t = random32() %
diff --git a/net/core/sock.c b/net/core/sock.c
index 524712a7b15..7626b6aacd6 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -446,7 +446,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
*/
int sock_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int val;
@@ -1228,17 +1228,22 @@ void __init sk_init(void)
void sock_wfree(struct sk_buff *skb)
{
struct sock *sk = skb->sk;
- int res;
+ unsigned int len = skb->truesize;
- /* In case it might be waiting for more memory. */
- res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc);
- if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE))
+ if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) {
+ /*
+ * Keep a reference on sk_wmem_alloc, this will be released
+ * after sk_write_space() call
+ */
+ atomic_sub(len - 1, &sk->sk_wmem_alloc);
sk->sk_write_space(sk);
+ len = 1;
+ }
/*
- * if sk_wmem_alloc reached 0, we are last user and should
- * free this sock, as sk_free() call could not do it.
+ * if sk_wmem_alloc reaches 0, we must finish what sk_free()
+ * could not do because of in-flight packets
*/
- if (res == 0)
+ if (atomic_sub_and_test(len, &sk->sk_wmem_alloc))
__sk_free(sk);
}
EXPORT_SYMBOL(sock_wfree);
@@ -1697,7 +1702,7 @@ int sock_no_shutdown(struct socket *sock, int how)
EXPORT_SYMBOL(sock_no_shutdown);
int sock_no_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
return -EOPNOTSUPP;
}
@@ -2018,7 +2023,7 @@ EXPORT_SYMBOL(sock_common_recvmsg);
* Set socket options on an inet socket.
*/
int sock_common_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
@@ -2028,7 +2033,7 @@ EXPORT_SYMBOL(sock_common_setsockopt);
#ifdef CONFIG_COMPAT
int compat_sock_common_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index d6bc47363b1..5ef32c2f0d6 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -290,14 +290,14 @@ extern int dccp_disconnect(struct sock *sk, int flags);
extern int dccp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
extern int dccp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
#ifdef CONFIG_COMPAT
extern int compat_dccp_getsockopt(struct sock *sk,
int level, int optname,
char __user *optval, int __user *optlen);
extern int compat_dccp_setsockopt(struct sock *sk,
int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
#endif
extern int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern int dccp_sendmsg(struct kiocb *iocb, struct sock *sk,
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index bc4467082a0..a156319fd0a 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -393,7 +393,7 @@ out:
EXPORT_SYMBOL_GPL(dccp_ioctl);
static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct dccp_sock *dp = dccp_sk(sk);
struct dccp_service_list *sl = NULL;
@@ -464,7 +464,7 @@ static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx)
}
static int dccp_setsockopt_ccid(struct sock *sk, int type,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
u8 *val;
int rc = 0;
@@ -494,7 +494,7 @@ static int dccp_setsockopt_ccid(struct sock *sk, int type,
}
static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct dccp_sock *dp = dccp_sk(sk);
int val, err = 0;
@@ -546,7 +546,7 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
}
int dccp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level != SOL_DCCP)
return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
@@ -559,7 +559,7 @@ EXPORT_SYMBOL_GPL(dccp_setsockopt);
#ifdef CONFIG_COMPAT
int compat_dccp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level != SOL_DCCP)
return inet_csk_compat_setsockopt(sk, level, optname,
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 77d40289653..7a58c87baf1 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -157,7 +157,7 @@ static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
static struct hlist_head dn_wild_sk;
static atomic_t decnet_memory_allocated;
-static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen, int flags);
+static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags);
static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
static struct hlist_head *dn_find_list(struct sock *sk)
@@ -1325,7 +1325,7 @@ out:
return err;
}
-static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int err;
@@ -1337,7 +1337,7 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
return err;
}
-static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, int optlen, int flags)
+static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, unsigned int optlen, int flags)
{
struct sock *sk = sock->sk;
struct dn_scp *scp = DN_SK(sk);
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
index 51593a48f2d..a413b1bf446 100644
--- a/net/ieee802154/dgram.c
+++ b/net/ieee802154/dgram.c
@@ -414,7 +414,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
}
static int dgram_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct dgram_sock *ro = dgram_sk(sk);
int val;
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c
index 13198859982..30e74eee07d 100644
--- a/net/ieee802154/raw.c
+++ b/net/ieee802154/raw.c
@@ -244,7 +244,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname,
}
static int raw_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
return -EOPNOTSUPP;
}
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 58c4b0f7c4a..57737b8d171 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1119,6 +1119,7 @@ int inet_sk_rebuild_header(struct sock *sk)
{
struct flowi fl = {
.oif = sk->sk_bound_dev_if,
+ .mark = sk->sk_mark,
.nl_u = {
.ip4_u = {
.daddr = daddr,
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index e92f1fd28aa..5df2f6a0b0f 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1077,12 +1077,16 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
ip_mc_up(in_dev);
/* fall through */
case NETDEV_CHANGEADDR:
- if (IN_DEV_ARP_NOTIFY(in_dev))
- arp_send(ARPOP_REQUEST, ETH_P_ARP,
- in_dev->ifa_list->ifa_address,
- dev,
- in_dev->ifa_list->ifa_address,
- NULL, dev->dev_addr, NULL);
+ /* Send gratuitous ARP to notify of link change */
+ if (IN_DEV_ARP_NOTIFY(in_dev)) {
+ struct in_ifaddr *ifa = in_dev->ifa_list;
+
+ if (ifa)
+ arp_send(ARPOP_REQUEST, ETH_P_ARP,
+ ifa->ifa_address, dev,
+ ifa->ifa_address, NULL,
+ dev->dev_addr, NULL);
+ }
break;
case NETDEV_DOWN:
ip_mc_down(in_dev);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 22cd19ee44e..4351ca2cf0b 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -714,7 +714,7 @@ int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt);
int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 9fe5d7b8158..f9895180f48 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -335,6 +335,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
{
struct flowi fl = { .oif = sk->sk_bound_dev_if,
+ .mark = sk->sk_mark,
.nl_u = { .ip4_u =
{ .daddr = daddr,
.saddr = inet->saddr,
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5a0693576e8..0c0b6e363a2 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -440,7 +440,7 @@ out:
*/
static int do_ip_setsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int optlen)
+ int optname, char __user *optval, unsigned int optlen)
{
struct inet_sock *inet = inet_sk(sk);
int val = 0, err;
@@ -950,7 +950,7 @@ e_inval:
}
int ip_setsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int optlen)
+ int optname, char __user *optval, unsigned int optlen)
{
int err;
@@ -975,7 +975,7 @@ EXPORT_SYMBOL(ip_setsockopt);
#ifdef CONFIG_COMPAT
int compat_ip_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
int err;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index c43ec2d51ce..630a56df7b4 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -931,7 +931,7 @@ static void mrtsock_destruct(struct sock *sk)
* MOSPF/PIM router set up we can clean this up.
*/
-int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen)
+int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
{
int ret;
struct vifctl vif;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index ebb1e5848bc..757c9171e7c 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -741,7 +741,7 @@ out: return ret;
}
static int do_raw_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (optname == ICMP_FILTER) {
if (inet_sk(sk)->num != IPPROTO_ICMP)
@@ -753,7 +753,7 @@ static int do_raw_setsockopt(struct sock *sk, int level, int optname,
}
static int raw_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level != SOL_RAW)
return ip_setsockopt(sk, level, optname, optval, optlen);
@@ -762,7 +762,7 @@ static int raw_setsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_COMPAT
static int compat_raw_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level != SOL_RAW)
return compat_ip_setsockopt(sk, level, optname, optval, optlen);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 21387ebabf0..64d0af67582 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -580,7 +580,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
lock_sock(sk);
- timeo = sock_rcvtimeo(sk, flags & SPLICE_F_NONBLOCK);
+ timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK);
while (tss.len) {
ret = __tcp_splice_read(sk, &tss);
if (ret < 0)
@@ -2032,7 +2032,7 @@ int tcp_disconnect(struct sock *sk, int flags)
* Socket option code for TCP.
*/
static int do_tcp_setsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int optlen)
+ int optname, char __user *optval, unsigned int optlen)
{
struct tcp_sock *tp = tcp_sk(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2047,7 +2047,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
return -EINVAL;
val = strncpy_from_user(name, optval,
- min(TCP_CA_NAME_MAX-1, optlen));
+ min_t(long, TCP_CA_NAME_MAX-1, optlen));
if (val < 0)
return -EFAULT;
name[val] = 0;
@@ -2220,7 +2220,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
}
int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
- int optlen)
+ unsigned int optlen)
{
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2232,7 +2232,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
#ifdef CONFIG_COMPAT
int compat_tcp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level != SOL_TCP)
return inet_csk_compat_setsockopt(sk, level, optname,
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 5200aab0ca9..fcd278a7080 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -361,6 +361,7 @@ static inline int tcp_urg_mode(const struct tcp_sock *tp)
#define OPTION_SACK_ADVERTISE (1 << 0)
#define OPTION_TS (1 << 1)
#define OPTION_MD5 (1 << 2)
+#define OPTION_WSCALE (1 << 3)
struct tcp_out_options {
u8 options; /* bit field of OPTION_* */
@@ -427,7 +428,7 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
TCPOLEN_SACK_PERM);
}
- if (unlikely(opts->ws)) {
+ if (unlikely(OPTION_WSCALE & opts->options)) {
*ptr++ = htonl((TCPOPT_NOP << 24) |
(TCPOPT_WINDOW << 16) |
(TCPOLEN_WINDOW << 8) |
@@ -494,8 +495,8 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
}
if (likely(sysctl_tcp_window_scaling)) {
opts->ws = tp->rx_opt.rcv_wscale;
- if (likely(opts->ws))
- size += TCPOLEN_WSCALE_ALIGNED;
+ opts->options |= OPTION_WSCALE;
+ size += TCPOLEN_WSCALE_ALIGNED;
}
if (likely(sysctl_tcp_sack)) {
opts->options |= OPTION_SACK_ADVERTISE;
@@ -537,8 +538,8 @@ static unsigned tcp_synack_options(struct sock *sk,
if (likely(ireq->wscale_ok)) {
opts->ws = ireq->rcv_wscale;
- if (likely(opts->ws))
- size += TCPOLEN_WSCALE_ALIGNED;
+ opts->options |= OPTION_WSCALE;
+ size += TCPOLEN_WSCALE_ALIGNED;
}
if (likely(doing_ts)) {
opts->options |= OPTION_TS;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ebaaa7f973d..6ec6a8a4a22 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -696,6 +696,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (rt == NULL) {
struct flowi fl = { .oif = ipc.oif,
+ .mark = sk->sk_mark,
.nl_u = { .ip4_u =
{ .daddr = faddr,
.saddr = saddr,
@@ -1359,7 +1360,7 @@ void udp_destroy_sock(struct sock *sk)
* Socket option code for UDP
*/
int udp_lib_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen,
+ char __user *optval, unsigned int optlen,
int (*push_pending_frames)(struct sock *))
{
struct udp_sock *up = udp_sk(sk);
@@ -1441,7 +1442,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
EXPORT_SYMBOL(udp_lib_setsockopt);
int udp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level == SOL_UDP || level == SOL_UDPLITE)
return udp_lib_setsockopt(sk, level, optname, optval, optlen,
@@ -1451,7 +1452,7 @@ int udp_setsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_COMPAT
int compat_udp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level == SOL_UDP || level == SOL_UDPLITE)
return udp_lib_setsockopt(sk, level, optname, optval, optlen,
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
index 9f4a6165f72..aaad650d47d 100644
--- a/net/ipv4/udp_impl.h
+++ b/net/ipv4/udp_impl.h
@@ -11,13 +11,13 @@ extern void __udp4_lib_err(struct sk_buff *, u32, struct udp_table *);
extern int udp_v4_get_port(struct sock *sk, unsigned short snum);
extern int udp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
extern int udp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
#ifdef CONFIG_COMPAT
extern int compat_udp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
extern int compat_udp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
#endif
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 090675e269e..716153941fc 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1281,7 +1281,7 @@ int ip6mr_sk_done(struct sock *sk)
* MOSPF/PIM router set up we can clean this up.
*/
-int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen)
+int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
{
int ret;
struct mif6ctl vif;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index f5e0682b402..14f54eb5a7f 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -123,7 +123,7 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
}
static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct net *net = sock_net(sk);
@@ -773,7 +773,7 @@ e_inval:
}
int ipv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
int err;
@@ -801,7 +801,7 @@ EXPORT_SYMBOL(ipv6_setsockopt);
#ifdef CONFIG_COMPAT
int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
int err;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 7d675b8d82d..4f24570b086 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -957,7 +957,7 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname,
static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct raw6_sock *rp = raw6_sk(sk);
int val;
@@ -1000,7 +1000,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
}
static int rawv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
switch(level) {
case SOL_RAW:
@@ -1024,7 +1024,7 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_COMPAT
static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
switch (level) {
case SOL_RAW:
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index d65e0c496cc..dbd19a78ca7 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -274,7 +274,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
c = 0;
for (prl = t->prl; prl; prl = prl->next) {
- if (c > cmax)
+ if (c >= cmax)
break;
if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr)
continue;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b265b7047d3..3a60f12b34e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1044,7 +1044,7 @@ void udpv6_destroy_sock(struct sock *sk)
* Socket option code for UDP
*/
int udpv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level == SOL_UDP || level == SOL_UDPLITE)
return udp_lib_setsockopt(sk, level, optname, optval, optlen,
@@ -1054,7 +1054,7 @@ int udpv6_setsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_COMPAT
int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
if (level == SOL_UDP || level == SOL_UDPLITE)
return udp_lib_setsockopt(sk, level, optname, optval, optlen,
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 6bb303471e2..d7571046bfc 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -16,10 +16,10 @@ extern int udp_v6_get_port(struct sock *sk, unsigned short snum);
extern int udpv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
extern int udpv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
#ifdef CONFIG_COMPAT
extern int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen);
+ char __user *optval, unsigned int optlen);
extern int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
#endif
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index f1118d92a19..66c7a20011f 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1292,7 +1292,7 @@ const char *ipx_device_name(struct ipx_interface *intrfc)
* socket object. */
static int ipx_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int opt;
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 50b43c57d5d..dd35641835f 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1826,7 +1826,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
*
*/
static int irda_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct irda_sock *self = irda_sk(sk);
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index d985d163dcf..bada1b9c670 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1387,7 +1387,7 @@ static int iucv_sock_release(struct socket *sock)
/* getsockopt and setsockopt */
static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct iucv_sock *iucv = iucv_sk(sk);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index c45eee1c0e8..7aa4fd17010 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -973,7 +973,7 @@ static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
* Set various connection specific parameters.
*/
static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct llc_sock *llc = llc_sk(sk);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5143d203256..fd402829661 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -367,7 +367,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
u32 staflags;
- if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control)))
+ if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control)
+ || ieee80211_is_auth(hdr->frame_control)
+ || ieee80211_is_assoc_resp(hdr->frame_control)
+ || ieee80211_is_reassoc_resp(hdr->frame_control)))
return TX_CONTINUE;
staflags = get_sta_flags(sta);
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index 8ab829f8657..f042ae52155 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -113,7 +113,7 @@ static int nf_sockopt(struct sock *sk, u_int8_t pf, int val,
}
int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
- int len)
+ unsigned int len)
{
return nf_sockopt(sk, pf, val, opt, &len, 0);
}
@@ -154,7 +154,7 @@ static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val,
}
int compat_nf_setsockopt(struct sock *sk, u_int8_t pf,
- int val, char __user *opt, int len)
+ int val, char __user *opt, unsigned int len)
{
return compat_nf_sockopt(sk, pf, val, opt, &len, 0);
}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index dd85320907c..19e98007691 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1150,7 +1150,7 @@ static void netlink_update_socket_mc(struct netlink_sock *nlk,
}
static int netlink_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct netlink_sock *nlk = nlk_sk(sk);
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index ce1a34b99c2..7a834952f67 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -301,7 +301,7 @@ void nr_destroy_socket(struct sock *sk)
*/
static int nr_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct nr_sock *nr = nr_sk(sk);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 103d5611b81..d7ecca0a0c0 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1701,7 +1701,7 @@ static void packet_flush_mclist(struct sock *sk)
}
static int
-packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct packet_sock *po = pkt_sk(sk);
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index b8252d289cd..5f32d217535 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -742,7 +742,7 @@ static int pep_init(struct sock *sk)
}
static int pep_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct pep_sock *pn = pep_sk(sk);
int val = 0, err = 0;
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 07aa9f08d5f..aa5b5a972bf 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -407,7 +407,6 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)
return -EADDRINUSE;
found:
- mutex_unlock(&port_mutex);
pn->sobject = pn_object(pn_addr(pn->sobject), sport);
return 0;
}
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 6b58aeff4c7..98e05382fd3 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -248,7 +248,7 @@ static int rds_cong_monitor(struct rds_sock *rs, char __user *optval,
}
static int rds_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct rds_sock *rs = rds_sk_to_rs(sock->sk);
int ret;
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index dbeaf298382..ba2efb960c6 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -27,6 +27,7 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/rfkill.h>
+#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/miscdevice.h>
#include <linux/wait.h>
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 1e166c9685a..502cce76621 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -370,7 +370,7 @@ void rose_destroy_socket(struct sock *sk)
*/
static int rose_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct rose_sock *rose = rose_sk(sk);
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index bfe493ebf27..a86afceaa94 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -507,7 +507,7 @@ out:
* set RxRPC socket options
*/
static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
unsigned min_sec_level;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 89af37a6c87..c8d05758661 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2027,7 +2027,8 @@ out:
* instead a error will be indicated to the user.
*/
static int sctp_setsockopt_disable_fragments(struct sock *sk,
- char __user *optval, int optlen)
+ char __user *optval,
+ unsigned int optlen)
{
int val;
@@ -2043,7 +2044,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk,
}
static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
- int optlen)
+ unsigned int optlen)
{
if (optlen > sizeof(struct sctp_event_subscribe))
return -EINVAL;
@@ -2064,7 +2065,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
* association is closed.
*/
static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
- int optlen)
+ unsigned int optlen)
{
struct sctp_sock *sp = sctp_sk(sk);
@@ -2318,7 +2319,8 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
}
static int sctp_setsockopt_peer_addr_params(struct sock *sk,
- char __user *optval, int optlen)
+ char __user *optval,
+ unsigned int optlen)
{
struct sctp_paddrparams params;
struct sctp_transport *trans = NULL;
@@ -2430,7 +2432,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
*/
static int sctp_setsockopt_delayed_ack(struct sock *sk,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
struct sctp_sack_info params;
struct sctp_transport *trans = NULL;
@@ -2546,7 +2548,7 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
* by the change). With TCP-style sockets, this option is inherited by
* sockets derived from a listener socket.
*/
-static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int optlen)
+static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, unsigned int optlen)
{
struct sctp_initmsg sinit;
struct sctp_sock *sp = sctp_sk(sk);
@@ -2583,7 +2585,8 @@ static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int opt
* to this call if the caller is using the UDP model.
*/
static int sctp_setsockopt_default_send_param(struct sock *sk,
- char __user *optval, int optlen)
+ char __user *optval,
+ unsigned int optlen)
{
struct sctp_sndrcvinfo info;
struct sctp_association *asoc;
@@ -2622,7 +2625,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
* association peer's addresses.
*/
static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
- int optlen)
+ unsigned int optlen)
{
struct sctp_prim prim;
struct sctp_transport *trans;
@@ -2651,7 +2654,7 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
* integer boolean flag.
*/
static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval,
- int optlen)
+ unsigned int optlen)
{
int val;
@@ -2676,7 +2679,8 @@ static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval,
* be changed.
*
*/
-static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int optlen) {
+static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigned int optlen)
+{
struct sctp_rtoinfo rtoinfo;
struct sctp_association *asoc;
@@ -2728,7 +2732,7 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int opt
* See [SCTP] for more information.
*
*/
-static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int optlen)
+static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsigned int optlen)
{
struct sctp_assocparams assocparams;
@@ -2800,7 +2804,7 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int o
* addresses and a user will receive both PF_INET6 and PF_INET type
* addresses on the socket.
*/
-static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int optlen)
+static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsigned int optlen)
{
int val;
struct sctp_sock *sp = sctp_sk(sk);
@@ -2844,7 +2848,7 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int op
* changed (effecting future associations only).
* assoc_value: This parameter specifies the maximum size in bytes.
*/
-static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen)
+static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen)
{
struct sctp_assoc_value params;
struct sctp_association *asoc;
@@ -2899,7 +2903,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl
* set primary request:
*/
static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval,
- int optlen)
+ unsigned int optlen)
{
struct sctp_sock *sp;
struct sctp_endpoint *ep;
@@ -2950,7 +2954,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
}
static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval,
- int optlen)
+ unsigned int optlen)
{
struct sctp_setadaptation adaptation;
@@ -2979,7 +2983,7 @@ static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval
* saved with outbound messages.
*/
static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
- int optlen)
+ unsigned int optlen)
{
struct sctp_assoc_value params;
struct sctp_sock *sp;
@@ -3030,7 +3034,7 @@ static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
*/
static int sctp_setsockopt_fragment_interleave(struct sock *sk,
char __user *optval,
- int optlen)
+ unsigned int optlen)
{
int val;
@@ -3063,7 +3067,7 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk,
*/
static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
char __user *optval,
- int optlen)
+ unsigned int optlen)
{
u32 val;
@@ -3096,7 +3100,7 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
*/
static int sctp_setsockopt_maxburst(struct sock *sk,
char __user *optval,
- int optlen)
+ unsigned int optlen)
{
struct sctp_assoc_value params;
struct sctp_sock *sp;
@@ -3140,8 +3144,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
* will only effect future associations on the socket.
*/
static int sctp_setsockopt_auth_chunk(struct sock *sk,
- char __user *optval,
- int optlen)
+ char __user *optval,
+ unsigned int optlen)
{
struct sctp_authchunk val;
@@ -3172,8 +3176,8 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
* endpoint requires the peer to use.
*/
static int sctp_setsockopt_hmac_ident(struct sock *sk,
- char __user *optval,
- int optlen)
+ char __user *optval,
+ unsigned int optlen)
{
struct sctp_hmacalgo *hmacs;
u32 idents;
@@ -3215,7 +3219,7 @@ out:
*/
static int sctp_setsockopt_auth_key(struct sock *sk,
char __user *optval,
- int optlen)
+ unsigned int optlen)
{
struct sctp_authkey *authkey;
struct sctp_association *asoc;
@@ -3260,8 +3264,8 @@ out:
* the association shared key.
*/
static int sctp_setsockopt_active_key(struct sock *sk,
- char __user *optval,
- int optlen)
+ char __user *optval,
+ unsigned int optlen)
{
struct sctp_authkeyid val;
struct sctp_association *asoc;
@@ -3288,8 +3292,8 @@ static int sctp_setsockopt_active_key(struct sock *sk,
* This set option will delete a shared secret key from use.
*/
static int sctp_setsockopt_del_key(struct sock *sk,
- char __user *optval,
- int optlen)
+ char __user *optval,
+ unsigned int optlen)
{
struct sctp_authkeyid val;
struct sctp_association *asoc;
@@ -3332,7 +3336,7 @@ static int sctp_setsockopt_del_key(struct sock *sk,
* optlen - the size of the buffer.
*/
SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
int retval = 0;
diff --git a/net/socket.c b/net/socket.c
index 41e8847508a..75655365b5f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2391,7 +2391,7 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
}
int kernel_setsockopt(struct socket *sock, int level, int optname,
- char *optval, int optlen)
+ char *optval, unsigned int optlen)
{
mm_segment_t oldfs = get_fs();
int err;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e8254e809b7..e6d9abf7440 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1658,7 +1658,7 @@ restart:
*/
static int setsockopt(struct socket *sock,
- int lvl, int opt, char __user *ov, int ol)
+ int lvl, int opt, char __user *ov, unsigned int ol)
{
struct sock *sk = sock->sk;
struct tipc_port *tport = tipc_sk_port(sk);
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 5e6c072c64d..7fa9c7ad3d3 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -409,7 +409,7 @@ static void x25_destroy_socket(struct sock *sk)
*/
static int x25_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval, unsigned int optlen)
{
int opt;
struct sock *sk = sock->sk;
diff --git a/samples/tracepoints/tracepoint-sample.c b/samples/tracepoints/tracepoint-sample.c
index 9cf80a11e8b..26fab33ffa8 100644
--- a/samples/tracepoints/tracepoint-sample.c
+++ b/samples/tracepoints/tracepoint-sample.c
@@ -28,7 +28,7 @@ static int my_open(struct inode *inode, struct file *file)
return -EPERM;
}
-static struct file_operations mark_ops = {
+static const struct file_operations mark_ops = {
.open = my_open,
};
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 8e9777b7640..0c72c9c3895 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -43,7 +43,7 @@ static ssize_t ima_show_htable_violations(struct file *filp,
return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
}
-static struct file_operations ima_htable_violations_ops = {
+static const struct file_operations ima_htable_violations_ops = {
.read = ima_show_htable_violations
};
@@ -55,7 +55,7 @@ static ssize_t ima_show_measurements_count(struct file *filp,
}
-static struct file_operations ima_measurements_count_ops = {
+static const struct file_operations ima_measurements_count_ops = {
.read = ima_show_measurements_count
};
@@ -158,7 +158,7 @@ static int ima_measurements_open(struct inode *inode, struct file *file)
return seq_open(file, &ima_measurments_seqops);
}
-static struct file_operations ima_measurements_ops = {
+static const struct file_operations ima_measurements_ops = {
.open = ima_measurements_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -233,7 +233,7 @@ static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
return seq_open(file, &ima_ascii_measurements_seqops);
}
-static struct file_operations ima_ascii_measurements_ops = {
+static const struct file_operations ima_ascii_measurements_ops = {
.open = ima_ascii_measurements_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -313,7 +313,7 @@ static int ima_release_policy(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations ima_measure_policy_ops = {
+static const struct file_operations ima_measure_policy_ops = {
.open = ima_open_policy,
.write = ima_write_policy,
.release = ima_release_policy
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index f0ebc971c68..1dd66ddffca 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -897,6 +897,15 @@ static int tas_create(struct i2c_adapter *adapter,
client = i2c_new_device(adapter, &info);
if (!client)
return -ENODEV;
+ /*
+ * We know the driver is already loaded, so the device should be
+ * already bound. If not it means binding failed, and then there
+ * is no point in keeping the device instantiated.
+ */
+ if (!client->driver) {
+ i2c_unregister_device(client);
+ return -ENODEV;
+ }
/*
* Let i2c-core delete that device on driver removal.
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 6e7d09ae0e8..7d722a025d0 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -29,6 +29,8 @@ extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
extern int use_internal_drums;
+static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
+ struct snd_midi_channel *chan);
/*
* The next table looks magical, but it certainly is not. Its values have
* been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
@@ -242,16 +244,20 @@ void snd_opl3_timer_func(unsigned long data)
int again = 0;
int i;
- spin_lock_irqsave(&opl3->sys_timer_lock, flags);
+ spin_lock_irqsave(&opl3->voice_lock, flags);
for (i = 0; i < opl3->max_voices; i++) {
struct snd_opl3_voice *vp = &opl3->voices[i];
if (vp->state > 0 && vp->note_off_check) {
if (vp->note_off == jiffies)
- snd_opl3_note_off(opl3, vp->note, 0, vp->chan);
+ snd_opl3_note_off_unsafe(opl3, vp->note, 0,
+ vp->chan);
else
again++;
}
}
+ spin_unlock_irqrestore(&opl3->voice_lock, flags);
+
+ spin_lock_irqsave(&opl3->sys_timer_lock, flags);
if (again) {
opl3->tlist.expires = jiffies + 1; /* invoke again */
add_timer(&opl3->tlist);
@@ -658,15 +664,14 @@ static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
/*
* Release a note in response to a midi note off.
*/
-void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
+static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
+ struct snd_midi_channel *chan)
{
struct snd_opl3 *opl3;
int voice;
struct snd_opl3_voice *vp;
- unsigned long flags;
-
opl3 = p;
#ifdef DEBUG_MIDI
@@ -674,12 +679,9 @@ void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan
chan->number, chan->midi_program, note);
#endif
- spin_lock_irqsave(&opl3->voice_lock, flags);
-
if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
if (chan->drum_channel && use_internal_drums) {
snd_opl3_drum_switch(opl3, note, vel, 0, chan);
- spin_unlock_irqrestore(&opl3->voice_lock, flags);
return;
}
/* this loop will hopefully kill all extra voices, because
@@ -697,6 +699,16 @@ void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan
snd_opl3_kill_voice(opl3, voice);
}
}
+}
+
+void snd_opl3_note_off(void *p, int note, int vel,
+ struct snd_midi_channel *chan)
+{
+ struct snd_opl3 *opl3 = p;
+ unsigned long flags;
+
+ spin_lock_irqsave(&opl3->voice_lock, flags);
+ snd_opl3_note_off_unsafe(p, note, vel, chan);
spin_unlock_irqrestore(&opl3->voice_lock, flags);
}
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index c52691c2fc4..9a88cdfd952 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -915,7 +915,7 @@ static int __devinit hal2_probe(struct platform_device *pdev)
return 0;
}
-static int __exit hal2_remove(struct platform_device *pdev)
+static int __devexit hal2_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index e497525bc11..8691f4cf619 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -973,7 +973,7 @@ static int __devinit snd_sgio2audio_probe(struct platform_device *pdev)
return 0;
}
-static int __exit snd_sgio2audio_remove(struct platform_device *pdev)
+static int __devexit snd_sgio2audio_remove(struct platform_device *pdev)
{
struct snd_card *card = platform_get_drvdata(pdev);
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index b1b3a644f73..75454648d50 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1037,7 +1037,7 @@ static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state)
static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state)
{
- return atc_daio_unmute(atc, state, LINEO4);
+ return atc_daio_unmute(atc, state, LINEO2);
}
static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
@@ -1047,7 +1047,7 @@ static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state)
{
- return atc_daio_unmute(atc, state, LINEO2);
+ return atc_daio_unmute(atc, state, LINEO4);
}
static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index da2065cd2c0..1305f7ca02c 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -950,7 +950,7 @@ static int __devinit snd_echo_new_pcm(struct echoaudio *chip)
Control interface
******************************************************************************/
-#ifndef ECHOCARD_HAS_VMIXER
+#if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN)
/******************* PCM output volume *******************/
static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol,
@@ -1003,6 +1003,19 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
return changed;
}
+#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
+/* On the Mia this one controls the line-out volume */
+static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
+ .name = "Line Playback Volume",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+ .info = snd_echo_output_gain_info,
+ .get = snd_echo_output_gain_get,
+ .put = snd_echo_output_gain_put,
+ .tlv = {.p = db_scale_output_gain},
+};
+#else
static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
.name = "PCM Playback Volume",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1012,9 +1025,10 @@ static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
.put = snd_echo_output_gain_put,
.tlv = {.p = db_scale_output_gain},
};
-
#endif
+#endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */
+
#ifdef ECHOCARD_HAS_INPUT_GAIN
@@ -2030,10 +2044,18 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
goto ctl_error;
-#else
- if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0)
+#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_echo_line_output_gain, chip));
+ if (err < 0)
goto ctl_error;
#endif
+#else /* ECHOCARD_HAS_VMIXER */
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_echo_pcm_output_gain, chip));
+ if (err < 0)
+ goto ctl_error;
+#endif /* ECHOCARD_HAS_VMIXER */
#ifdef ECHOCARD_HAS_INPUT_GAIN
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index f3b9b45c9c1..f05c8c097aa 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -29,6 +29,7 @@
#define ECHOCARD_HAS_ADAT FALSE
#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
#define ECHOCARD_HAS_MIDI
+#define ECHOCARD_HAS_LINE_OUT_GAIN
/* Pipe indexes */
#define PX_ANALOG_OUT 0 /* 8 */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 20a66f85f0a..c9ad182e1b4 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2303,6 +2303,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
* white-list for enable_msi
*/
static struct snd_pci_quirk msi_white_list[] __devinitdata = {
+ SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1),
SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1),
{}
};
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 215e72a8711..2d603f6aba6 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -4032,6 +4032,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
}
/*
+ * HP Touchsmart
+ * port-A (0x11) - front hp-out
+ * port-B (0x14) - unused
+ * port-C (0x15) - unused
+ * port-D (0x12) - rear line out
+ * port-E (0x1c) - front mic-in
+ * port-F (0x16) - Internal speakers
+ * digital-mic (0x17) - Internal mic
+ */
+
+static struct hda_verb ad1984a_touchsmart_verbs[] = {
+ /* DACs; unmute as default */
+ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
+ /* Port-A (HP) mixer - route only from analog mixer */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ /* Port-A pin */
+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ /* Port-A (HP) pin - always unmuted */
+ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Port-E (int speaker) mixer - route only from analog mixer */
+ {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
+ /* Port-E pin */
+ {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ /* Port-F (int speaker) mixer - route only from analog mixer */
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ /* Port-F pin */
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Analog mixer; mute as default */
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ /* Analog Mix output amp */
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* capture sources */
+ /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* unsolicited event for pin-sense */
+ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
+ {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
+ /* allow to touch GPIO1 (for mute control) */
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
+ /* internal mic - dmic */
+ {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ /* set magic COEFs for dmic */
+ {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
+ {0x01, AC_VERB_SET_PROC_COEF, 0x08},
+ { } /* end */
+};
+
+static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
+/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Master Playback Switch",
+ .info = snd_hda_mixer_amp_switch_info,
+ .get = snd_hda_mixer_amp_switch_get,
+ .put = ad1884a_mobile_master_sw_put,
+ .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
+ },
+ HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
+ HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
+/* switch to external mic if plugged */
+static void ad1984a_touchsmart_automic(struct hda_codec *codec)
+{
+ if (snd_hda_codec_read(codec, 0x1c, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000) {
+ snd_hda_codec_write(codec, 0x0c, 0,
+ AC_VERB_SET_CONNECT_SEL, 0x4);
+ } else {
+ snd_hda_codec_write(codec, 0x0c, 0,
+ AC_VERB_SET_CONNECT_SEL, 0x5);
+ }
+}
+
+
+/* unsolicited event for HP jack sensing */
+static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case AD1884A_HP_EVENT:
+ ad1884a_hp_automute(codec);
+ break;
+ case AD1884A_MIC_EVENT:
+ ad1984a_touchsmart_automic(codec);
+ break;
+ }
+}
+
+/* initialize jack-sensing, too */
+static int ad1984a_touchsmart_init(struct hda_codec *codec)
+{
+ ad198x_init(codec);
+ ad1884a_hp_automute(codec);
+ ad1984a_touchsmart_automic(codec);
+ return 0;
+}
+
+
+/*
*/
enum {
@@ -4039,6 +4160,7 @@ enum {
AD1884A_LAPTOP,
AD1884A_MOBILE,
AD1884A_THINKPAD,
+ AD1984A_TOUCHSMART,
AD1884A_MODELS
};
@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
[AD1884A_LAPTOP] = "laptop",
[AD1884A_MOBILE] = "mobile",
[AD1884A_THINKPAD] = "thinkpad",
+ [AD1984A_TOUCHSMART] = "touchsmart",
};
static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
+ SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
{}
};
@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec)
codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
codec->patch_ops.init = ad1984a_thinkpad_init;
break;
+ case AD1984A_TOUCHSMART:
+ spec->mixers[0] = ad1984a_touchsmart_mixers;
+ spec->init_verbs[0] = ad1984a_touchsmart_verbs;
+ spec->multiout.dig_out_nid = 0;
+ codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
+ codec->patch_ops.init = ad1984a_touchsmart_init;
+ /* set the upper-limit for mixer amp to 0dB for avoiding the
+ * possible damage by overloading
+ */
+ snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
+ (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (1 << AC_AMPCAP_MUTE_SHIFT));
+ break;
}
return 0;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 9d899eda44d..3fbbc8c01e7 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -682,11 +682,13 @@ static struct hda_input_mux cxt5045_capture_source = {
};
static struct hda_input_mux cxt5045_capture_source_benq = {
- .num_items = 3,
+ .num_items = 5,
.items = {
{ "IntMic", 0x1 },
{ "ExtMic", 0x2 },
{ "LineIn", 0x3 },
+ { "CD", 0x4 },
+ { "Mixer", 0x0 },
}
};
@@ -811,11 +813,19 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
};
static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
+ HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
+
HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
+
{}
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 12960581956..470fd74a0a1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1332,15 +1332,20 @@ do_sku:
* when the external headphone out jack is plugged"
*/
if (!spec->autocfg.hp_pins[0]) {
+ hda_nid_t nid;
tmp = (ass >> 11) & 0x3; /* HP to chassis */
if (tmp == 0)
- spec->autocfg.hp_pins[0] = porta;
+ nid = porta;
else if (tmp == 1)
- spec->autocfg.hp_pins[0] = porte;
+ nid = porte;
else if (tmp == 2)
- spec->autocfg.hp_pins[0] = portd;
+ nid = portd;
else
return 1;
+ for (i = 0; i < spec->autocfg.line_outs; i++)
+ if (spec->autocfg.line_out_pins[i] == nid)
+ return 1;
+ spec->autocfg.hp_pins[0] = nid;
}
alc_init_auto_hp(codec);
@@ -1362,7 +1367,7 @@ static void alc_ssid_check(struct hda_codec *codec,
}
/*
- * Fix-up pin default configurations
+ * Fix-up pin default configurations and add default verbs
*/
struct alc_pincfg {
@@ -1370,9 +1375,14 @@ struct alc_pincfg {
u32 val;
};
-static void alc_fix_pincfg(struct hda_codec *codec,
+struct alc_fixup {
+ const struct alc_pincfg *pins;
+ const struct hda_verb *verbs;
+};
+
+static void alc_pick_fixup(struct hda_codec *codec,
const struct snd_pci_quirk *quirk,
- const struct alc_pincfg **pinfix)
+ const struct alc_fixup *fix)
{
const struct alc_pincfg *cfg;
@@ -1380,9 +1390,14 @@ static void alc_fix_pincfg(struct hda_codec *codec,
if (!quirk)
return;
- cfg = pinfix[quirk->value];
- for (; cfg->nid; cfg++)
- snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+ fix += quirk->value;
+ cfg = fix->pins;
+ if (cfg) {
+ for (; cfg->nid; cfg++)
+ snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+ }
+ if (fix->verbs)
+ add_verb(codec->spec, fix->verbs);
}
/*
@@ -9593,11 +9608,13 @@ static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
{ }
};
-static const struct alc_pincfg *alc882_pin_fixes[] = {
- [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
+static const struct alc_fixup alc882_fixups[] = {
+ [PINFIX_ABIT_AW9D_MAX] = {
+ .pins = alc882_abit_aw9d_pinfix
+ },
};
-static struct snd_pci_quirk alc882_pinfix_tbl[] = {
+static struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
{}
};
@@ -9869,7 +9886,7 @@ static int patch_alc882(struct hda_codec *codec)
board_config = ALC882_AUTO;
}
- alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
+ alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
if (board_config == ALC882_AUTO) {
/* automatic parse from the BIOS config */
@@ -12660,7 +12677,7 @@ static struct alc_config_preset alc268_presets[] = {
.init_hook = alc268_toshiba_automute,
},
[ALC268_ACER] = {
- .mixers = { alc268_acer_mixer, alc268_capture_nosrc_mixer,
+ .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
alc268_beep_mixer },
.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
alc268_acer_verbs },
@@ -12842,12 +12859,15 @@ static int patch_alc268(struct hda_codec *codec)
unsigned int wcap = get_wcaps(codec, 0x07);
int i;
+ spec->capsrc_nids = alc268_capsrc_nids;
/* get type */
wcap = get_wcaps_type(wcap);
if (spec->auto_mic ||
wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
spec->adc_nids = alc268_adc_nids_alt;
spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
+ if (spec->auto_mic)
+ fixup_automic_adc(codec);
if (spec->auto_mic || spec->input_mux->num_items == 1)
add_mixer(spec, alc268_capture_nosrc_mixer);
else
@@ -12857,7 +12877,6 @@ static int patch_alc268(struct hda_codec *codec)
spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
add_mixer(spec, alc268_capture_mixer);
}
- spec->capsrc_nids = alc268_capsrc_nids;
/* set default input source */
for (i = 0; i < spec->num_adc_nids; i++)
snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
@@ -14357,15 +14376,16 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
static void alc861_auto_init_hp_out(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
- hda_nid_t pin;
- pin = spec->autocfg.hp_pins[0];
- if (pin)
- alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
+ if (spec->autocfg.hp_outs)
+ alc861_auto_set_output_and_unmute(codec,
+ spec->autocfg.hp_pins[0],
+ PIN_HP,
spec->multiout.hp_nid);
- pin = spec->autocfg.speaker_pins[0];
- if (pin)
- alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT,
+ if (spec->autocfg.speaker_outs)
+ alc861_auto_set_output_and_unmute(codec,
+ spec->autocfg.speaker_pins[0],
+ PIN_OUT,
spec->multiout.dac_nids[0]);
}
@@ -15158,7 +15178,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
- SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
+ /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
@@ -15551,6 +15571,29 @@ static void alc861vd_auto_init(struct hda_codec *codec)
alc_inithook(codec);
}
+enum {
+ ALC660VD_FIX_ASUS_GPIO1
+};
+
+/* reset GPIO1 */
+static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
+ { }
+};
+
+static const struct alc_fixup alc861vd_fixups[] = {
+ [ALC660VD_FIX_ASUS_GPIO1] = {
+ .verbs = alc660vd_fix_asus_gpio1_verbs,
+ },
+};
+
+static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
+ {}
+};
+
static int patch_alc861vd(struct hda_codec *codec)
{
struct alc_spec *spec;
@@ -15572,6 +15615,8 @@ static int patch_alc861vd(struct hda_codec *codec)
board_config = ALC861VD_AUTO;
}
+ alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
+
if (board_config == ALC861VD_AUTO) {
/* automatic parse from the BIOS config */
err = alc861vd_parse_auto_config(codec);
@@ -16852,6 +16897,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
ALC662_3ST_6ch_DIG),
@@ -17145,70 +17191,145 @@ static struct alc_config_preset alc662_presets[] = {
* BIOS auto configuration
*/
+/* convert from MIX nid to DAC */
+static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
+{
+ if (nid == 0x0f)
+ return 0x02;
+ else if (nid >= 0x0c && nid <= 0x0e)
+ return nid - 0x0c + 0x02;
+ else
+ return 0;
+}
+
+/* get MIX nid connected to the given pin targeted to DAC */
+static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
+ hda_nid_t dac)
+{
+ hda_nid_t mix[4];
+ int i, num;
+
+ num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
+ for (i = 0; i < num; i++) {
+ if (alc662_mix_to_dac(mix[i]) == dac)
+ return mix[i];
+ }
+ return 0;
+}
+
+/* look for an empty DAC slot */
+static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t srcs[5];
+ int i, j, num;
+
+ num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
+ if (num < 0)
+ return 0;
+ for (i = 0; i < num; i++) {
+ hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
+ if (!nid)
+ continue;
+ for (j = 0; j < spec->multiout.num_dacs; j++)
+ if (spec->multiout.dac_nids[j] == nid)
+ break;
+ if (j >= spec->multiout.num_dacs)
+ return nid;
+ }
+ return 0;
+}
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
+ const struct auto_pin_cfg *cfg)
+{
+ struct alc_spec *spec = codec->spec;
+ int i;
+ hda_nid_t dac;
+
+ spec->multiout.dac_nids = spec->private_dac_nids;
+ for (i = 0; i < cfg->line_outs; i++) {
+ dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
+ if (!dac)
+ continue;
+ spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
+ }
+ return 0;
+}
+
+static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
+ hda_nid_t nid, unsigned int chs)
+{
+ char name[32];
+ sprintf(name, "%s Playback Volume", pfx);
+ return add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
+}
+
+static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
+ hda_nid_t nid, unsigned int chs)
+{
+ char name[32];
+ sprintf(name, "%s Playback Switch", pfx);
+ return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
+}
+
+#define alc662_add_stereo_vol(spec, pfx, nid) \
+ alc662_add_vol_ctl(spec, pfx, nid, 3)
+#define alc662_add_stereo_sw(spec, pfx, nid) \
+ alc662_add_sw_ctl(spec, pfx, nid, 3)
+
/* add playback controls from the parsed DAC table */
-static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
+static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
- char name[32];
+ struct alc_spec *spec = codec->spec;
static const char *chname[4] = {
"Front", "Surround", NULL /*CLFE*/, "Side"
};
- hda_nid_t nid;
+ hda_nid_t nid, mix;
int i, err;
for (i = 0; i < cfg->line_outs; i++) {
- if (!spec->multiout.dac_nids[i])
+ nid = spec->multiout.dac_nids[i];
+ if (!nid)
+ continue;
+ mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
+ if (!mix)
continue;
- nid = alc880_idx_to_dac(i);
if (i == 2) {
/* Center/LFE */
- err = add_control(spec, ALC_CTL_WIDGET_VOL,
- "Center Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid, 1, 0,
- HDA_OUTPUT));
+ err = alc662_add_vol_ctl(spec, "Center", nid, 1);
if (err < 0)
return err;
- err = add_control(spec, ALC_CTL_WIDGET_VOL,
- "LFE Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid, 2, 0,
- HDA_OUTPUT));
+ err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
if (err < 0)
return err;
- err = add_control(spec, ALC_CTL_WIDGET_MUTE,
- "Center Playback Switch",
- HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
- HDA_INPUT));
+ err = alc662_add_sw_ctl(spec, "Center", mix, 1);
if (err < 0)
return err;
- err = add_control(spec, ALC_CTL_WIDGET_MUTE,
- "LFE Playback Switch",
- HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
- HDA_INPUT));
+ err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
if (err < 0)
return err;
} else {
const char *pfx;
if (cfg->line_outs == 1 &&
cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
- if (!cfg->hp_pins)
+ if (cfg->hp_outs)
pfx = "Speaker";
else
pfx = "PCM";
} else
pfx = chname[i];
- sprintf(name, "%s Playback Volume", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0,
- HDA_OUTPUT));
+ err = alc662_add_vol_ctl(spec, pfx, nid, 3);
if (err < 0)
return err;
if (cfg->line_outs == 1 &&
cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
pfx = "Speaker";
- sprintf(name, "%s Playback Switch", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
- 3, 0, HDA_INPUT));
+ err = alc662_add_sw_ctl(spec, pfx, mix, 3);
if (err < 0)
return err;
}
@@ -17217,54 +17338,38 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
}
/* add playback controls for speaker and HP outputs */
-static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+/* return DAC nid if any new DAC is assigned */
+static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
const char *pfx)
{
- hda_nid_t nid;
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t nid, mix;
int err;
- char name[32];
if (!pin)
return 0;
-
- if (pin == 0x17) {
- /* ALC663 has a mono output pin on 0x17 */
+ nid = alc662_look_for_dac(codec, pin);
+ if (!nid) {
+ char name[32];
+ /* the corresponding DAC is already occupied */
+ if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
+ return 0; /* no way */
+ /* create a switch only */
sprintf(name, "%s Playback Switch", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
- return err;
+ return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
}
- if (alc880_is_fixed_pin(pin)) {
- nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
- /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
- /* specify the DAC as the extra output */
- if (!spec->multiout.hp_nid)
- spec->multiout.hp_nid = nid;
- else
- spec->multiout.extra_out_nid[0] = nid;
- /* control HP volume/switch on the output mixer amp */
- nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
- sprintf(name, "%s Playback Volume", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- sprintf(name, "%s Playback Switch", pfx);
- err = add_control(spec, ALC_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
- if (err < 0)
- return err;
- } else if (alc880_is_multi_pin(pin)) {
- /* set manual connection */
- /* we have only a switch on HP-out PIN */
- sprintf(name, "%s Playback Switch", pfx);
- err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
- if (err < 0)
- return err;
- }
- return 0;
+ mix = alc662_dac_to_mix(codec, pin, nid);
+ if (!mix)
+ return 0;
+ err = alc662_add_vol_ctl(spec, pfx, nid, 3);
+ if (err < 0)
+ return err;
+ err = alc662_add_sw_ctl(spec, pfx, mix, 3);
+ if (err < 0)
+ return err;
+ return nid;
}
/* create playback/capture controls for input pins */
@@ -17273,30 +17378,35 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
hda_nid_t nid, int pin_type,
- int dac_idx)
+ hda_nid_t dac)
{
+ int i, num;
+ hda_nid_t srcs[4];
+
alc_set_pin_output(codec, nid, pin_type);
/* need the manual connection? */
- if (alc880_is_multi_pin(nid)) {
- struct alc_spec *spec = codec->spec;
- int idx = alc880_multi_pin_idx(nid);
- snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
- AC_VERB_SET_CONNECT_SEL,
- alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
+ num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
+ if (num <= 1)
+ return;
+ for (i = 0; i < num; i++) {
+ if (alc662_mix_to_dac(srcs[i]) != dac)
+ continue;
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
+ return;
}
}
static void alc662_auto_init_multi_out(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
int i;
for (i = 0; i <= HDA_SIDE; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
- int pin_type = get_pin_type(spec->autocfg.line_out_type);
if (nid)
alc662_auto_set_output_and_unmute(codec, nid, pin_type,
- i);
+ spec->multiout.dac_nids[i]);
}
}
@@ -17306,12 +17416,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
hda_nid_t pin;
pin = spec->autocfg.hp_pins[0];
- if (pin) /* connect to front */
- /* use dac 0 */
- alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
+ if (pin)
+ alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
+ spec->multiout.hp_nid);
pin = spec->autocfg.speaker_pins[0];
if (pin)
- alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
+ alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
+ spec->multiout.extra_out_nid[0]);
}
#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
@@ -17349,21 +17460,25 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
if (!spec->autocfg.line_outs)
return 0; /* can't find valid BIOS pin config */
- err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+ err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
if (err < 0)
return err;
- err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
if (err < 0)
return err;
- err = alc662_auto_create_extra_out(spec,
+ err = alc662_auto_create_extra_out(codec,
spec->autocfg.speaker_pins[0],
"Speaker");
if (err < 0)
return err;
- err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+ if (err)
+ spec->multiout.extra_out_nid[0] = err;
+ err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
"Headphone");
if (err < 0)
return err;
+ if (err)
+ spec->multiout.hp_nid = err;
err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
if (err < 0)
return err;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 826137ec300..a9b26828a65 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -182,8 +182,8 @@ struct sigmatel_jack {
struct sigmatel_mic_route {
hda_nid_t pin;
- unsigned char mux_idx;
- unsigned char dmux_idx;
+ signed char mux_idx;
+ signed char dmux_idx;
};
struct sigmatel_spec {
@@ -3469,18 +3469,26 @@ static int set_mic_route(struct hda_codec *codec,
break;
if (i <= AUTO_PIN_FRONT_MIC) {
/* analog pin */
- mic->dmux_idx = 0;
i = get_connection_index(codec, spec->mux_nids[0], pin);
if (i < 0)
return -1;
mic->mux_idx = i;
+ mic->dmux_idx = -1;
+ if (spec->dmux_nids)
+ mic->dmux_idx = get_connection_index(codec,
+ spec->dmux_nids[0],
+ spec->mux_nids[0]);
} else if (spec->dmux_nids) {
/* digital pin */
- mic->mux_idx = 0;
i = get_connection_index(codec, spec->dmux_nids[0], pin);
if (i < 0)
return -1;
mic->dmux_idx = i;
+ mic->mux_idx = -1;
+ if (spec->mux_nids)
+ mic->mux_idx = get_connection_index(codec,
+ spec->mux_nids[0],
+ spec->dmux_nids[0]);
}
return 0;
}
@@ -4557,11 +4565,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
mic = &spec->ext_mic;
else
mic = &spec->int_mic;
- if (mic->dmux_idx)
+ if (mic->dmux_idx >= 0)
snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
AC_VERB_SET_CONNECT_SEL,
mic->dmux_idx);
- else
+ if (mic->mux_idx >= 0)
snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
AC_VERB_SET_CONNECT_SEL,
mic->mux_idx);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index cecf1ffeeaa..d74033a2cfb 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2259,7 +2259,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
}
static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "Multi Track Peak",
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = snd_ice1712_pro_peak_info,
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index af6e0014862..76b717dae4b 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1294,7 +1294,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(ice->pci),
- 64*1024, 64*1024);
+ 256*1024, 256*1024);
ice->pcm = pcm;
@@ -1408,7 +1408,7 @@ static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(ice->pci),
- 64*1024, 64*1024);
+ 256*1024, 256*1024);
ice->pcm_ds = pcm;
@@ -2110,7 +2110,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
}
static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "Multi Track Peak",
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = snd_vt1724_pro_peak_info,
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 171ada53520..754867ed478 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1954,6 +1954,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.name = "Sony S1XP",
.type = AC97_TUNE_INV_EAPD
},
+ {
+ .subvendor = 0x104d,
+ .subdevice = 0x81c0,
+ .name = "Sony VAIO VGN-T350P", /*AD1981B*/
+ .type = AC97_TUNE_INV_EAPD
+ },
+ {
+ .subvendor = 0x104d,
+ .subdevice = 0x81c5,
+ .name = "Sony VAIO VGN-B1VP", /*AD1981B*/
+ .type = AC97_TUNE_INV_EAPD
+ },
{
.subvendor = 0x1043,
.subdevice = 0x80f3,
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index acfa4760da4..91683a34903 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1626,7 +1626,7 @@ static int snd_via8233_dxs_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+ unsigned int idx = kcontrol->id.subdevice;
ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
@@ -1646,7 +1646,7 @@ static int snd_via8233_dxs_volume_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct via82xx *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+ unsigned int idx = kcontrol->id.subdevice;
unsigned long port = chip->port + 0x10 * idx;
unsigned char val;
int i, change = 0;
@@ -1705,11 +1705,12 @@ static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata =
};
static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
- .name = "VIA DXS Playback Volume",
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .device = 0,
+ /* .subdevice set later */
+ .name = "PCM Playback Volume",
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .count = 4,
.info = snd_via8233_dxs_volume_info,
.get = snd_via8233_dxs_volume_get,
.put = snd_via8233_dxs_volume_put,
@@ -1936,10 +1937,18 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip)
}
else /* Using DXS when PCM emulation is enabled is really weird */
{
- /* Standalone DXS controls */
- err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
- if (err < 0)
- return err;
+ for (i = 0; i < 4; ++i) {
+ struct snd_kcontrol *kctl;
+
+ kctl = snd_ctl_new1(
+ &snd_via8233_dxs_volume_control, chip);
+ if (!kctl)
+ return -ENOMEM;
+ kctl->id.subdevice = i;
+ err = snd_ctl_add(chip->card, kctl);
+ if (err < 0)
+ return err;
+ }
}
}
/* select spdif data slot 10/11 */
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index 835fa19ed46..d06f780bd7e 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -59,6 +59,18 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
strlcpy(info.type, "keywest", I2C_NAME_SIZE);
info.addr = keywest_ctx->addr;
keywest_ctx->client = i2c_new_device(adapter, &info);
+ if (!keywest_ctx->client)
+ return -ENODEV;
+ /*
+ * We know the driver is already loaded, so the device should be
+ * already bound. If not it means binding failed, and then there
+ * is no point in keeping the device instantiated.
+ */
+ if (!keywest_ctx->client->driver) {
+ i2c_unregister_device(keywest_ctx->client);
+ keywest_ctx->client = NULL;
+ return -ENODEV;
+ }
/*
* Let i2c-core delete that device on driver removal.
@@ -86,7 +98,7 @@ static const struct i2c_device_id keywest_i2c_id[] = {
{ }
};
-struct i2c_driver keywest_driver = {
+static struct i2c_driver keywest_driver = {
.driver = {
.name = "PMac Keywest Audio",
},
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index ac927ffdc96..97f1a251e44 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -7,15 +7,6 @@ config SND_BF5XX_I2S
mode (supports single stereo In/Out).
You will also need to select the audio interfaces to support below.
-config SND_BF5XX_TDM
- tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
- depends on (BLACKFIN && SND_SOC)
- help
- Say Y or M if you want to add support for codecs attached to
- the Blackfin SPORT (synchronous serial ports) interface in TDM
- mode.
- You will also need to select the audio interfaces to support below.
-
config SND_BF5XX_SOC_SSM2602
tristate "SoC SSM2602 Audio support for BF52x ezkit"
depends on SND_BF5XX_I2S
@@ -41,6 +32,31 @@ config SND_BFIN_AD73311_SE
Enter the GPIO used to control AD73311's SE pin. Acceptable
values are 0 to 7
+config SND_BF5XX_TDM
+ tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
+ depends on (BLACKFIN && SND_SOC)
+ help
+ Say Y or M if you want to add support for codecs attached to
+ the Blackfin SPORT (synchronous serial ports) interface in TDM
+ mode.
+ You will also need to select the audio interfaces to support below.
+
+config SND_BF5XX_SOC_AD1836
+ tristate "SoC AD1836 Audio support for BF5xx"
+ depends on SND_BF5XX_TDM
+ select SND_BF5XX_SOC_TDM
+ select SND_SOC_AD1836
+ help
+ Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
+
+config SND_BF5XX_SOC_AD1938
+ tristate "SoC AD1938 Audio support for Blackfin"
+ depends on SND_BF5XX_TDM
+ select SND_BF5XX_SOC_TDM
+ select SND_SOC_AD1938
+ help
+ Say Y if you want to add support for AD1938 codec on Blackfin.
+
config SND_BF5XX_AC97
tristate "SoC AC97 Audio for the ADI BF5xx chip"
depends on BLACKFIN
@@ -71,6 +87,30 @@ config SND_BF5XX_MULTICHAN_SUPPORT
Say y if you want AC97 driver to support up to 5.1 channel audio.
this mode will consume much more memory for DMA.
+config SND_BF5XX_HAVE_COLD_RESET
+ bool "BOARD has COLD Reset GPIO"
+ depends on SND_BF5XX_AC97
+ default y if BFIN548_EZKIT
+ default n if !BFIN548_EZKIT
+
+config SND_BF5XX_RESET_GPIO_NUM
+ int "Set a GPIO for cold reset"
+ depends on SND_BF5XX_HAVE_COLD_RESET
+ range 0 159
+ default 19 if BFIN548_EZKIT
+ default 5 if BFIN537_STAMP
+ default 0
+ help
+ Set the correct GPIO for RESET the sound chip.
+
+config SND_BF5XX_SOC_AD1980
+ tristate "SoC AD1980/1 Audio support for BF5xx"
+ depends on SND_BF5XX_AC97
+ select SND_BF5XX_SOC_AC97
+ select SND_SOC_AD1980
+ help
+ Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
+
config SND_BF5XX_SOC_SPORT
tristate
@@ -88,30 +128,6 @@ config SND_BF5XX_SOC_AC97
select SND_SOC_AC97_BUS
select SND_BF5XX_SOC_SPORT
-config SND_BF5XX_SOC_AD1836
- tristate "SoC AD1836 Audio support for BF5xx"
- depends on SND_BF5XX_TDM
- select SND_BF5XX_SOC_TDM
- select SND_SOC_AD1836
- help
- Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD1980
- tristate "SoC AD1980/1 Audio support for BF5xx"
- depends on SND_BF5XX_AC97
- select SND_BF5XX_SOC_AC97
- select SND_SOC_AD1980
- help
- Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
-
-config SND_BF5XX_SOC_AD1938
- tristate "SoC AD1938 Audio support for Blackfin"
- depends on SND_BF5XX_TDM
- select SND_BF5XX_SOC_TDM
- select SND_SOC_AD1938
- help
- Say Y if you want to add support for AD1938 codec on Blackfin.
-
config SND_BF5XX_SPORT_NUM
int "Set a SPORT for Sound chip"
depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM)
@@ -120,19 +136,3 @@ config SND_BF5XX_SPORT_NUM
default 0
help
Set the correct SPORT for sound chip.
-
-config SND_BF5XX_HAVE_COLD_RESET
- bool "BOARD has COLD Reset GPIO"
- depends on SND_BF5XX_AC97
- default y if BFIN548_EZKIT
- default n if !BFIN548_EZKIT
-
-config SND_BF5XX_RESET_GPIO_NUM
- int "Set a GPIO for cold reset"
- depends on SND_BF5XX_HAVE_COLD_RESET
- range 0 159
- default 19 if BFIN548_EZKIT
- default 5 if BFIN537_STAMP
- default 0
- help
- Set the correct GPIO for RESET the sound chip.
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 1e9d161c76c..084b68884ad 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = {
* TFS. When Port G is selected and EMAC then there is a conflict between
* the PHY interrupt line and TFS. Current settings prevent the conflict
* by ignoring the TFS pin when Port G is selected. This allows both
- * ssm2602 using Port G and EMAC concurrently.
+ * codecs and EMAC using Port G concurrently.
*/
-#ifdef CONFIG_BF527_SPORT0_PORTF
-#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
-#else
+#ifdef CONFIG_BF527_SPORT0_PORTG
#define LOCAL_SPORT0_TFS (0)
+#else
+#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#endif
static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 3096badf09a..ff546e91a22 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -78,12 +78,12 @@ static struct sport_param sport_params[2] = {
* TFS. When Port G is selected and EMAC then there is a conflict between
* the PHY interrupt line and TFS. Current settings prevent the conflict
* by ignoring the TFS pin when Port G is selected. This allows both
- * ssm2602 using Port G and EMAC concurrently.
+ * codecs and EMAC using Port G concurrently.
*/
-#ifdef CONFIG_BF527_SPORT0_PORTF
-#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
-#else
+#ifdef CONFIG_BF527_SPORT0_PORTG
#define LOCAL_SPORT0_TFS (0)
+#else
+#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
#endif
static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 3ff0373dff8..593d5b9c9f0 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -579,7 +579,7 @@ static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
SOC_DAPM_SINGLE("PGA Capture Switch",
- WM8350_LEFT_INPUT_VOLUME, 14, 1, 0),
+ WM8350_LEFT_INPUT_VOLUME, 14, 1, 1),
};
/* Right Input Mixer */
@@ -589,7 +589,7 @@ static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
SOC_DAPM_SINGLE("PGA Capture Switch",
- WM8350_RIGHT_INPUT_VOLUME, 14, 1, 0),
+ WM8350_RIGHT_INPUT_VOLUME, 14, 1, 1),
};
/* Left Mic Mixer */
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index da97aae475a..1ef2454c520 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -790,7 +790,7 @@ static int wm8940_register(struct wm8940_priv *wm8940,
codec->reg_cache = &wm8940->reg_cache;
ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
- if (ret == 0) {
+ if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 12a6c549ee6..4ae70704802 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -97,22 +97,19 @@ enum {
DAVINCI_MCBSP_WORD_32,
};
-static struct davinci_pcm_dma_params davinci_i2s_pcm_out = {
- .name = "I2S PCM Stereo out",
-};
-
-static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
- .name = "I2S PCM Stereo in",
-};
-
struct davinci_mcbsp_dev {
+ /*
+ * dma_params must be first because rtd->dai->cpu_dai->private_data
+ * is cast to a pointer of an array of struct davinci_pcm_dma_params in
+ * davinci_pcm_open.
+ */
+ struct davinci_pcm_dma_params dma_params[2];
void __iomem *base;
#define MOD_DSP_A 0
#define MOD_DSP_B 1
int mode;
u32 pcr;
struct clk *clk;
- struct davinci_pcm_dma_params *dma_params[2];
};
static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
@@ -215,14 +212,6 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
toggle_clock(dev, playback);
}
-static int davinci_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
- cpu_dai->dma_data = dev->dma_params[substream->stream];
- return 0;
-}
-
#define DEFAULT_BITPERSAMPLE 16
static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -353,8 +342,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
- struct davinci_pcm_dma_params *dma_params = dai->dma_data;
struct davinci_mcbsp_dev *dev = dai->private_data;
+ struct davinci_pcm_dma_params *dma_params =
+ &dev->dma_params[substream->stream];
struct snd_interval *i = NULL;
int mcbsp_word_length;
unsigned int rcr, xcr, srgr;
@@ -472,7 +462,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
- .startup = davinci_i2s_startup,
.shutdown = davinci_i2s_shutdown,
.prepare = davinci_i2s_prepare,
.trigger = davinci_i2s_trigger,
@@ -534,12 +523,10 @@ static int davinci_i2s_probe(struct platform_device *pdev)
dev->base = (void __iomem *)IO_ADDRESS(mem->start);
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out;
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
+ dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
(dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in;
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
+ dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
(dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
/* first TX, then RX */
@@ -549,7 +536,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENXIO;
goto err_free_mem;
}
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start;
+ dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) {
@@ -557,7 +544,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
ret = -ENXIO;
goto err_free_mem;
}
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start;
+ dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
davinci_i2s_dai.private_data = dev;
ret = snd_soc_register_dai(&davinci_i2s_dai);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 7a06c0a8666..5d1f98a4c97 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
printk(KERN_ERR "GBLCTL write error\n");
}
-static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *cpu_dai)
-{
- struct davinci_audio_dev *dev = cpu_dai->private_data;
- cpu_dai->dma_data = dev->dma_params[substream->stream];
- return 0;
-}
-
static void mcasp_start_rx(struct davinci_audio_dev *dev)
{
mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
{
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (dev->txnumevt) /* enable FIFO */
+ mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ FIFO_ENABLE);
mcasp_start_tx(dev);
- else
+ } else {
+ if (dev->rxnumevt) /* enable FIFO */
+ mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ FIFO_ENABLE);
mcasp_start_rx(dev);
-
- /* enable FIFO */
- if (dev->txnumevt)
- mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
-
- if (dev->rxnumevt)
- mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+ }
}
static void mcasp_stop_rx(struct davinci_audio_dev *dev)
@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev)
static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
{
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (dev->txnumevt) /* disable FIFO */
+ mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+ FIFO_ENABLE);
mcasp_stop_tx(dev);
- else
+ } else {
+ if (dev->rxnumevt) /* disable FIFO */
+ mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+ FIFO_ENABLE);
mcasp_stop_rx(dev);
-
- /* disable FIFO */
- if (dev->txnumevt)
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
-
- if (dev->rxnumevt)
- mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
+ }
}
static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -720,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
{
struct davinci_audio_dev *dev = cpu_dai->private_data;
struct davinci_pcm_dma_params *dma_params =
- dev->dma_params[substream->stream];
+ &dev->dma_params[substream->stream];
int word_length;
u8 numevt;
@@ -798,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
}
static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
- .startup = davinci_mcasp_startup,
.trigger = davinci_mcasp_trigger,
.hw_params = davinci_mcasp_hw_params,
.set_fmt = davinci_mcasp_set_dai_fmt,
@@ -849,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
struct resource *mem, *ioarea, *res;
struct snd_platform_data *pdata;
struct davinci_audio_dev *dev;
- int count = 0;
int ret = 0;
dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
- dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
- GFP_KERNEL);
- if (!dma_data) {
- ret = -ENOMEM;
- goto err_release_dev;
- }
-
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
@@ -897,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dev->txnumevt = pdata->txnumevt;
dev->rxnumevt = pdata->rxnumevt;
- dma_data[count].name = "I2S PCM Stereo out";
- dma_data[count].eventq_no = pdata->eventq_no;
- dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
+ dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
+ dma_data->eventq_no = pdata->eventq_no;
+ dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
io_v2p(dev->base));
- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
/* first TX, then RX */
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -910,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err_release_region;
}
- dma_data[count].channel = res->start;
- count++;
- dma_data[count].name = "I2S PCM Stereo in";
- dma_data[count].eventq_no = pdata->eventq_no;
- dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
+ dma_data->channel = res->start;
+
+ dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
+ dma_data->eventq_no = pdata->eventq_no;
+ dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
io_v2p(dev->base));
- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) {
@@ -924,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
goto err_release_region;
}
- dma_data[count].channel = res->start;
+ dma_data->channel = res->start;
davinci_mcasp_dai[pdata->op_mode].private_data = dev;
davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
@@ -936,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
err_release_region:
release_mem_region(mem->start, (mem->end - mem->start) + 1);
err_release_data:
- kfree(dma_data);
-err_release_dev:
kfree(dev);
return ret;
@@ -946,7 +925,6 @@ err_release_dev:
static int davinci_mcasp_remove(struct platform_device *pdev)
{
struct snd_platform_data *pdata = pdev->dev.platform_data;
- struct davinci_pcm_dma_params *dma_data;
struct davinci_audio_dev *dev;
struct resource *mem;
@@ -959,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, (mem->end - mem->start) + 1);
- dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
- kfree(dma_data);
kfree(dev);
return 0;
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 554354c1cc2..9d179cc88f7 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -39,10 +39,15 @@ enum {
};
struct davinci_audio_dev {
+ /*
+ * dma_params must be first because rtd->dai->cpu_dai->private_data
+ * is cast to a pointer of an array of struct davinci_pcm_dma_params in
+ * davinci_pcm_open.
+ */
+ struct davinci_pcm_dma_params dma_params[2];
void __iomem *base;
int sample_rate;
struct clk *clk;
- struct davinci_pcm_dma_params *dma_params[2];
unsigned int codec_fmt;
/* McASP specific data */
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 2f7da49ed34..c73a915f233 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -126,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
{
struct davinci_runtime_data *prtd = substream->runtime->private_data;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
struct edmacc_param p_ram;
int ret;
- if (!dma_data)
- return -ENODEV;
-
- prtd->params = dma_data;
-
/* Request master DMA channel */
ret = edma_alloc_channel(prtd->params->channel,
davinci_pcm_dma_irq, substream,
@@ -244,6 +237,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct davinci_runtime_data *prtd;
int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data;
+ struct davinci_pcm_dma_params *params = &pa[substream->stream];
+ if (!params)
+ return -ENODEV;
snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware);
/* ensure that buffer size is a multiple of period size */
@@ -257,6 +255,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
return -ENOMEM;
spin_lock_init(&prtd->lock);
+ prtd->params = params;
runtime->private_data = prtd;
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 63d96253c73..8746606efc8 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -17,7 +17,6 @@
struct davinci_pcm_dma_params {
- char *name; /* stream identifier */
int channel; /* sync dma channel ID */
unsigned short acnt;
dma_addr_t dma_addr; /* device physical address for DMA */
diff --git a/sound/soc/imx/mxc-ssi.c b/sound/soc/imx/mxc-ssi.c
index 3806ff2c0cd..ccdefe60e75 100644
--- a/sound/soc/imx/mxc-ssi.c
+++ b/sound/soc/imx/mxc-ssi.c
@@ -397,14 +397,6 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai,
break;
}
- /* sync */
- if (!(fmt & SND_SOC_DAIFMT_ASYNC))
- scr |= SSI_SCR_SYN;
-
- /* tdm - only for stereo atm */
- if (fmt & SND_SOC_DAIFMT_TDM)
- scr |= SSI_SCR_NET;
-
if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
SSI1_STCR = stcr;
SSI1_SRCR = srcr;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 6375b4ea525..dcb3181bb34 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -138,7 +138,7 @@ config SND_PXA2XX_SOC_MIOA701
config SND_PXA2XX_SOC_IMOTE2
tristate "SoC Audio support for IMote 2"
- depends on SND_PXA2XX_SOC && MACH_INTELMOTE2
+ depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 && I2C
select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8940
help
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f79711b9fa5..8de6f9dec4a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -524,7 +524,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
/* connected jack or spk ? */
if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk ||
- widget->id == snd_soc_dapm_line)
+ (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources)))
return 1;
}
@@ -573,7 +573,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
return 1;
/* connected jack ? */
- if (widget->id == snd_soc_dapm_mic || widget->id == snd_soc_dapm_line)
+ if (widget->id == snd_soc_dapm_mic ||
+ (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks)))
return 1;
}
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index ab5a3ac2ac4..9efcfd08d74 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -898,6 +898,11 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
* build a feature control
*/
+static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
+{
+ return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
+}
+
static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
unsigned int ctl_mask, int control,
struct usb_audio_term *iterm, int unitid)
@@ -978,13 +983,13 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
*/
if (! mapped_name && ! (state->oterm.type >> 16)) {
if ((state->oterm.type & 0xff00) == 0x0100) {
- len = strlcat(kctl->id.name, " Capture", sizeof(kctl->id.name));
+ len = append_ctl_name(kctl, " Capture");
} else {
- len = strlcat(kctl->id.name + len, " Playback", sizeof(kctl->id.name));
+ len = append_ctl_name(kctl, " Playback");
}
}
- strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume",
- sizeof(kctl->id.name));
+ append_ctl_name(kctl, control == USB_FEATURE_MUTE ?
+ " Switch" : " Volume");
if (control == USB_FEATURE_VOLUME) {
kctl->tlv.c = mixer_vol_tlv;
kctl->vd[0].access |=
@@ -1143,7 +1148,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
if (! len)
len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
- strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name));
+ append_ctl_name(kctl, " Volume");
snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
@@ -1400,8 +1405,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
if (! len)
strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
}
- strlcat(kctl->id.name, " ", sizeof(kctl->id.name));
- strlcat(kctl->id.name, valinfo->suffix, sizeof(kctl->id.name));
+ append_ctl_name(kctl, " ");
+ append_ctl_name(kctl, valinfo->suffix);
snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
@@ -1610,9 +1615,9 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
if ((state->oterm.type & 0xff00) == 0x0100)
- strlcat(kctl->id.name, " Capture Source", sizeof(kctl->id.name));
+ append_ctl_name(kctl, " Capture Source");
else
- strlcat(kctl->id.name, " Playback Source", sizeof(kctl->id.name));
+ append_ctl_name(kctl, " Playback Source");
}
snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt
index 1c2ed3090cc..a7910099d6f 100644
--- a/tools/perf/Documentation/perf-timechart.txt
+++ b/tools/perf/Documentation/perf-timechart.txt
@@ -31,6 +31,9 @@ OPTIONS
-w::
--width=::
Select the width of the SVG file (default: 1000)
+-p::
+--power-only::
+ Only output the CPU power section of the diagram
SEE ALSO
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index b5f1953b614..5881943f0c3 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -728,7 +728,7 @@ $(BUILT_INS): perf$X
common-cmds.h: util/generate-cmdlist.sh command-list.txt
common-cmds.h: $(wildcard Documentation/perf-*.txt)
- $(QUIET_GEN)util/generate-cmdlist.sh > $@+ && mv $@+ $@
+ $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
$(QUIET_GEN)$(RM) $@ $@+ && \
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index a5a050af8e7..3eeef339c78 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -41,6 +41,7 @@ static int raw_samples = 0;
static int system_wide = 0;
static int profile_cpu = -1;
static pid_t target_pid = -1;
+static pid_t child_pid = -1;
static int inherit = 1;
static int force = 0;
static int append_file = 0;
@@ -184,6 +185,9 @@ static void sig_handler(int sig)
static void sig_atexit(void)
{
+ if (child_pid != -1)
+ kill(child_pid, SIGTERM);
+
if (signr == -1)
return;
@@ -610,6 +614,8 @@ static int __cmd_record(int argc, const char **argv)
exit(-1);
}
}
+
+ child_pid = pid;
}
if (realtime_prio) {
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e5f6ece65a1..3db31e7bf17 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -69,7 +69,8 @@ static int run_idx = 0;
static int run_count = 1;
static int inherit = 1;
static int scale = 1;
-static int target_pid = -1;
+static pid_t target_pid = -1;
+static pid_t child_pid = -1;
static int null_run = 0;
static int fd[MAX_NR_CPUS][MAX_COUNTERS];
@@ -285,6 +286,8 @@ static int run_perf_stat(int argc __used, const char **argv)
exit(-1);
}
+ child_pid = pid;
+
/*
* Wait for the child to be ready to exec.
*/
@@ -433,6 +436,9 @@ static void skip_signal(int signo)
static void sig_atexit(void)
{
+ if (child_pid != -1)
+ kill(child_pid, SIGTERM);
+
if (signr == -1)
return;
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 4405681b313..702d8fe58fb 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -46,6 +46,8 @@ static u64 turbo_frequency;
static u64 first_time, last_time;
+static int power_only;
+
static struct perf_header *header;
@@ -547,7 +549,7 @@ static void end_sample_processing(void)
u64 cpu;
struct power_event *pwr;
- for (cpu = 0; cpu < numcpus; cpu++) {
+ for (cpu = 0; cpu <= numcpus; cpu++) {
pwr = malloc(sizeof(struct power_event));
if (!pwr)
return;
@@ -871,7 +873,7 @@ static int determine_display_tasks(u64 threshold)
/* no exit marker, task kept running to the end */
if (p->end_time == 0)
p->end_time = last_time;
- if (p->total_time >= threshold)
+ if (p->total_time >= threshold && !power_only)
p->display = 1;
c = p->all;
@@ -882,7 +884,7 @@ static int determine_display_tasks(u64 threshold)
if (c->start_time == 1)
c->start_time = first_time;
- if (c->total_time >= threshold) {
+ if (c->total_time >= threshold && !power_only) {
c->display = 1;
count++;
}
@@ -1134,6 +1136,8 @@ static const struct option options[] = {
"output file name"),
OPT_INTEGER('w', "width", &svg_page_width,
"page width"),
+ OPT_BOOLEAN('p', "power-only", &power_only,
+ "output power data only"),
OPT_END()
};
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 1ca88896eee..37512e93623 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -782,6 +782,7 @@ static const char *skip_symbols[] = {
"exit_idle",
"mwait_idle",
"mwait_idle_with_hints",
+ "poll_idle",
"ppc64_runlatch_off",
"pseries_dedicated_idle_sleep",
NULL
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index e9d256e2f47..0c5e4f72f2b 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -219,10 +219,6 @@ remap:
more:
event = (event_t *)(buf + head);
- size = event->header.size;
- if (!size)
- size = 8;
-
if (head + event->header.size >= page_size * mmap_window) {
unsigned long shift = page_size * (head / page_size);
int res;
@@ -237,7 +233,6 @@ more:
size = event->header.size;
-
if (!size || process_event(event, offset, head) < 0) {
/*
@@ -290,7 +285,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
usage_with_options(annotate_usage, options);
}
-
setup_pager();
return __cmd_trace();
diff --git a/tools/perf/design.txt b/tools/perf/design.txt
index f1946d107b1..fdd42a824c9 100644
--- a/tools/perf/design.txt
+++ b/tools/perf/design.txt
@@ -455,3 +455,6 @@ will need at least this:
If your architecture does have hardware capabilities, you can override the
weak stub hw_perf_event_init() to register hardware counters.
+
+Architectures that have d-cache aliassing issues, such as Sparc and ARM,
+should select PERF_USE_VMALLOC in order to avoid these for perf mmap().
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index a778fd0f4ae..856655d8b0b 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -28,7 +28,7 @@ static u64 turbo_frequency, max_freq;
int svg_page_width = 1000;
-#define MIN_TEXT_SIZE 0.001
+#define MIN_TEXT_SIZE 0.01
static u64 total_height;
static FILE *svgfile;
@@ -217,6 +217,18 @@ static char *cpu_model(void)
}
fclose(file);
}
+
+ /* CPU type */
+ file = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", "r");
+ if (file) {
+ while (fgets(buf, 255, file)) {
+ unsigned int freq;
+ freq = strtoull(buf, NULL, 10);
+ if (freq > max_freq)
+ max_freq = freq;
+ }
+ fclose(file);
+ }
return cpu_m;
}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 559fb06210f..47ea0609a76 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -324,8 +324,7 @@ static inline int elf_sym__is_function(const GElf_Sym *sym)
{
return elf_sym__type(sym) == STT_FUNC &&
sym->st_name != 0 &&
- sym->st_shndx != SHN_UNDEF &&
- sym->st_size != 0;
+ sym->st_shndx != SHN_UNDEF;
}
static inline int elf_sym__is_label(const GElf_Sym *sym)
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index f6a8437141c..55b41b9e383 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -1968,10 +1968,11 @@ static const struct flag flags[] = {
{ "NET_TX_SOFTIRQ", 2 },
{ "NET_RX_SOFTIRQ", 3 },
{ "BLOCK_SOFTIRQ", 4 },
- { "TASKLET_SOFTIRQ", 5 },
- { "SCHED_SOFTIRQ", 6 },
- { "HRTIMER_SOFTIRQ", 7 },
- { "RCU_SOFTIRQ", 8 },
+ { "BLOCK_IOPOLL_SOFTIRQ", 5 },
+ { "TASKLET_SOFTIRQ", 6 },
+ { "SCHED_SOFTIRQ", 7 },
+ { "HRTIMER_SOFTIRQ", 8 },
+ { "RCU_SOFTIRQ", 9 },
{ "HRTIMER_NORESTART", 0 },
{ "HRTIMER_RESTART", 1 },
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index b5e7e3f1183..b7c78a403dc 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -850,6 +850,19 @@ static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
}
+static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
+ struct mm_struct *mm,
+ unsigned long address,
+ pte_t pte)
+{
+ struct kvm *kvm = mmu_notifier_to_kvm(mn);
+
+ spin_lock(&kvm->mmu_lock);
+ kvm->mmu_notifier_seq++;
+ kvm_set_spte_hva(kvm, address, pte);
+ spin_unlock(&kvm->mmu_lock);
+}
+
static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
struct mm_struct *mm,
unsigned long start,
@@ -929,6 +942,7 @@ static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
.invalidate_range_start = kvm_mmu_notifier_invalidate_range_start,
.invalidate_range_end = kvm_mmu_notifier_invalidate_range_end,
.clear_flush_young = kvm_mmu_notifier_clear_flush_young,
+ .change_pte = kvm_mmu_notifier_change_pte,
.release = kvm_mmu_notifier_release,
};
#endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */
@@ -2625,7 +2639,7 @@ static int vcpu_stat_get(void *_offset, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n");
-static struct file_operations *stat_fops[] = {
+static const struct file_operations *stat_fops[] = {
[KVM_STAT_VCPU] = &vcpu_stat_fops,
[KVM_STAT_VM] = &vm_stat_fops,
};