From 844657112919393e1a166721fd8bed58d914c900 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Mon, 27 Apr 2009 08:29:12 -0400 Subject: [PATCH] --- yaml --- r: 154873 b: refs/heads/master c: 90eab5e09de20e8d991bbb11f6edfb573f906352 h: refs/heads/master i: 154871: 8c8aca240249bf1d05127d56ea98f2265fa75624 v: v3 --- [refs] | 2 +- trunk/.gitignore | 1 - trunk/Documentation/block/data-integrity.txt | 4 +- trunk/Documentation/cgroups/cpusets.txt | 12 - trunk/Documentation/device-mapper/dm-log.txt | 54 - .../device-mapper/dm-queue-length.txt | 39 - .../device-mapper/dm-service-time.txt | 91 -- trunk/Documentation/filesystems/Locking | 43 +- trunk/Documentation/gcov.txt | 25 +- trunk/Documentation/kernel-parameters.txt | 19 +- trunk/Documentation/kmemleak.txt | 23 +- trunk/Documentation/laptops/thinkpad-acpi.txt | 47 +- trunk/Documentation/leds-lp3944.txt | 50 - .../powerpc/booting-without-of.txt | 1168 +++++++++++++++- .../powerpc/dts-bindings/4xx/emac.txt | 148 --- .../powerpc/dts-bindings/gpio/gpio.txt | 50 - .../powerpc/dts-bindings/gpio/led.txt | 17 +- .../powerpc/dts-bindings/gpio/mdio.txt | 19 - .../powerpc/dts-bindings/marvell.txt | 521 -------- .../powerpc/dts-bindings/phy.txt | 25 - .../powerpc/dts-bindings/spi-bus.txt | 57 - .../powerpc/dts-bindings/usb-ehci.txt | 25 - .../powerpc/dts-bindings/xilinx.txt | 295 ---- .../sound/alsa/HD-Audio-Models.txt | 1 - trunk/Documentation/spi/spidev_test.c | 10 +- trunk/Documentation/video4linux/CARDLIST.cx88 | 6 +- .../Documentation/video4linux/CARDLIST.em28xx | 1 - .../video4linux/v4l2-framework.txt | 24 - trunk/Documentation/watchdog/hpwdt.txt | 19 +- trunk/MAINTAINERS | 93 +- trunk/Makefile | 11 +- trunk/arch/alpha/include/asm/percpu.h | 6 +- trunk/arch/arm/Kconfig.debug | 8 + trunk/arch/arm/configs/s3c2410_defconfig | 2 +- trunk/arch/arm/configs/s3c6400_defconfig | 1 + trunk/arch/arm/configs/tct_hammer_defconfig | 1 + trunk/arch/arm/include/asm/page.h | 2 +- trunk/arch/arm/kernel/irq.c | 24 +- trunk/arch/arm/kernel/vmlinux.lds.S | 15 +- trunk/arch/arm/mach-at91/board-sam9g20ek.c | 54 - trunk/arch/arm/mach-at91/board-sam9rlek.c | 6 +- trunk/arch/arm/mach-omap1/board-nokia770.c | 3 +- trunk/arch/arm/mach-omap1/mailbox.c | 2 +- .../arm/mach-omap2/board-rx51-peripherals.c | 1 - trunk/arch/arm/mach-omap2/gpmc-onenand.c | 21 +- trunk/arch/arm/mach-omap2/id.c | 22 - trunk/arch/arm/mach-omap2/mailbox.c | 6 +- trunk/arch/arm/mach-omap2/mmc-twl4030.c | 13 +- trunk/arch/arm/mach-s3c2440/mach-mini2440.c | 3 +- trunk/arch/arm/mach-s3c2442/mach-gta02.c | 3 +- trunk/arch/arm/plat-omap/dma.c | 13 - trunk/arch/arm/plat-omap/gpio.c | 1 - trunk/arch/arm/plat-omap/include/mach/cpu.h | 22 +- trunk/arch/arm/plat-omap/include/mach/dma.h | 15 - trunk/arch/arm/plat-omap/include/mach/io.h | 2 +- trunk/arch/arm/plat-omap/iommu.c | 2 +- trunk/arch/arm/plat-omap/sram.c | 7 +- trunk/arch/arm/plat-s3c/Makefile | 2 +- trunk/arch/arm/plat-s3c/include/plat/devs.h | 1 - trunk/arch/arm/plat-s3c24xx/Makefile | 2 +- .../arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c | 3 +- .../arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c | 3 +- trunk/arch/cris/arch-v10/kernel/dma.c | 4 +- trunk/arch/cris/arch-v32/drivers/cryptocop.c | 4 +- trunk/arch/cris/arch-v32/kernel/irq.c | 2 +- trunk/arch/cris/arch-v32/lib/Makefile | 2 +- trunk/arch/cris/arch-v32/lib/strcmp.S | 21 - .../cris/include/arch-v32/arch/spinlock.h | 6 +- trunk/arch/cris/include/asm/string.h | 6 - trunk/arch/frv/Kconfig | 1 - trunk/arch/frv/include/asm/atomic.h | 68 +- trunk/arch/frv/include/asm/perf_counter.h | 17 - trunk/arch/frv/include/asm/system.h | 2 - trunk/arch/frv/include/asm/unistd.h | 4 +- trunk/arch/frv/kernel/entry.S | 2 - trunk/arch/frv/kernel/frv_ksyms.c | 4 - trunk/arch/frv/lib/Makefile | 4 +- trunk/arch/frv/lib/atomic-ops.S | 3 +- trunk/arch/frv/lib/atomic64-ops.S | 162 --- trunk/arch/frv/lib/perf_counter.c | 19 - trunk/arch/h8300/Kconfig.cpu | 8 +- trunk/arch/ia64/kernel/acpi-processor.c | 12 - trunk/arch/ia64/kernel/esi.c | 2 +- trunk/arch/ia64/kernel/perfmon.c | 2 +- trunk/arch/ia64/kernel/salinfo.c | 2 +- trunk/arch/ia64/kvm/kvm_lib.c | 6 - trunk/arch/ia64/kvm/process.c | 6 +- trunk/arch/ia64/kvm/vcpu.c | 2 +- trunk/arch/ia64/kvm/vtlb.c | 4 +- trunk/arch/ia64/sn/kernel/io_common.c | 3 +- trunk/arch/mips/Kconfig | 42 +- trunk/arch/mips/Makefile | 7 - trunk/arch/mips/ar7/Makefile | 10 - trunk/arch/mips/ar7/clock.c | 440 ------ trunk/arch/mips/ar7/gpio.c | 48 - trunk/arch/mips/ar7/irq.c | 176 --- trunk/arch/mips/ar7/memory.c | 72 - trunk/arch/mips/ar7/platform.c | 555 -------- trunk/arch/mips/ar7/prom.c | 297 ----- trunk/arch/mips/ar7/setup.c | 94 -- trunk/arch/mips/ar7/time.c | 30 - trunk/arch/mips/cavium-octeon/Makefile | 4 + trunk/arch/mips/cavium-octeon/dma-octeon.c | 2 +- .../{pci/msi-octeon.c => cavium-octeon/msi.c} | 56 +- trunk/arch/mips/cavium-octeon/octeon-irq.c | 61 +- trunk/arch/mips/cavium-octeon/octeon_boot.h | 70 - trunk/arch/mips/cavium-octeon/pci-common.c | 137 ++ .../pci-common.h} | 30 +- .../{pci/pci-octeon.c => cavium-octeon/pci.c} | 147 +- .../pcie-octeon.c => cavium-octeon/pcie.c} | 37 +- trunk/arch/mips/cavium-octeon/setup.c | 1 - trunk/arch/mips/cavium-octeon/smp.c | 234 +--- trunk/arch/mips/cobalt/buttons.c | 2 +- trunk/arch/mips/cobalt/lcd.c | 2 +- trunk/arch/mips/cobalt/led.c | 2 +- trunk/arch/mips/cobalt/mtd.c | 2 +- trunk/arch/mips/cobalt/rtc.c | 2 +- trunk/arch/mips/cobalt/serial.c | 2 +- trunk/arch/mips/cobalt/time.c | 2 +- trunk/arch/mips/configs/ar7_defconfig | 1182 ----------------- trunk/arch/mips/gt64120/wrppmc/serial.c | 2 +- trunk/arch/mips/include/asm/amon.h | 7 - trunk/arch/mips/include/asm/bug.h | 1 - trunk/arch/mips/include/asm/bugs.h | 1 - trunk/arch/mips/include/asm/ds1287.h | 2 +- trunk/arch/mips/include/asm/elf.h | 4 - trunk/arch/mips/include/asm/gcmpregs.h | 2 - trunk/arch/mips/include/asm/gic.h | 6 - trunk/arch/mips/include/asm/irq.h | 1 - trunk/arch/mips/include/asm/irq_gt641xx.h | 2 +- trunk/arch/mips/include/asm/mach-ar7/ar7.h | 178 --- trunk/arch/mips/include/asm/mach-ar7/gpio.h | 110 -- trunk/arch/mips/include/asm/mach-ar7/irq.h | 16 - trunk/arch/mips/include/asm/mach-ar7/prom.h | 25 - trunk/arch/mips/include/asm/mach-ar7/spaces.h | 22 - trunk/arch/mips/include/asm/mach-ar7/war.h | 25 - trunk/arch/mips/include/asm/mach-cobalt/irq.h | 2 +- .../include/asm/mach-cobalt/mach-gt64120.h | 2 +- trunk/arch/mips/include/asm/mmu_context.h | 1 - trunk/arch/mips/include/asm/page.h | 9 +- trunk/arch/mips/include/asm/reg.h | 2 +- trunk/arch/mips/include/asm/smp-ops.h | 4 - trunk/arch/mips/include/asm/smp.h | 20 - trunk/arch/mips/include/asm/sn/addrs.h | 1 - trunk/arch/mips/include/asm/swab.h | 8 +- trunk/arch/mips/include/asm/unistd.h | 18 +- trunk/arch/mips/include/asm/vr41xx/capcella.h | 2 +- trunk/arch/mips/include/asm/vr41xx/giu.h | 22 +- trunk/arch/mips/include/asm/vr41xx/irq.h | 2 +- trunk/arch/mips/include/asm/vr41xx/mpc30x.h | 2 +- trunk/arch/mips/include/asm/vr41xx/pci.h | 2 +- trunk/arch/mips/include/asm/vr41xx/siu.h | 2 +- trunk/arch/mips/include/asm/vr41xx/tb0219.h | 2 +- trunk/arch/mips/include/asm/vr41xx/tb0226.h | 2 +- trunk/arch/mips/include/asm/vr41xx/vr41xx.h | 2 +- trunk/arch/mips/jazz/irq.c | 1 - trunk/arch/mips/kernel/binfmt_elfo32.c | 20 +- trunk/arch/mips/kernel/cevt-bcm1480.c | 1 - trunk/arch/mips/kernel/cevt-ds1287.c | 2 +- trunk/arch/mips/kernel/cevt-gt641xx.c | 2 +- trunk/arch/mips/kernel/cevt-r4k.c | 1 - trunk/arch/mips/kernel/cevt-sb1250.c | 1 - trunk/arch/mips/kernel/cevt-smtc.c | 1 - trunk/arch/mips/kernel/cpu-probe.c | 1 - trunk/arch/mips/kernel/csrc-ioasic.c | 2 +- trunk/arch/mips/kernel/i8253.c | 1 - trunk/arch/mips/kernel/irq-gic.c | 20 +- trunk/arch/mips/kernel/irq-gt641xx.c | 2 +- trunk/arch/mips/kernel/kgdb.c | 1 - trunk/arch/mips/kernel/process.c | 13 +- trunk/arch/mips/kernel/scall32-o32.S | 2 - trunk/arch/mips/kernel/scall64-64.S | 2 - trunk/arch/mips/kernel/scall64-n32.S | 2 - trunk/arch/mips/kernel/scall64-o32.S | 2 - trunk/arch/mips/kernel/smp-cmp.c | 67 +- trunk/arch/mips/kernel/smp-up.c | 16 - trunk/arch/mips/kernel/smp.c | 18 +- trunk/arch/mips/kernel/smtc.c | 1 - trunk/arch/mips/kernel/sync-r4k.c | 31 +- trunk/arch/mips/kernel/topology.c | 5 +- trunk/arch/mips/kernel/vpe.c | 2 +- trunk/arch/mips/mipssim/sim_time.c | 1 - trunk/arch/mips/mm/c-octeon.c | 1 - trunk/arch/mips/mm/c-r3k.c | 1 - trunk/arch/mips/mm/c-r4k.c | 1 - trunk/arch/mips/mm/c-tx39.c | 1 - trunk/arch/mips/mm/highmem.c | 1 - trunk/arch/mips/mm/init.c | 1 - trunk/arch/mips/mm/page.c | 1 - trunk/arch/mips/mm/tlb-r3k.c | 1 - trunk/arch/mips/mm/tlb-r4k.c | 1 - trunk/arch/mips/mm/tlb-r8k.c | 1 - trunk/arch/mips/mm/tlbex.c | 1 - trunk/arch/mips/mti-malta/malta-init.c | 14 +- trunk/arch/mips/mti-malta/malta-int.c | 90 +- trunk/arch/mips/mti-malta/malta-reset.c | 3 + trunk/arch/mips/pci/Makefile | 5 - trunk/arch/mips/pci/fixup-capcella.c | 2 +- trunk/arch/mips/pci/fixup-mpc30x.c | 2 +- trunk/arch/mips/pci/fixup-tb0219.c | 2 +- trunk/arch/mips/pci/fixup-tb0226.c | 2 +- trunk/arch/mips/pci/fixup-tb0287.c | 2 +- trunk/arch/mips/pci/ops-vr41xx.c | 6 +- trunk/arch/mips/pci/pci-ip27.c | 1 - trunk/arch/mips/pci/pci-vr41xx.c | 6 +- trunk/arch/mips/pci/pci-vr41xx.h | 4 +- trunk/arch/mips/pmc-sierra/yosemite/smp.c | 1 - trunk/arch/mips/power/hibernate.S | 9 + trunk/arch/mips/sgi-ip27/ip27-init.c | 1 - trunk/arch/mips/sgi-ip27/ip27-irq.c | 1 - trunk/arch/mips/sgi-ip27/ip27-timer.c | 1 - trunk/arch/mips/sgi-ip27/ip27-xtalk.c | 1 - trunk/arch/mips/sibyte/bcm1480/irq.c | 1 - trunk/arch/mips/sibyte/common/cfe_console.c | 7 +- trunk/arch/mips/sni/time.c | 1 - trunk/arch/mips/vr41xx/casio-e55/setup.c | 2 +- trunk/arch/mips/vr41xx/common/bcu.c | 8 +- trunk/arch/mips/vr41xx/common/cmu.c | 8 +- trunk/arch/mips/vr41xx/common/giu.c | 2 +- trunk/arch/mips/vr41xx/common/icu.c | 8 +- trunk/arch/mips/vr41xx/common/init.c | 2 +- trunk/arch/mips/vr41xx/common/irq.c | 2 +- trunk/arch/mips/vr41xx/common/pmu.c | 2 +- trunk/arch/mips/vr41xx/common/rtc.c | 2 +- trunk/arch/mips/vr41xx/common/siu.c | 2 +- trunk/arch/mips/vr41xx/common/type.c | 2 +- trunk/arch/mips/vr41xx/ibm-workpad/setup.c | 2 +- trunk/arch/mn10300/include/asm/unistd.h | 4 +- trunk/arch/mn10300/kernel/entry.S | 2 - trunk/arch/mn10300/kernel/vmlinux.lds.S | 2 +- trunk/arch/parisc/include/asm/unistd.h | 4 +- trunk/arch/parisc/kernel/syscall_table.S | 2 + trunk/arch/powerpc/Kconfig | 1 + trunk/arch/powerpc/boot/.gitignore | 10 - trunk/arch/powerpc/boot/dts/amigaone.dts | 4 +- trunk/arch/powerpc/boot/dts/mpc8569mds.dts | 1 - trunk/arch/powerpc/include/asm/cpm1.h | 2 + trunk/arch/powerpc/include/asm/dma-mapping.h | 24 +- trunk/arch/powerpc/include/asm/highmem.h | 57 +- trunk/arch/powerpc/include/asm/hw_irq.h | 20 +- trunk/arch/powerpc/include/asm/perf_counter.h | 2 - .../arch/powerpc/include/asm/pte-hash64-64k.h | 3 +- trunk/arch/powerpc/include/asm/rtas.h | 5 +- trunk/arch/powerpc/kernel/entry_32.S | 127 +- trunk/arch/powerpc/kernel/head_32.S | 17 +- trunk/arch/powerpc/kernel/of_device.c | 2 +- trunk/arch/powerpc/kernel/process.c | 2 +- trunk/arch/powerpc/kernel/rtas.c | 69 +- trunk/arch/powerpc/kernel/setup_32.c | 2 - trunk/arch/powerpc/kernel/smp.c | 3 +- trunk/arch/powerpc/kernel/udbg_16550.c | 2 +- trunk/arch/powerpc/mm/Makefile | 1 - trunk/arch/powerpc/mm/highmem.c | 77 -- trunk/arch/powerpc/platforms/44x/warp.c | 44 +- .../arch/powerpc/platforms/85xx/mpc85xx_mds.c | 1 - trunk/arch/powerpc/platforms/85xx/smp.c | 9 +- trunk/arch/powerpc/platforms/85xx/socrates.c | 6 +- .../arch/powerpc/platforms/85xx/xes_mpc85xx.c | 1 + trunk/arch/powerpc/platforms/cell/smp.c | 30 +- trunk/arch/powerpc/platforms/chrp/smp.c | 33 +- trunk/arch/powerpc/platforms/pasemi/setup.c | 15 +- trunk/arch/powerpc/platforms/powermac/setup.c | 41 +- trunk/arch/powerpc/platforms/powermac/smp.c | 166 +-- trunk/arch/powerpc/platforms/pseries/smp.c | 30 +- trunk/arch/powerpc/sysdev/mpic.c | 34 +- trunk/arch/powerpc/sysdev/qe_lib/qe.c | 9 +- trunk/arch/s390/include/asm/kvm_host.h | 4 +- trunk/arch/s390/kvm/kvm-s390.c | 23 +- trunk/arch/s390/kvm/priv.c | 2 +- trunk/arch/sh/Kconfig | 12 +- trunk/arch/sh/Kconfig.debug | 4 + trunk/arch/sh/boards/mach-se/7206/io.c | 2 +- trunk/arch/sh/boards/mach-se/7724/setup.c | 110 +- trunk/arch/sh/configs/migor_defconfig | 53 +- trunk/arch/sh/configs/se7724_defconfig | 25 +- trunk/arch/sh/include/asm/dma-mapping.h | 12 +- trunk/arch/sh/include/asm/perf_counter.h | 2 +- trunk/arch/sh/include/asm/syscall_32.h | 1 - trunk/arch/sh/include/asm/system.h | 1 - trunk/arch/sh/include/mach-se/mach/se7724.h | 5 - trunk/arch/sh/kernel/cpu/sh4a/Makefile | 6 +- trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 29 +- trunk/arch/sh/kernel/idle.c | 23 +- trunk/arch/sh/mm/fault_32.c | 61 +- trunk/arch/sh/mm/init.c | 4 +- trunk/arch/sh/mm/tlbflush_64.c | 15 +- trunk/arch/sparc/boot/Makefile | 6 +- trunk/arch/sparc/boot/piggyback_32.c | 4 +- trunk/arch/sparc/boot/piggyback_64.c | 1 - trunk/arch/sparc/kernel/irq_64.c | 45 +- trunk/arch/um/drivers/slip_kern.c | 1 + trunk/arch/um/drivers/slirp_kern.c | 1 + trunk/arch/um/include/asm/dma-mapping.h | 4 +- trunk/arch/x86/Kconfig | 15 +- trunk/arch/x86/include/asm/acpi.h | 1 - trunk/arch/x86/include/asm/boot.h | 6 +- trunk/arch/x86/include/asm/pci.h | 2 +- trunk/arch/x86/include/asm/pci_x86.h | 5 +- trunk/arch/x86/include/asm/percpu.h | 10 - trunk/arch/x86/include/asm/perf_counter.h | 3 - trunk/arch/x86/include/asm/proto.h | 11 +- trunk/arch/x86/kernel/acpi/boot.c | 80 +- trunk/arch/x86/kernel/acpi/cstate.c | 16 +- trunk/arch/x86/kernel/acpi/processor.c | 13 - trunk/arch/x86/kernel/apic/io_apic.c | 6 - trunk/arch/x86/kernel/cpu/amd.c | 4 +- trunk/arch/x86/kernel/cpu/common.c | 3 + trunk/arch/x86/kernel/cpu/mcheck/mce.c | 4 +- trunk/arch/x86/kernel/cpu/perf_counter.c | 22 +- trunk/arch/x86/kernel/dumpstack.c | 1 - trunk/arch/x86/kernel/e820.c | 16 +- trunk/arch/x86/kernel/pci-dma.c | 2 +- trunk/arch/x86/kernel/setup.c | 16 - trunk/arch/x86/kernel/setup_percpu.c | 219 +-- trunk/arch/x86/kernel/tlb_uv.c | 9 +- trunk/arch/x86/kernel/traps.c | 3 - trunk/arch/x86/kvm/mmu.c | 6 +- trunk/arch/x86/kvm/paging_tmpl.h | 2 +- trunk/arch/x86/kvm/vmx.c | 15 - trunk/arch/x86/kvm/x86.c | 1 - trunk/arch/x86/kvm/x86_emulate.c | 2 +- trunk/arch/x86/lib/delay.c | 3 - trunk/arch/x86/mm/init.c | 17 + trunk/arch/x86/mm/init_64.c | 2 - trunk/arch/x86/mm/pageattr.c | 65 +- trunk/arch/x86/pci/acpi.c | 2 +- trunk/arch/x86/pci/amd_bus.c | 2 +- trunk/arch/x86/pci/common.c | 4 +- trunk/arch/x86/pci/mmconfig-shared.c | 65 +- trunk/arch/x86/power/cpu.c | 2 +- trunk/block/Makefile | 2 +- trunk/block/blk-core.c | 14 +- trunk/block/blk-merge.c | 6 - trunk/block/bsg.c | 5 +- trunk/block/cfq-iosched.c | 176 ++- trunk/block/cmd-filter.c | 233 ++++ trunk/block/elevator.c | 8 - trunk/block/scsi_ioctl.c | 43 +- trunk/drivers/acpi/ac.c | 20 +- trunk/drivers/acpi/battery.c | 34 +- trunk/drivers/acpi/blacklist.c | 16 - trunk/drivers/acpi/bus.c | 91 +- trunk/drivers/acpi/glue.c | 40 + trunk/drivers/acpi/osl.c | 25 +- trunk/drivers/acpi/pci_bind.c | 313 ++++- trunk/drivers/acpi/pci_irq.c | 17 +- trunk/drivers/acpi/pci_root.c | 297 ++--- trunk/drivers/acpi/power.c | 28 +- trunk/drivers/acpi/processor_core.c | 45 +- trunk/drivers/acpi/processor_idle.c | 47 +- trunk/drivers/acpi/scan.c | 69 +- trunk/drivers/acpi/video.c | 61 +- trunk/drivers/acpi/video_detect.c | 9 +- trunk/drivers/ata/Kconfig | 8 - trunk/drivers/ata/Makefile | 1 - trunk/drivers/ata/libata-core.c | 25 +- trunk/drivers/ata/pata_at91.c | 361 ----- trunk/drivers/ata/sata_fsl.c | 35 - trunk/drivers/block/cciss.c | 15 +- trunk/drivers/block/cciss_cmd.h | 1 - trunk/drivers/block/floppy.c | 5 +- trunk/drivers/char/Kconfig | 4 + trunk/drivers/char/Makefile | 1 + trunk/drivers/char/bsr.c | 42 +- trunk/drivers/char/mxser.c | 2 + trunk/drivers/char/nozomi.c | 2 + trunk/drivers/char/synclink_gt.c | 72 +- trunk/drivers/char/tb0219.c | 4 +- trunk/drivers/char/tty_ldisc.c | 15 +- trunk/drivers/char/tty_port.c | 2 +- trunk/drivers/char/vr41xx_giu.c | 680 ++++++++++ trunk/drivers/clocksource/sh_tmu.c | 2 +- trunk/drivers/dma/txx9dmac.c | 20 +- trunk/drivers/edac/amd64_edac.c | 25 +- trunk/drivers/edac/amd64_edac.h | 2 +- trunk/drivers/edac/edac_core.h | 4 - trunk/drivers/edac/edac_mc_sysfs.c | 4 +- trunk/drivers/edac/mpc85xx_edac.c | 6 - trunk/drivers/edac/mpc85xx_edac.h | 1 - trunk/drivers/gpio/Kconfig | 6 - trunk/drivers/gpio/Makefile | 1 - trunk/drivers/gpio/pl061.c | 20 +- trunk/drivers/gpio/vr41xx_giu.c | 586 -------- trunk/drivers/gpu/drm/Kconfig | 1 - trunk/drivers/gpu/drm/Makefile | 2 +- trunk/drivers/gpu/drm/drm_edid.c | 12 +- trunk/drivers/gpu/drm/i915/Makefile | 2 - trunk/drivers/gpu/drm/i915/dvo.h | 4 +- trunk/drivers/gpu/drm/i915/dvo_ch7017.c | 20 +- trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c | 25 +- trunk/drivers/gpu/drm/i915/dvo_ivch.c | 21 +- trunk/drivers/gpu/drm/i915/dvo_sil164.c | 25 +- trunk/drivers/gpu/drm/i915/dvo_tfp410.c | 25 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 4 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 12 - trunk/drivers/gpu/drm/i915/i915_gem.c | 19 +- trunk/drivers/gpu/drm/i915/i915_gem_debug.c | 6 +- trunk/drivers/gpu/drm/i915/i915_gem_tiling.c | 2 - trunk/drivers/gpu/drm/i915/i915_irq.c | 12 +- trunk/drivers/gpu/drm/i915/i915_opregion.c | 2 +- trunk/drivers/gpu/drm/i915/i915_reg.h | 29 - trunk/drivers/gpu/drm/i915/i915_suspend.c | 34 +- trunk/drivers/gpu/drm/i915/intel_bios.c | 12 +- trunk/drivers/gpu/drm/i915/intel_display.c | 199 +-- trunk/drivers/gpu/drm/i915/intel_dp.c | 1153 ---------------- trunk/drivers/gpu/drm/i915/intel_dp.h | 144 -- trunk/drivers/gpu/drm/i915/intel_dp_i2c.c | 272 ---- trunk/drivers/gpu/drm/i915/intel_drv.h | 17 +- trunk/drivers/gpu/drm/i915/intel_dvo.c | 16 +- trunk/drivers/gpu/drm/i915/intel_hdmi.c | 35 +- trunk/drivers/gpu/drm/i915/intel_i2c.c | 16 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 344 +---- trunk/drivers/gpu/drm/i915/intel_modes.c | 14 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 72 +- trunk/drivers/gpu/drm/i915/intel_tv.c | 53 +- trunk/drivers/gpu/drm/radeon/radeon_device.c | 22 +- trunk/drivers/gpu/drm/radeon/radeon_drv.c | 2 +- trunk/drivers/gpu/drm/radeon/radeon_fb.c | 33 +- trunk/drivers/gpu/drm/radeon/radeon_object.c | 30 + trunk/drivers/gpu/drm/ttm/ttm_bo_util.c | 1 + trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c | 1 + trunk/drivers/gpu/drm/ttm/ttm_tt.c | 1 + trunk/drivers/i2c/busses/Kconfig | 10 - trunk/drivers/i2c/busses/Makefile | 1 - trunk/drivers/i2c/busses/i2c-designware.c | 624 --------- trunk/drivers/ide/cmd64x.c | 3 +- trunk/drivers/ide/cs5520.c | 1 - trunk/drivers/ide/ide-acpi.c | 37 +- trunk/drivers/ide/ide-cd.c | 24 +- trunk/drivers/ide/ide-devsets.c | 2 +- trunk/drivers/ide/ide-dma.c | 21 + trunk/drivers/ide/ide-eh.c | 2 +- trunk/drivers/ide/ide-floppy.c | 2 +- trunk/drivers/ide/ide-io.c | 68 +- trunk/drivers/ide/ide-ioctls.c | 3 +- trunk/drivers/ide/ide-iops.c | 4 +- trunk/drivers/ide/ide-pm.c | 30 +- trunk/drivers/ide/ide-probe.c | 23 +- trunk/drivers/infiniband/core/addr.c | 4 +- trunk/drivers/infiniband/core/cma.c | 4 +- trunk/drivers/infiniband/hw/ehca/ehca_hca.c | 2 +- trunk/drivers/infiniband/hw/ehca/ehca_main.c | 20 +- trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c | 508 +------ trunk/drivers/infiniband/hw/ehca/ehca_mrmw.h | 13 +- trunk/drivers/infiniband/hw/mthca/mthca_mr.c | 13 +- trunk/drivers/infiniband/hw/nes/nes_cm.c | 8 +- trunk/drivers/infiniband/hw/nes/nes_verbs.c | 2 +- trunk/drivers/input/misc/cobalt_btns.c | 4 +- trunk/drivers/leds/Kconfig | 14 +- trunk/drivers/leds/Makefile | 1 - trunk/drivers/leds/leds-alix2.c | 7 +- trunk/drivers/leds/leds-bd2802.c | 96 +- trunk/drivers/leds/leds-cobalt-raq.c | 2 +- trunk/drivers/leds/leds-gpio.c | 22 +- trunk/drivers/leds/leds-lp3944.c | 466 ------- trunk/drivers/leds/leds-pca9532.c | 58 +- trunk/drivers/lguest/lg.h | 2 +- trunk/drivers/lguest/lguest_user.c | 4 +- trunk/drivers/macintosh/macio_asic.c | 11 - trunk/drivers/md/Kconfig | 30 - trunk/drivers/md/Makefile | 5 - trunk/drivers/md/dm-crypt.c | 19 +- trunk/drivers/md/dm-delay.c | 26 +- trunk/drivers/md/dm-exception-store.c | 9 +- trunk/drivers/md/dm-exception-store.h | 2 +- trunk/drivers/md/dm-io.c | 14 +- trunk/drivers/md/dm-ioctl.c | 27 +- trunk/drivers/md/dm-linear.c | 15 +- trunk/drivers/md/dm-log-userspace-base.c | 696 ---------- trunk/drivers/md/dm-log-userspace-transfer.c | 276 ---- trunk/drivers/md/dm-log-userspace-transfer.h | 18 - trunk/drivers/md/dm-log.c | 9 +- trunk/drivers/md/dm-mpath.c | 334 ++--- trunk/drivers/md/dm-path-selector.h | 8 +- trunk/drivers/md/dm-queue-length.c | 263 ---- trunk/drivers/md/dm-raid1.c | 17 +- trunk/drivers/md/dm-region-hash.c | 2 +- trunk/drivers/md/dm-round-robin.c | 2 +- trunk/drivers/md/dm-service-time.c | 339 ----- trunk/drivers/md/dm-snap-persistent.c | 2 +- trunk/drivers/md/dm-snap.c | 11 - trunk/drivers/md/dm-stripe.c | 33 +- trunk/drivers/md/dm-sysfs.c | 9 - trunk/drivers/md/dm-table.c | 465 ++----- trunk/drivers/md/dm.c | 1137 ++-------------- trunk/drivers/md/dm.h | 35 +- trunk/drivers/md/linear.c | 4 +- trunk/drivers/md/md.c | 56 +- trunk/drivers/md/multipath.c | 7 +- trunk/drivers/md/raid0.c | 9 +- trunk/drivers/md/raid1.c | 9 +- trunk/drivers/md/raid10.c | 19 +- trunk/drivers/md/raid5.c | 28 +- trunk/drivers/media/common/ir-keymaps.c | 23 - trunk/drivers/media/dvb/frontends/stv0900.h | 7 +- .../media/dvb/frontends/stv0900_core.c | 100 +- .../media/dvb/frontends/stv0900_priv.h | 2 - trunk/drivers/media/dvb/frontends/stv090x.c | 11 +- trunk/drivers/media/dvb/frontends/tda10048.c | 1 - trunk/drivers/media/dvb/siano/smscoreapi.c | 4 +- trunk/drivers/media/radio/radio-tea5764.c | 4 +- trunk/drivers/media/video/Kconfig | 6 +- .../drivers/media/video/cx18/cx18-controls.c | 2 - .../media/video/cx231xx/cx231xx-avcore.c | 19 +- .../media/video/cx231xx/cx231xx-video.c | 26 +- trunk/drivers/media/video/cx231xx/cx231xx.h | 3 + trunk/drivers/media/video/cx2341x.c | 2 - .../drivers/media/video/cx23885/cx23885-dvb.c | 33 +- .../media/video/cx23885/cx23885-video.c | 11 +- trunk/drivers/media/video/cx88/cx88-cards.c | 94 +- trunk/drivers/media/video/cx88/cx88-video.c | 11 +- .../drivers/media/video/em28xx/em28xx-cards.c | 56 - trunk/drivers/media/video/em28xx/em28xx-dvb.c | 1 - .../drivers/media/video/em28xx/em28xx-video.c | 38 +- trunk/drivers/media/video/em28xx/em28xx.h | 1 - trunk/drivers/media/video/gspca/gspca.c | 8 +- trunk/drivers/media/video/gspca/ov519.c | 981 ++------------ trunk/drivers/media/video/gspca/sonixj.c | 181 +-- .../media/video/gspca/stv06xx/Makefile | 3 +- .../media/video/gspca/stv06xx/stv06xx.c | 53 +- .../media/video/gspca/stv06xx/stv06xx.h | 11 - .../media/video/gspca/stv06xx/stv06xx_hdcs.c | 10 +- .../video/gspca/stv06xx/stv06xx_sensor.h | 3 +- .../video/gspca/stv06xx/stv06xx_st6422.c | 453 ------- .../video/gspca/stv06xx/stv06xx_st6422.h | 59 - .../drivers/media/video/ivtv/ivtv-controls.c | 2 - trunk/drivers/media/video/mt9m001.c | 12 +- trunk/drivers/media/video/mt9t031.c | 14 +- trunk/drivers/media/video/mt9v022.c | 12 +- trunk/drivers/media/video/ov511.c | 2 + .../media/video/pvrusb2/pvrusb2-audio.c | 14 +- .../media/video/pvrusb2/pvrusb2-cs53l32a.c | 24 +- .../media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 37 +- .../drivers/media/video/pvrusb2/pvrusb2-hdw.c | 60 +- .../media/video/pvrusb2/pvrusb2-video-v4l.c | 35 +- trunk/drivers/media/video/pxa_camera.c | 34 +- .../media/video/saa7134/saa7134-video.c | 11 +- .../media/video/sh_mobile_ceu_camera.c | 12 +- trunk/drivers/media/video/tcm825x.c | 4 +- trunk/drivers/media/video/usbvideo/Kconfig | 5 +- trunk/drivers/media/video/v4l2-common.c | 181 +-- trunk/drivers/media/video/vivi.c | 11 +- trunk/drivers/media/video/w9968cf.c | 35 +- .../drivers/media/video/zoran/zoran_driver.c | 14 +- trunk/drivers/message/fusion/mptsas.c | 4 +- trunk/drivers/mfd/ezx-pcap.c | 4 +- trunk/drivers/mfd/sm501.c | 3 +- trunk/drivers/mfd/twl4030-core.c | 12 - trunk/drivers/mmc/host/mmc_spi.c | 6 - trunk/drivers/mtd/cmdlinepart.c | 2 +- trunk/drivers/mtd/devices/m25p80.c | 2 +- trunk/drivers/mtd/inftlcore.c | 11 +- trunk/drivers/mtd/maps/integrator-flash.c | 22 +- trunk/drivers/mtd/nand/atmel_nand.c | 2 +- trunk/drivers/mtd/nand/omap2.c | 7 +- trunk/drivers/mtd/nftlcore.c | 16 +- trunk/drivers/net/Kconfig | 1 - trunk/drivers/net/atl1c/atl1c_ethtool.c | 2 - trunk/drivers/net/atl1e/atl1e_ethtool.c | 2 - trunk/drivers/net/benet/be.h | 2 +- trunk/drivers/net/benet/be_ethtool.c | 4 +- trunk/drivers/net/benet/be_main.c | 45 +- trunk/drivers/net/bnx2.c | 10 +- trunk/drivers/net/bnx2x_main.c | 10 +- trunk/drivers/net/can/Kconfig | 2 +- trunk/drivers/net/cnic.c | 6 +- trunk/drivers/net/cnic_if.h | 2 - trunk/drivers/net/cpmac.c | 2 +- trunk/drivers/net/e1000/e1000_main.c | 11 +- trunk/drivers/net/e1000e/netdev.c | 3 - trunk/drivers/net/fsl_pq_mdio.c | 8 +- trunk/drivers/net/igb/igb_main.c | 14 +- trunk/drivers/net/irda/bfin_sir.c | 16 +- trunk/drivers/net/ixgbe/ixgbe_ethtool.c | 5 +- trunk/drivers/net/ixgbe/ixgbe_main.c | 45 +- trunk/drivers/net/mdio.c | 4 - trunk/drivers/net/mlx4/mr.c | 14 +- trunk/drivers/net/netxen/netxen_nic_init.c | 37 +- trunk/drivers/net/netxen/netxen_nic_main.c | 7 +- trunk/drivers/net/qla3xxx.c | 6 +- trunk/drivers/net/sh_eth.c | 9 +- trunk/drivers/net/sky2.c | 2 +- trunk/drivers/net/usb/cdc_eem.c | 2 +- trunk/drivers/net/usb/dm9601.c | 10 +- trunk/drivers/net/usb/net1080.c | 12 +- trunk/drivers/net/usb/rndis_host.c | 2 +- trunk/drivers/net/usb/smsc95xx.c | 10 +- trunk/drivers/net/usb/usbnet.c | 30 +- trunk/drivers/net/veth.c | 41 +- trunk/drivers/parport/parport_pc.c | 5 +- trunk/drivers/pci/hotplug/acpi_pcihp.c | 40 +- trunk/drivers/pci/hotplug/acpiphp_glue.c | 27 +- trunk/drivers/pci/intel-iommu.c | 970 ++++++-------- trunk/drivers/pci/intr_remapping.c | 160 +-- trunk/drivers/pci/intr_remapping.h | 2 - trunk/drivers/pci/iova.c | 26 +- trunk/drivers/pcmcia/vrc4171_card.c | 4 +- trunk/drivers/pcmcia/vrc4173_cardu.c | 4 +- trunk/drivers/pcmcia/vrc4173_cardu.h | 2 +- trunk/drivers/platform/x86/Kconfig | 35 +- trunk/drivers/platform/x86/Makefile | 1 - trunk/drivers/platform/x86/acerhdf.c | 602 --------- trunk/drivers/platform/x86/asus-laptop.c | 111 +- trunk/drivers/platform/x86/asus_acpi.c | 30 +- trunk/drivers/platform/x86/dell-wmi.c | 56 +- trunk/drivers/platform/x86/eeepc-laptop.c | 468 ++----- trunk/drivers/platform/x86/hp-wmi.c | 87 +- trunk/drivers/platform/x86/thinkpad_acpi.c | 411 +----- trunk/drivers/pnp/pnpacpi/rsparser.c | 46 +- trunk/drivers/power/Kconfig | 8 - trunk/drivers/power/Makefile | 3 +- trunk/drivers/power/da9030_battery.c | 19 +- trunk/drivers/power/ds2760_battery.c | 42 +- trunk/drivers/power/max17040_battery.c | 309 ----- trunk/drivers/rtc/rtc-bfin.c | 30 +- trunk/drivers/rtc/rtc-vr41xx.c | 4 +- trunk/drivers/scsi/Kconfig | 13 +- trunk/drivers/scsi/bnx2i/Kconfig | 2 - trunk/drivers/scsi/cxgb3i/Kbuild | 2 +- trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c | 90 +- trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h | 2 - trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c | 4 - trunk/drivers/scsi/fcoe/fcoe.c | 108 +- trunk/drivers/scsi/fcoe/fcoe.h | 24 - trunk/drivers/scsi/fcoe/libfcoe.c | 94 +- trunk/drivers/scsi/fnic/fnic_main.c | 8 +- trunk/drivers/scsi/fnic/fnic_scsi.c | 7 +- trunk/drivers/scsi/hosts.c | 8 +- trunk/drivers/scsi/ibmvscsi/ibmvfc.c | 36 +- trunk/drivers/scsi/ibmvscsi/ibmvfc.h | 1 - trunk/drivers/scsi/ibmvscsi/ibmvscsi.c | 7 +- trunk/drivers/scsi/ipr.c | 138 +- trunk/drivers/scsi/ipr.h | 10 +- trunk/drivers/scsi/iscsi_tcp.c | 14 +- trunk/drivers/scsi/libfc/fc_disc.c | 83 +- trunk/drivers/scsi/libfc/fc_exch.c | 58 +- trunk/drivers/scsi/libfc/fc_fcp.c | 97 +- trunk/drivers/scsi/libfc/fc_lport.c | 156 +-- trunk/drivers/scsi/libfc/fc_rport.c | 120 +- trunk/drivers/scsi/libiscsi.c | 161 +-- trunk/drivers/scsi/libiscsi_tcp.c | 6 +- trunk/drivers/scsi/qla2xxx/qla_dbg.c | 2 +- trunk/drivers/scsi/qla2xxx/qla_init.c | 2 +- trunk/drivers/scsi/qla2xxx/qla_mbx.c | 28 +- trunk/drivers/scsi/qla2xxx/qla_os.c | 2 +- trunk/drivers/scsi/qla2xxx/qla_version.h | 2 +- trunk/drivers/scsi/scsi_debug.c | 30 +- trunk/drivers/scsi/scsi_devinfo.c | 247 +--- trunk/drivers/scsi/scsi_lib.c | 1 - trunk/drivers/scsi/scsi_priv.h | 17 +- trunk/drivers/scsi/scsi_sysfs.c | 17 + trunk/drivers/scsi/scsi_transport_fc.c | 49 +- trunk/drivers/scsi/scsi_transport_iscsi.c | 1 - trunk/drivers/scsi/scsi_transport_sas.c | 4 +- trunk/drivers/scsi/scsi_transport_spi.c | 51 +- trunk/drivers/scsi/sd.c | 74 +- trunk/drivers/scsi/sd.h | 1 - trunk/drivers/scsi/sg.c | 4 +- trunk/drivers/scsi/sr.c | 1 - trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c | 5 +- trunk/drivers/scsi/zalon.c | 2 +- trunk/drivers/serial/8250_pci.c | 12 +- trunk/drivers/serial/icom.c | 3 +- trunk/drivers/serial/jsm/jsm_tty.c | 4 +- trunk/drivers/serial/serial_txx9.c | 113 +- trunk/drivers/serial/vr41xx_siu.c | 2 +- trunk/drivers/spi/omap_uwire.c | 2 - trunk/drivers/spi/spi_bitbang.c | 24 +- trunk/drivers/spi/spidev.c | 17 +- trunk/drivers/ssb/driver_mipscore.c | 85 +- trunk/drivers/staging/octeon/Makefile | 1 + .../drivers/staging/octeon/ethernet-common.c | 328 +++++ .../drivers/staging/octeon/ethernet-common.h | 29 + .../drivers/staging/octeon/ethernet-defines.h | 2 - trunk/drivers/staging/octeon/ethernet-rgmii.c | 9 +- trunk/drivers/staging/octeon/ethernet-sgmii.c | 9 +- trunk/drivers/staging/octeon/ethernet-spi.c | 1 + trunk/drivers/staging/octeon/ethernet-tx.c | 62 +- trunk/drivers/staging/octeon/ethernet-tx.h | 25 - trunk/drivers/staging/octeon/ethernet-xaui.c | 9 +- trunk/drivers/staging/octeon/ethernet.c | 470 +------ .../drivers/staging/octeon/octeon-ethernet.h | 11 - trunk/drivers/usb/class/cdc-acm.c | 4 +- trunk/drivers/usb/serial/usb-serial.c | 3 - trunk/drivers/uwb/hwa-rc.c | 2 +- trunk/drivers/uwb/wlp/txrx.c | 2 +- trunk/drivers/video/atafb.c | 7 +- trunk/drivers/video/atmel_lcdfb.c | 2 - trunk/drivers/video/aty/atyfb.h | 3 - trunk/drivers/video/aty/atyfb_base.c | 141 +- trunk/drivers/video/aty/mach64_accel.c | 7 +- trunk/drivers/video/backlight/tdo24m.c | 2 +- trunk/drivers/video/cobalt_lcdfb.c | 2 +- trunk/drivers/video/fbmem.c | 13 +- trunk/drivers/video/fsl-diu-fb.c | 14 +- trunk/drivers/video/i810/i810_main.c | 2 - trunk/drivers/video/matrox/matroxfb_base.c | 3 - trunk/drivers/video/matrox/matroxfb_crtc2.c | 5 +- trunk/drivers/video/mx3fb.c | 17 +- trunk/drivers/video/nvidia/nv_setup.c | 3 +- trunk/drivers/video/omap/omapfb_main.c | 4 - trunk/drivers/video/platinumfb.c | 2 - trunk/drivers/video/pxafb.c | 2 - trunk/drivers/video/sh7760fb.c | 19 +- trunk/drivers/video/sh_mobile_lcdcfb.c | 53 +- trunk/drivers/video/sis/sis_main.c | 2 - trunk/drivers/video/sm501fb.c | 21 +- trunk/drivers/video/w100fb.c | 2 - trunk/drivers/w1/slaves/w1_ds2760.c | 30 - trunk/drivers/w1/slaves/w1_ds2760.h | 7 - trunk/drivers/watchdog/Kconfig | 59 +- trunk/drivers/watchdog/Makefile | 5 - trunk/drivers/watchdog/bcm47xx_wdt.c | 286 ---- trunk/drivers/watchdog/coh901327_wdt.c | 537 -------- trunk/drivers/watchdog/hpwdt.c | 26 +- trunk/drivers/watchdog/omap_wdt.c | 7 - trunk/drivers/watchdog/pnx833x_wdt.c | 282 ---- trunk/drivers/watchdog/stmp3xxx_wdt.c | 296 ----- trunk/drivers/watchdog/twl4030_wdt.c | 272 ---- trunk/drivers/watchdog/wdrtas.c | 8 +- trunk/drivers/watchdog/wdt_pci.c | 122 +- trunk/fs/afs/flock.c | 1 + trunk/fs/aio.c | 24 +- trunk/fs/binfmt_elf.c | 9 +- trunk/fs/bio-integrity.c | 170 +-- trunk/fs/bio.c | 11 +- trunk/fs/btrfs/acl.c | 44 +- trunk/fs/btrfs/async-thread.c | 2 +- trunk/fs/btrfs/btrfs_inode.h | 4 + trunk/fs/btrfs/ctree.h | 5 +- trunk/fs/btrfs/extent-tree.c | 566 +++----- trunk/fs/btrfs/file.c | 5 +- trunk/fs/btrfs/inode.c | 43 +- trunk/fs/btrfs/ioctl.c | 6 +- trunk/fs/btrfs/relocation.c | 5 +- trunk/fs/btrfs/transaction.c | 4 +- trunk/fs/cifs/CHANGES | 2 +- trunk/fs/cifs/asn1.c | 55 +- trunk/fs/cifs/cifsfs.c | 157 ++- trunk/fs/cifs/cifsglob.h | 2 +- trunk/fs/cifs/cifsproto.h | 2 +- trunk/fs/cifs/cifssmb.c | 4 +- trunk/fs/cifs/connect.c | 39 +- trunk/fs/cifs/dir.c | 6 +- trunk/fs/cifs/dns_resolve.c | 25 +- trunk/fs/cifs/file.c | 34 +- trunk/fs/cifs/inode.c | 15 +- trunk/fs/cifs/link.c | 3 +- trunk/fs/cifs/netmisc.c | 56 +- trunk/fs/cifs/sess.c | 2 +- trunk/fs/cifs/xattr.c | 12 +- trunk/fs/compat_ioctl.c | 48 - trunk/fs/devpts/inode.c | 10 + trunk/fs/eventfd.c | 122 +- trunk/fs/ext2/acl.c | 81 +- trunk/fs/ext2/acl.h | 4 + trunk/fs/ext2/ext2.h | 4 + trunk/fs/ext2/inode.c | 4 + trunk/fs/ext2/namei.c | 12 +- trunk/fs/ext2/super.c | 16 + trunk/fs/ext3/acl.c | 85 +- trunk/fs/ext3/acl.h | 4 + trunk/fs/ext3/inode.c | 4 + trunk/fs/ext3/super.c | 16 + trunk/fs/ext4/acl.c | 67 +- trunk/fs/ext4/acl.h | 4 + trunk/fs/ext4/ext4.h | 4 + trunk/fs/ext4/inode.c | 4 + trunk/fs/ext4/super.c | 16 + trunk/fs/fs-writeback.c | 100 +- trunk/fs/fuse/dev.c | 83 +- trunk/fs/fuse/dir.c | 57 +- trunk/fs/fuse/file.c | 2 +- trunk/fs/fuse/fuse_i.h | 27 - trunk/fs/fuse/inode.c | 68 +- trunk/fs/hostfs/hostfs_kern.c | 1 - trunk/fs/inode.c | 27 +- trunk/fs/ioctl.c | 35 - trunk/fs/jffs2/acl.c | 87 +- trunk/fs/jffs2/acl.h | 4 + trunk/fs/jffs2/jffs2_fs_i.h | 4 + trunk/fs/jffs2/os-linux.h | 4 + trunk/fs/jffs2/readinode.c | 1 + trunk/fs/jffs2/scan.c | 4 +- trunk/fs/jfs/acl.c | 47 +- trunk/fs/jfs/jfs_incore.h | 6 + trunk/fs/jfs/super.c | 16 + trunk/fs/jfs/xattr.c | 10 +- trunk/fs/namei.c | 18 +- trunk/fs/namespace.c | 37 +- trunk/fs/nfsd/vfs.c | 3 +- trunk/fs/nilfs2/inode.c | 8 + trunk/fs/nilfs2/nilfs.h | 4 + trunk/fs/nilfs2/super.c | 10 + trunk/fs/notify/inotify/inotify_user.c | 3 - trunk/fs/ocfs2/dlmglue.c | 123 +- trunk/fs/ocfs2/dlmglue.h | 24 +- trunk/fs/ocfs2/file.c | 6 +- trunk/fs/ocfs2/inode.c | 11 - trunk/fs/ocfs2/journal.c | 43 +- trunk/fs/ocfs2/journal.h | 2 +- trunk/fs/ocfs2/namei.c | 15 +- trunk/fs/ocfs2/ocfs2.h | 10 - trunk/fs/ocfs2/stack_o2cb.c | 11 - trunk/fs/ocfs2/stack_user.c | 8 - trunk/fs/ocfs2/stackglue.c | 13 +- trunk/fs/ocfs2/stackglue.h | 6 - trunk/fs/ocfs2/suballoc.c | 28 +- trunk/fs/ocfs2/super.c | 69 +- trunk/fs/ocfs2/sysfile.c | 19 - trunk/fs/open.c | 58 +- trunk/fs/reiserfs/inode.c | 4 + trunk/fs/reiserfs/resize.c | 1 + trunk/fs/reiserfs/super.c | 24 + trunk/fs/reiserfs/xattr_acl.c | 58 +- trunk/fs/super.c | 9 +- trunk/fs/ubifs/xattr.c | 2 +- trunk/fs/udf/balloc.c | 9 +- trunk/fs/udf/lowlevel.c | 7 +- trunk/fs/xfs/linux-2.6/xfs_acl.c | 73 +- trunk/fs/xfs/xfs_acl.h | 4 + trunk/fs/xfs/xfs_iget.c | 2 + trunk/fs/xfs/xfs_inode.h | 5 + trunk/include/acpi/acpi_bus.h | 7 +- trunk/include/acpi/acpi_drivers.h | 13 +- trunk/include/acpi/processor.h | 1 - trunk/include/acpi/video.h | 4 +- trunk/include/asm-generic/hardirq.h | 13 + trunk/include/asm-generic/percpu.h | 4 - trunk/include/asm-generic/pgtable.h | 4 - trunk/include/asm-generic/uaccess.h | 14 +- trunk/include/asm-generic/unistd.h | 7 +- trunk/include/asm-generic/vmlinux.lds.h | 15 +- trunk/include/drm/drm_edid.h | 38 +- trunk/include/linux/Kbuild | 1 - trunk/include/linux/acpi.h | 6 +- trunk/include/linux/aio.h | 4 +- trunk/include/linux/audit.h | 3 - trunk/include/linux/bio.h | 22 +- trunk/include/linux/blkdev.h | 15 +- trunk/include/linux/connector.h | 4 +- trunk/include/linux/device-mapper.h | 47 +- trunk/include/linux/dm-ioctl.h | 14 +- trunk/include/linux/dm-log-userspace.h | 386 ------ trunk/include/linux/dmar.h | 11 - trunk/include/linux/eventfd.h | 35 +- trunk/include/linux/ext3_fs_i.h | 4 + trunk/include/linux/falloc.h | 21 - trunk/include/linux/fb.h | 1 - trunk/include/linux/fs.h | 13 - trunk/include/linux/fsnotify_backend.h | 2 +- trunk/include/linux/fuse.h | 36 +- trunk/include/linux/hrtimer.h | 5 - trunk/include/linux/hugetlb.h | 4 +- trunk/include/linux/icmpv6.h | 6 +- trunk/include/linux/ide.h | 5 +- trunk/include/linux/ima.h | 6 - trunk/include/linux/init_task.h | 3 - trunk/include/linux/kernel.h | 1 - trunk/include/linux/kvm_host.h | 1 - trunk/include/linux/leds-lp3944.h | 53 - trunk/include/linux/leds.h | 14 +- trunk/include/linux/linkage.h | 9 - trunk/include/linux/lockdep.h | 15 - trunk/include/linux/max17040_battery.h | 19 - trunk/include/linux/mm.h | 2 +- trunk/include/linux/netfilter/xt_conntrack.h | 13 - trunk/include/linux/netfilter/xt_osf.h | 2 - trunk/include/linux/pci_hotplug.h | 1 + trunk/include/linux/pci_ids.h | 1 - trunk/include/linux/percpu-defs.h | 3 +- trunk/include/linux/perf_counter.h | 46 +- trunk/include/linux/posix_acl.h | 74 -- trunk/include/linux/reiserfs_acl.h | 17 + trunk/include/linux/reiserfs_fs_i.h | 4 + trunk/include/linux/rmap.h | 9 +- trunk/include/linux/sched.h | 16 +- trunk/include/linux/shmem_fs.h | 8 + trunk/include/linux/spi/spi.h | 6 - trunk/include/linux/spi/spidev.h | 2 - trunk/include/linux/swap.h | 12 +- trunk/include/linux/timer.h | 4 - trunk/include/linux/usb/usbnet.h | 1 + trunk/include/linux/videodev2.h | 4 +- trunk/include/media/ir-common.h | 2 - trunk/include/media/v4l2-common.h | 26 - trunk/include/media/v4l2-i2c-drv.h | 5 +- trunk/include/media/v4l2-subdev.h | 7 +- trunk/include/net/netfilter/nf_conntrack.h | 4 +- trunk/include/net/phonet/pn_dev.h | 1 - trunk/include/net/protocol.h | 2 +- trunk/include/net/rawv6.h | 2 +- trunk/include/net/sctp/sctp.h | 1 - trunk/include/net/sock.h | 2 - trunk/include/net/xfrm.h | 2 +- trunk/include/scsi/fc_encode.h | 2 + trunk/include/scsi/libfc.h | 77 +- trunk/include/scsi/libiscsi.h | 4 - trunk/include/scsi/scsi_driver.h | 1 - trunk/init/main.c | 6 +- trunk/ipc/mqueue.c | 2 - trunk/kernel/Makefile | 3 +- trunk/kernel/acct.c | 6 +- trunk/kernel/audit.c | 146 +- trunk/kernel/audit.h | 43 +- trunk/kernel/audit_tree.c | 66 +- trunk/kernel/audit_watch.c | 543 -------- trunk/kernel/auditfilter.c | 518 +++++++- trunk/kernel/auditsc.c | 33 +- trunk/kernel/futex.c | 45 +- trunk/kernel/perf_counter.c | 320 +---- trunk/kernel/pid.c | 7 - trunk/kernel/resource.c | 2 +- trunk/kernel/sysctl.c | 13 +- trunk/kernel/time/timer_stats.c | 16 +- trunk/kernel/timer.c | 2 - trunk/kernel/trace/ftrace.c | 56 +- trunk/kernel/trace/ring_buffer.c | 11 - trunk/kernel/trace/trace.c | 23 +- trunk/kernel/trace/trace.h | 7 - trunk/kernel/trace/trace_events.c | 28 +- trunk/kernel/trace/trace_functions.c | 3 +- trunk/kernel/trace/trace_printk.c | 26 +- trunk/kernel/trace/trace_stat.c | 6 +- trunk/lib/Kconfig.debug | 17 +- trunk/lib/checksum.c | 10 +- trunk/mm/dmapool.c | 2 - trunk/mm/hugetlb.c | 17 +- trunk/mm/kmemleak.c | 243 ++-- trunk/mm/memory.c | 34 +- trunk/mm/nommu.c | 33 +- trunk/mm/page-writeback.c | 5 +- trunk/mm/page_alloc.c | 23 +- trunk/mm/percpu.c | 24 +- trunk/mm/shmem.c | 6 +- trunk/mm/shmem_acl.c | 29 +- trunk/mm/slub.c | 10 +- trunk/mm/thrash.c | 32 +- trunk/mm/vmscan.c | 2 +- trunk/net/ax25/ax25_in.c | 3 +- trunk/net/bridge/br.c | 2 +- trunk/net/core/dev.c | 10 +- trunk/net/dccp/ipv6.c | 2 +- trunk/net/decnet/af_decnet.c | 2 - trunk/net/ieee802154/netlink.c | 6 - trunk/net/ipv4/arp.c | 7 +- trunk/net/ipv4/fib_trie.c | 3 - trunk/net/ipv4/ip_input.c | 3 - trunk/net/ipv4/netfilter/nf_nat_helper.c | 17 +- trunk/net/ipv4/route.c | 26 +- trunk/net/ipv4/tcp.c | 15 +- trunk/net/ipv4/tcp_minisocks.c | 3 +- trunk/net/ipv4/tcp_output.c | 3 +- trunk/net/ipv6/addrconf.c | 5 +- trunk/net/ipv6/af_inet6.c | 2 - trunk/net/ipv6/ah6.c | 2 +- trunk/net/ipv6/esp6.c | 2 +- trunk/net/ipv6/icmp.c | 12 +- trunk/net/ipv6/ip6_input.c | 3 - trunk/net/ipv6/ip6_tunnel.c | 18 +- trunk/net/ipv6/ipcomp6.c | 2 +- trunk/net/ipv6/mip6.c | 2 +- trunk/net/ipv6/raw.c | 4 +- trunk/net/ipv6/route.c | 2 +- trunk/net/ipv6/tcp_ipv6.c | 2 +- trunk/net/ipv6/tunnel6.c | 2 +- trunk/net/ipv6/udp.c | 6 +- trunk/net/ipv6/udp_impl.h | 2 +- trunk/net/ipv6/udplite.c | 2 +- trunk/net/ipv6/xfrm6_tunnel.c | 2 +- trunk/net/irda/af_irda.c | 3 + trunk/net/irda/ircomm/ircomm_lmp.c | 1 - trunk/net/mac80211/mesh.c | 2 +- trunk/net/netfilter/nf_conntrack_core.c | 25 +- trunk/net/netfilter/nf_conntrack_expect.c | 4 +- trunk/net/netfilter/nf_conntrack_extend.c | 2 +- trunk/net/netfilter/nf_conntrack_proto_tcp.c | 6 +- trunk/net/netfilter/nf_log.c | 16 +- trunk/net/netfilter/xt_NFQUEUE.c | 8 +- trunk/net/netfilter/xt_cluster.c | 8 +- trunk/net/netfilter/xt_conntrack.c | 66 +- trunk/net/netfilter/xt_quota.c | 1 - trunk/net/netfilter/xt_rateest.c | 2 +- trunk/net/phonet/pn_dev.c | 52 +- trunk/net/phonet/pn_netlink.c | 4 +- trunk/net/sctp/ipv6.c | 2 +- trunk/net/sctp/output.c | 2 +- trunk/net/sunrpc/sunrpc_syms.c | 1 - trunk/net/xfrm/xfrm_algo.c | 4 +- trunk/net/xfrm/xfrm_state.c | 57 +- trunk/scripts/.gitignore | 1 - trunk/scripts/dtc/.gitignore | 5 - trunk/scripts/kernel-doc | 4 +- trunk/scripts/package/builddeb | 2 - trunk/scripts/pnmtologo.c | 4 +- trunk/security/integrity/ima/ima_main.c | 29 +- trunk/security/integrity/ima/ima_queue.c | 3 +- trunk/sound/core/pcm_native.c | 2 +- trunk/sound/core/seq/seq_midi_event.c | 8 +- trunk/sound/isa/cmi8330.c | 2 +- trunk/sound/oss/kahlua.c | 2 +- trunk/sound/oss/mpu401.c | 16 +- trunk/sound/pci/atiixp.c | 8 +- trunk/sound/pci/atiixp_modem.c | 4 +- trunk/sound/pci/au88x0/au8810.c | 3 +- trunk/sound/pci/au88x0/au8820.c | 3 +- trunk/sound/pci/au88x0/au8830.c | 3 +- trunk/sound/pci/ca0106/ca0106_main.c | 2 +- trunk/sound/pci/cmipci.c | 10 +- trunk/sound/pci/cs4281.c | 2 +- trunk/sound/pci/cs46xx/cs46xx.c | 6 +- trunk/sound/pci/ctxfi/ctatc.c | 206 +-- trunk/sound/pci/ctxfi/ctatc.h | 7 - trunk/sound/pci/ctxfi/cthardware.h | 7 - trunk/sound/pci/ctxfi/cthw20k1.c | 83 +- trunk/sound/pci/ctxfi/cthw20k2.c | 65 +- trunk/sound/pci/ctxfi/ctmixer.c | 92 +- trunk/sound/pci/ctxfi/ctmixer.h | 3 - trunk/sound/pci/ctxfi/ctpcm.c | 4 - trunk/sound/pci/ctxfi/xfi.c | 22 - trunk/sound/pci/emu10k1/emu10k1.c | 6 +- trunk/sound/pci/emu10k1/emu10k1x.c | 2 +- trunk/sound/pci/ens1370.c | 8 +- trunk/sound/pci/es1938.c | 2 +- trunk/sound/pci/hda/Kconfig | 9 +- trunk/sound/pci/hda/hda_codec.c | 14 +- trunk/sound/pci/hda/hda_intel.c | 7 - trunk/sound/pci/hda/patch_analog.c | 156 +-- trunk/sound/pci/hda/patch_ca0110.c | 2 +- trunk/sound/pci/hda/patch_conexant.c | 4 +- trunk/sound/pci/hda/patch_realtek.c | 179 ++- trunk/sound/pci/hda/patch_sigmatel.c | 10 +- trunk/sound/pci/ice1712/ice1712.c | 2 +- trunk/sound/pci/ice1712/ice1724.c | 2 +- trunk/sound/pci/intel8x0.c | 46 +- trunk/sound/pci/intel8x0m.c | 34 +- trunk/sound/pci/lx6464es/lx6464es.c | 7 +- trunk/sound/pci/mixart/mixart.c | 2 +- trunk/sound/pci/nm256/nm256.c | 6 +- trunk/sound/pci/oxygen/oxygen_mixer.c | 28 +- trunk/sound/pci/oxygen/virtuoso.c | 2 - trunk/sound/pci/rme32.c | 9 +- trunk/sound/pci/rme96.c | 12 +- trunk/sound/pci/sonicvibes.c | 2 +- trunk/sound/pci/via82xx.c | 10 +- trunk/sound/pci/via82xx_modem.c | 2 +- trunk/sound/pci/ymfpci/ymfpci.c | 12 +- trunk/sound/soc/blackfin/bf5xx-i2s.c | 10 +- trunk/sound/soc/fsl/Kconfig | 6 +- trunk/sound/soc/omap/omap-pcm.c | 11 +- trunk/sound/soc/pxa/pxa2xx-i2s.c | 7 +- trunk/sound/sound_core.c | 5 +- trunk/sound/usb/caiaq/device.c | 10 +- trunk/sound/usb/usx2y/us122l.c | 2 +- trunk/sound/usb/usx2y/usbusx2y.c | 2 +- trunk/tools/perf/CREDITS | 30 - .../tools/perf/Documentation/perf-report.txt | 14 +- trunk/tools/perf/Documentation/perf-stat.txt | 6 +- trunk/tools/perf/Makefile | 6 +- trunk/tools/perf/builtin-annotate.c | 8 +- trunk/tools/perf/builtin-record.c | 127 +- trunk/tools/perf/builtin-report.c | 236 +--- trunk/tools/perf/builtin-stat.c | 171 +-- trunk/tools/perf/builtin-top.c | 11 +- trunk/tools/perf/perf.h | 19 +- trunk/tools/perf/{util => }/types.h | 0 trunk/tools/perf/util/callchain.c | 174 --- trunk/tools/perf/util/callchain.h | 33 - trunk/tools/perf/util/header.c | 242 ---- trunk/tools/perf/util/header.h | 37 - trunk/tools/perf/util/help.c | 15 + trunk/tools/perf/util/pager.c | 5 +- trunk/tools/perf/util/parse-events.c | 153 +-- trunk/tools/perf/util/run-command.c | 95 +- trunk/tools/perf/util/run-command.h | 5 + trunk/tools/perf/util/strbuf.c | 2 +- trunk/tools/perf/util/string.h | 2 +- trunk/tools/perf/util/strlist.c | 184 --- trunk/tools/perf/util/strlist.h | 32 - trunk/tools/perf/util/symbol.c | 16 +- trunk/tools/perf/util/symbol.h | 5 +- trunk/tools/perf/util/util.h | 15 + trunk/virt/kvm/kvm_main.c | 5 - 1083 files changed, 11598 insertions(+), 33008 deletions(-) delete mode 100644 trunk/Documentation/device-mapper/dm-log.txt delete mode 100644 trunk/Documentation/device-mapper/dm-queue-length.txt delete mode 100644 trunk/Documentation/device-mapper/dm-service-time.txt delete mode 100644 trunk/Documentation/leds-lp3944.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/4xx/emac.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/gpio/gpio.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/gpio/mdio.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/marvell.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/phy.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/spi-bus.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/usb-ehci.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/xilinx.txt delete mode 100644 trunk/arch/cris/arch-v32/lib/strcmp.S delete mode 100644 trunk/arch/frv/include/asm/perf_counter.h delete mode 100644 trunk/arch/frv/lib/atomic64-ops.S delete mode 100644 trunk/arch/frv/lib/perf_counter.c delete mode 100644 trunk/arch/mips/ar7/Makefile delete mode 100644 trunk/arch/mips/ar7/clock.c delete mode 100644 trunk/arch/mips/ar7/gpio.c delete mode 100644 trunk/arch/mips/ar7/irq.c delete mode 100644 trunk/arch/mips/ar7/memory.c delete mode 100644 trunk/arch/mips/ar7/platform.c delete mode 100644 trunk/arch/mips/ar7/prom.c delete mode 100644 trunk/arch/mips/ar7/setup.c delete mode 100644 trunk/arch/mips/ar7/time.c rename trunk/arch/mips/{pci/msi-octeon.c => cavium-octeon/msi.c} (88%) delete mode 100644 trunk/arch/mips/cavium-octeon/octeon_boot.h create mode 100644 trunk/arch/mips/cavium-octeon/pci-common.c rename trunk/arch/mips/{include/asm/octeon/pci-octeon.h => cavium-octeon/pci-common.h} (52%) rename trunk/arch/mips/{pci/pci-octeon.c => cavium-octeon/pci.c} (78%) rename trunk/arch/mips/{pci/pcie-octeon.c => cavium-octeon/pcie.c} (98%) delete mode 100644 trunk/arch/mips/configs/ar7_defconfig delete mode 100644 trunk/arch/mips/include/asm/amon.h delete mode 100644 trunk/arch/mips/include/asm/mach-ar7/ar7.h delete mode 100644 trunk/arch/mips/include/asm/mach-ar7/gpio.h delete mode 100644 trunk/arch/mips/include/asm/mach-ar7/irq.h delete mode 100644 trunk/arch/mips/include/asm/mach-ar7/prom.h delete mode 100644 trunk/arch/mips/include/asm/mach-ar7/spaces.h delete mode 100644 trunk/arch/mips/include/asm/mach-ar7/war.h delete mode 100644 trunk/arch/powerpc/mm/highmem.c create mode 100644 trunk/block/cmd-filter.c delete mode 100644 trunk/drivers/ata/pata_at91.c delete mode 100644 trunk/drivers/gpio/vr41xx_giu.c delete mode 100644 trunk/drivers/gpu/drm/i915/intel_dp.c delete mode 100644 trunk/drivers/gpu/drm/i915/intel_dp.h delete mode 100644 trunk/drivers/gpu/drm/i915/intel_dp_i2c.c delete mode 100644 trunk/drivers/i2c/busses/i2c-designware.c delete mode 100644 trunk/drivers/leds/leds-lp3944.c delete mode 100644 trunk/drivers/md/dm-log-userspace-base.c delete mode 100644 trunk/drivers/md/dm-log-userspace-transfer.c delete mode 100644 trunk/drivers/md/dm-log-userspace-transfer.h delete mode 100644 trunk/drivers/md/dm-queue-length.c delete mode 100644 trunk/drivers/md/dm-service-time.c delete mode 100644 trunk/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c delete mode 100644 trunk/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h delete mode 100644 trunk/drivers/platform/x86/acerhdf.c delete mode 100644 trunk/drivers/power/max17040_battery.c create mode 100644 trunk/drivers/staging/octeon/ethernet-common.c create mode 100644 trunk/drivers/staging/octeon/ethernet-common.h delete mode 100644 trunk/drivers/watchdog/bcm47xx_wdt.c delete mode 100644 trunk/drivers/watchdog/coh901327_wdt.c delete mode 100644 trunk/drivers/watchdog/pnx833x_wdt.c delete mode 100644 trunk/drivers/watchdog/stmp3xxx_wdt.c delete mode 100644 trunk/drivers/watchdog/twl4030_wdt.c delete mode 100644 trunk/include/linux/dm-log-userspace.h delete mode 100644 trunk/include/linux/leds-lp3944.h delete mode 100644 trunk/include/linux/max17040_battery.h delete mode 100644 trunk/kernel/audit_watch.c delete mode 100644 trunk/scripts/dtc/.gitignore delete mode 100644 trunk/tools/perf/CREDITS rename trunk/tools/perf/{util => }/types.h (100%) delete mode 100644 trunk/tools/perf/util/callchain.c delete mode 100644 trunk/tools/perf/util/callchain.h delete mode 100644 trunk/tools/perf/util/header.c delete mode 100644 trunk/tools/perf/util/header.h delete mode 100644 trunk/tools/perf/util/strlist.c delete mode 100644 trunk/tools/perf/util/strlist.h diff --git a/[refs] b/[refs] index 627ce698811c..2019f417f1fc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dd0888c264c0d5feb5d86eb69c1fdbcdb42566af +refs/heads/master: 90eab5e09de20e8d991bbb11f6edfb573f906352 diff --git a/trunk/.gitignore b/trunk/.gitignore index b93fb7eff942..cecb3b040cc1 100644 --- a/trunk/.gitignore +++ b/trunk/.gitignore @@ -27,7 +27,6 @@ *.gz *.lzma *.patch -*.gcno # # Top-level generic files diff --git a/trunk/Documentation/block/data-integrity.txt b/trunk/Documentation/block/data-integrity.txt index 2d735b0ae383..e8ca040ba2cf 100644 --- a/trunk/Documentation/block/data-integrity.txt +++ b/trunk/Documentation/block/data-integrity.txt @@ -50,7 +50,7 @@ encouraged them to allow separation of the data and integrity metadata scatter-gather lists. The controller will interleave the buffers on write and split them on -read. This means that Linux can DMA the data buffers to and from +read. This means that the Linux can DMA the data buffers to and from host memory without changes to the page cache. Also, the 16-bit CRC checksum mandated by both the SCSI and SATA specs @@ -66,7 +66,7 @@ software RAID5). The IP checksum is weaker than the CRC in terms of detecting bit errors. However, the strength is really in the separation of the data -buffers and the integrity metadata. These two distinct buffers must +buffers and the integrity metadata. These two distinct buffers much match up for an I/O to complete. The separation of the data and integrity metadata buffers as well as diff --git a/trunk/Documentation/cgroups/cpusets.txt b/trunk/Documentation/cgroups/cpusets.txt index 1d7e9784439a..f9ca389dddf4 100644 --- a/trunk/Documentation/cgroups/cpusets.txt +++ b/trunk/Documentation/cgroups/cpusets.txt @@ -777,18 +777,6 @@ in cpuset directories: # /bin/echo 1-4 > cpus -> set cpus list to cpus 1,2,3,4 # /bin/echo 1,2,3,4 > cpus -> set cpus list to cpus 1,2,3,4 -To add a CPU to a cpuset, write the new list of CPUs including the -CPU to be added. To add 6 to the above cpuset: - -# /bin/echo 1-4,6 > cpus -> set cpus list to cpus 1,2,3,4,6 - -Similarly to remove a CPU from a cpuset, write the new list of CPUs -without the CPU to be removed. - -To remove all the CPUs: - -# /bin/echo "" > cpus -> clear cpus list - 2.3 Setting flags ----------------- diff --git a/trunk/Documentation/device-mapper/dm-log.txt b/trunk/Documentation/device-mapper/dm-log.txt deleted file mode 100644 index 994dd75475a6..000000000000 --- a/trunk/Documentation/device-mapper/dm-log.txt +++ /dev/null @@ -1,54 +0,0 @@ -Device-Mapper Logging -===================== -The device-mapper logging code is used by some of the device-mapper -RAID targets to track regions of the disk that are not consistent. -A region (or portion of the address space) of the disk may be -inconsistent because a RAID stripe is currently being operated on or -a machine died while the region was being altered. In the case of -mirrors, a region would be considered dirty/inconsistent while you -are writing to it because the writes need to be replicated for all -the legs of the mirror and may not reach the legs at the same time. -Once all writes are complete, the region is considered clean again. - -There is a generic logging interface that the device-mapper RAID -implementations use to perform logging operations (see -dm_dirty_log_type in include/linux/dm-dirty-log.h). Various different -logging implementations are available and provide different -capabilities. The list includes: - -Type Files -==== ===== -disk drivers/md/dm-log.c -core drivers/md/dm-log.c -userspace drivers/md/dm-log-userspace* include/linux/dm-log-userspace.h - -The "disk" log type -------------------- -This log implementation commits the log state to disk. This way, the -logging state survives reboots/crashes. - -The "core" log type -------------------- -This log implementation keeps the log state in memory. The log state -will not survive a reboot or crash, but there may be a small boost in -performance. This method can also be used if no storage device is -available for storing log state. - -The "userspace" log type ------------------------- -This log type simply provides a way to export the log API to userspace, -so log implementations can be done there. This is done by forwarding most -logging requests to userspace, where a daemon receives and processes the -request. - -The structure used for communication between kernel and userspace are -located in include/linux/dm-log-userspace.h. Due to the frequency, -diversity, and 2-way communication nature of the exchanges between -kernel and userspace, 'connector' is used as the interface for -communication. - -There are currently two userspace log implementations that leverage this -framework - "clustered_disk" and "clustered_core". These implementations -provide a cluster-coherent log for shared-storage. Device-mapper mirroring -can be used in a shared-storage environment when the cluster log implementations -are employed. diff --git a/trunk/Documentation/device-mapper/dm-queue-length.txt b/trunk/Documentation/device-mapper/dm-queue-length.txt deleted file mode 100644 index f4db2562175c..000000000000 --- a/trunk/Documentation/device-mapper/dm-queue-length.txt +++ /dev/null @@ -1,39 +0,0 @@ -dm-queue-length -=============== - -dm-queue-length is a path selector module for device-mapper targets, -which selects a path with the least number of in-flight I/Os. -The path selector name is 'queue-length'. - -Table parameters for each path: [] - : The number of I/Os to dispatch using the selected - path before switching to the next path. - If not given, internal default is used. To check - the default value, see the activated table. - -Status for each path: - : 'A' if the path is active, 'F' if the path is failed. - : The number of path failures. - : The number of in-flight I/Os on the path. - - -Algorithm -========= - -dm-queue-length increments/decrements 'in-flight' when an I/O is -dispatched/completed respectively. -dm-queue-length selects a path with the minimum 'in-flight'. - - -Examples -======== -In case that 2 paths (sda and sdb) are used with repeat_count == 128. - -# echo "0 10 multipath 0 0 1 1 queue-length 0 2 1 8:0 128 8:16 128" \ - dmsetup create test -# -# dmsetup table -test: 0 10 multipath 0 0 1 1 queue-length 0 2 1 8:0 128 8:16 128 -# -# dmsetup status -test: 0 10 multipath 2 0 0 0 1 1 E 0 2 1 8:0 A 0 0 8:16 A 0 0 diff --git a/trunk/Documentation/device-mapper/dm-service-time.txt b/trunk/Documentation/device-mapper/dm-service-time.txt deleted file mode 100644 index 7d00668e97bb..000000000000 --- a/trunk/Documentation/device-mapper/dm-service-time.txt +++ /dev/null @@ -1,91 +0,0 @@ -dm-service-time -=============== - -dm-service-time is a path selector module for device-mapper targets, -which selects a path with the shortest estimated service time for -the incoming I/O. - -The service time for each path is estimated by dividing the total size -of in-flight I/Os on a path with the performance value of the path. -The performance value is a relative throughput value among all paths -in a path-group, and it can be specified as a table argument. - -The path selector name is 'service-time'. - -Table parameters for each path: [ []] - : The number of I/Os to dispatch using the selected - path before switching to the next path. - If not given, internal default is used. To check - the default value, see the activated table. - : The relative throughput value of the path - among all paths in the path-group. - The valid range is 0-100. - If not given, minimum value '1' is used. - If '0' is given, the path isn't selected while - other paths having a positive value are available. - -Status for each path: \ - - : 'A' if the path is active, 'F' if the path is failed. - : The number of path failures. - : The size of in-flight I/Os on the path. - : The relative throughput value of the path - among all paths in the path-group. - - -Algorithm -========= - -dm-service-time adds the I/O size to 'in-flight-size' when the I/O is -dispatched and substracts when completed. -Basically, dm-service-time selects a path having minimum service time -which is calculated by: - - ('in-flight-size' + 'size-of-incoming-io') / 'relative_throughput' - -However, some optimizations below are used to reduce the calculation -as much as possible. - - 1. If the paths have the same 'relative_throughput', skip - the division and just compare the 'in-flight-size'. - - 2. If the paths have the same 'in-flight-size', skip the division - and just compare the 'relative_throughput'. - - 3. If some paths have non-zero 'relative_throughput' and others - have zero 'relative_throughput', ignore those paths with zero - 'relative_throughput'. - -If such optimizations can't be applied, calculate service time, and -compare service time. -If calculated service time is equal, the path having maximum -'relative_throughput' may be better. So compare 'relative_throughput' -then. - - -Examples -======== -In case that 2 paths (sda and sdb) are used with repeat_count == 128 -and sda has an average throughput 1GB/s and sdb has 4GB/s, -'relative_throughput' value may be '1' for sda and '4' for sdb. - -# echo "0 10 multipath 0 0 1 1 service-time 0 2 2 8:0 128 1 8:16 128 4" \ - dmsetup create test -# -# dmsetup table -test: 0 10 multipath 0 0 1 1 service-time 0 2 2 8:0 128 1 8:16 128 4 -# -# dmsetup status -test: 0 10 multipath 2 0 0 0 1 1 E 0 2 2 8:0 A 0 0 1 8:16 A 0 0 4 - - -Or '2' for sda and '8' for sdb would be also true. - -# echo "0 10 multipath 0 0 1 1 service-time 0 2 2 8:0 128 2 8:16 128 8" \ - dmsetup create test -# -# dmsetup table -test: 0 10 multipath 0 0 1 1 service-time 0 2 2 8:0 128 2 8:16 128 8 -# -# dmsetup status -test: 0 10 multipath 2 0 0 0 1 1 E 0 2 2 8:0 A 0 0 2 8:16 A 0 0 8 diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index 18b9d0ca0630..229d7b7c50a3 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -109,28 +109,27 @@ prototypes: locking rules: All may block. - None have BKL - s_umount -alloc_inode: -destroy_inode: -dirty_inode: (must not sleep) -write_inode: -drop_inode: !!!inode_lock!!! -delete_inode: -put_super: write -write_super: read -sync_fs: read -freeze_fs: read -unfreeze_fs: read -statfs: no -remount_fs: maybe (see below) -clear_inode: -umount_begin: no -show_options: no (namespace_sem) -quota_read: no (see below) -quota_write: no (see below) - -->remount_fs() will have the s_umount exclusive lock if it's already mounted. + BKL s_lock s_umount +alloc_inode: no no no +destroy_inode: no +dirty_inode: no (must not sleep) +write_inode: no +drop_inode: no !!!inode_lock!!! +delete_inode: no +put_super: yes yes no +write_super: no yes read +sync_fs: no no read +freeze_fs: ? +unfreeze_fs: ? +statfs: no no no +remount_fs: yes yes maybe (see below) +clear_inode: no +umount_begin: yes no no +show_options: no (vfsmount->sem) +quota_read: no no no (see below) +quota_write: no no no (see below) + +->remount_fs() will have the s_umount lock if it's already mounted. When called from get_sb_single, it does NOT have the s_umount lock. ->quota_read() and ->quota_write() functions are both guaranteed to be the only ones operating on the quota file by the quota code (via diff --git a/trunk/Documentation/gcov.txt b/trunk/Documentation/gcov.txt index 40ec63352760..e716aadb3a33 100644 --- a/trunk/Documentation/gcov.txt +++ b/trunk/Documentation/gcov.txt @@ -188,18 +188,13 @@ Solution: Exclude affected source files from profiling by specifying GCOV_PROFILE := n or GCOV_PROFILE_basename.o := n in the corresponding Makefile. -Problem: Files copied from sysfs appear empty or incomplete. -Cause: Due to the way seq_file works, some tools such as cp or tar - may not correctly copy files from sysfs. -Solution: Use 'cat' to read .gcda files and 'cp -d' to copy links. - Alternatively use the mechanism shown in Appendix B. - Appendix A: gather_on_build.sh ============================== Sample script to gather coverage meta files on the build machine (see 6a): + #!/bin/bash KSRC=$1 @@ -231,7 +226,7 @@ Appendix B: gather_on_test.sh Sample script to gather coverage data files on the test machine (see 6b): -#!/bin/bash -e +#!/bin/bash DEST=$1 GCDA=/sys/kernel/debug/gcov @@ -241,13 +236,11 @@ if [ -z "$DEST" ] ; then exit 1 fi -TEMPDIR=$(mktemp -d) -echo Collecting data.. -find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \; -find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \; -find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \; -tar czf $DEST -C $TEMPDIR sys -rm -rf $TEMPDIR +find $GCDA -name '*.gcno' -o -name '*.gcda' | tar cfz $DEST -T - -echo "$DEST successfully created, copy to build system and unpack with:" -echo " tar xfz $DEST" +if [ $? -eq 0 ] ; then + echo "$DEST successfully created, copy to build system and unpack with:" + echo " tar xfz $DEST" +else + echo "Could not create file $DEST" +fi diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index d77fbd8b79ac..92e1ab8178a8 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -229,6 +229,14 @@ and is between 256 and 4096 characters. It is defined in the file to assume that this machine's pmtimer latches its value and always returns good values. + acpi.power_nocheck= [HW,ACPI] + Format: 1/0 enable/disable the check of power state. + On some bogus BIOS the _PSC object/_STA object of + power resource can't return the correct device power + state. In such case it is unneccessary to check its + power state again in power transition. + 1 : disable the power state check + acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode Format: { level | edge | high | low } @@ -1855,7 +1863,7 @@ and is between 256 and 4096 characters. It is defined in the file IRQ routing is enabled. noacpi [X86] Do not use ACPI for IRQ routing or for PCI scanning. - use_crs [X86] Use _CRS for PCI resource + nocrs [X86] Don't use _CRS for PCI resource allocation. routeirq Do IRQ routing for all PCI devices. This is normally done in pci_enable_device(), @@ -1915,12 +1923,6 @@ and is between 256 and 4096 characters. It is defined in the file Format: { 0 | 1 } See arch/parisc/kernel/pdc_chassis.c - percpu_alloc= [X86] Select which percpu first chunk allocator to use. - Allowed values are one of "lpage", "embed" and "4k". - See comments in arch/x86/kernel/setup_percpu.c for - details on each allocator. This parameter is primarily - for debugging and performance comparison. - pf. [PARIDE] See Documentation/blockdev/paride.txt. @@ -2473,8 +2475,7 @@ and is between 256 and 4096 characters. It is defined in the file tp720= [HW,PS2] - trace_buf_size=nn[KMG] - [FTRACE] will set tracing buffer size. + trace_buf_size=nn[KMG] [ftrace] will set tracing buffer size. trix= [HW,OSS] MediaTrix AudioTrix Pro Format: diff --git a/trunk/Documentation/kmemleak.txt b/trunk/Documentation/kmemleak.txt index 89068030b01b..0112da3b9ab8 100644 --- a/trunk/Documentation/kmemleak.txt +++ b/trunk/Documentation/kmemleak.txt @@ -16,17 +16,13 @@ Usage ----- CONFIG_DEBUG_KMEMLEAK in "Kernel hacking" has to be enabled. A kernel -thread scans the memory every 10 minutes (by default) and prints the -number of new unreferenced objects found. To display the details of all -the possible memory leaks: +thread scans the memory every 10 minutes (by default) and prints any new +unreferenced objects found. To trigger an intermediate scan and display +all the possible memory leaks: # mount -t debugfs nodev /sys/kernel/debug/ # cat /sys/kernel/debug/kmemleak -To trigger an intermediate memory scan: - - # echo scan > /sys/kernel/debug/kmemleak - Note that the orphan objects are listed in the order they were allocated and one object at the beginning of the list may cause other subsequent objects to be reported as orphan. @@ -35,21 +31,16 @@ Memory scanning parameters can be modified at run-time by writing to the /sys/kernel/debug/kmemleak file. The following parameters are supported: off - disable kmemleak (irreversible) - stack=on - enable the task stacks scanning (default) + stack=on - enable the task stacks scanning stack=off - disable the tasks stacks scanning - scan=on - start the automatic memory scanning thread (default) + scan=on - start the automatic memory scanning thread scan=off - stop the automatic memory scanning thread - scan= - set the automatic memory scanning period in seconds - (default 600, 0 to stop the automatic scanning) - scan - trigger a memory scan + scan= - set the automatic memory scanning period in seconds (0 + to disable it) Kmemleak can also be disabled at boot-time by passing "kmemleak=off" on the kernel command line. -Memory may be allocated or freed before kmemleak is initialised and -these actions are stored in an early log buffer. The size of this buffer -is configured via the CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE option. - Basic Algorithm --------------- diff --git a/trunk/Documentation/laptops/thinkpad-acpi.txt b/trunk/Documentation/laptops/thinkpad-acpi.txt index f2296ecedb89..78e354b42f67 100644 --- a/trunk/Documentation/laptops/thinkpad-acpi.txt +++ b/trunk/Documentation/laptops/thinkpad-acpi.txt @@ -920,7 +920,7 @@ The available commands are: echo ' off' >/proc/acpi/ibm/led echo ' blink' >/proc/acpi/ibm/led -The range is 0 to 15. The set of LEDs that can be +The range is 0 to 7. The set of LEDs that can be controlled varies from model to model. Here is the common ThinkPad mapping: @@ -932,11 +932,6 @@ mapping: 5 - UltraBase battery slot 6 - (unknown) 7 - standby - 8 - dock status 1 - 9 - dock status 2 - 10, 11 - (unknown) - 12 - thinkvantage - 13, 14, 15 - (unknown) All of the above can be turned on and off and can be made to blink. @@ -945,12 +940,10 @@ sysfs notes: The ThinkPad LED sysfs interface is described in detail by the LED class documentation, in Documentation/leds-class.txt. -The LEDs are named (in LED ID order, from 0 to 12): +The leds are named (in LED ID order, from 0 to 7): "tpacpi::power", "tpacpi:orange:batt", "tpacpi:green:batt", "tpacpi::dock_active", "tpacpi::bay_active", "tpacpi::dock_batt", -"tpacpi::unknown_led", "tpacpi::standby", "tpacpi::dock_status1", -"tpacpi::dock_status2", "tpacpi::unknown_led2", "tpacpi::unknown_led3", -"tpacpi::thinkvantage". +"tpacpi::unknown_led", "tpacpi::standby". Due to limitations in the sysfs LED class, if the status of the LED indicators cannot be read due to an error, thinkpad-acpi will report it as @@ -965,12 +958,6 @@ ThinkPad indicator LED should blink in hardware accelerated mode, use the "timer" trigger, and leave the delay_on and delay_off parameters set to zero (to request hardware acceleration autodetection). -LEDs that are known not to exist in a given ThinkPad model are not -made available through the sysfs interface. If you have a dock and you -notice there are LEDs listed for your ThinkPad that do not exist (and -are not in the dock), or if you notice that there are missing LEDs, -a report to ibm-acpi-devel@lists.sourceforge.net is appreciated. - ACPI sounds -- /proc/acpi/ibm/beep ---------------------------------- @@ -1169,19 +1156,17 @@ may not be distinct. Later Lenovo models that implement the ACPI display backlight brightness control methods have 16 levels, ranging from 0 to 15. -For IBM ThinkPads, there are two interfaces to the firmware for direct -brightness control, EC and UCMS (or CMOS). To select which one should be -used, use the brightness_mode module parameter: brightness_mode=1 selects -EC mode, brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC -mode with NVRAM backing (so that brightness changes are remembered across -shutdown/reboot). +There are two interfaces to the firmware for direct brightness control, +EC and UCMS (or CMOS). To select which one should be used, use the +brightness_mode module parameter: brightness_mode=1 selects EC mode, +brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC +mode with NVRAM backing (so that brightness changes are remembered +across shutdown/reboot). The driver tries to select which interface to use from a table of defaults for each ThinkPad model. If it makes a wrong choice, please report this as a bug, so that we can fix it. -Lenovo ThinkPads only support brightness_mode=2 (UCMS). - When display backlight brightness controls are available through the standard ACPI interface, it is best to use it instead of this direct ThinkPad-specific interface. The driver will disable its native @@ -1269,7 +1254,7 @@ Fan control and monitoring: fan speed, fan enable/disable procfs: /proc/acpi/ibm/fan sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1, - pwm1_enable, fan2_input + pwm1_enable sysfs hwmon driver attributes: fan_watchdog NOTE NOTE NOTE: fan control operations are disabled by default for @@ -1282,9 +1267,6 @@ from the hardware registers of the embedded controller. This is known to work on later R, T, X and Z series ThinkPads but may show a bogus value on other models. -Some Lenovo ThinkPads support a secondary fan. This fan cannot be -controlled separately, it shares the main fan control. - Fan levels: Most ThinkPad fans work in "levels" at the firmware interface. Level 0 @@ -1415,11 +1397,6 @@ hwmon device attribute fan1_input: which can take up to two minutes. May return rubbish on older ThinkPads. -hwmon device attribute fan2_input: - Fan tachometer reading, in RPM, for the secondary fan. - Available only on some ThinkPads. If the secondary fan is - not installed, will always read 0. - hwmon driver attribute fan_watchdog: Fan safety watchdog timer interval, in seconds. Minimum is 1 second, maximum is 120 seconds. 0 disables the watchdog. @@ -1578,7 +1555,3 @@ Sysfs interface changelog: 0x020300: hotkey enable/disable support removed, attributes hotkey_bios_enabled and hotkey_enable deprecated and marked for removal. - -0x020400: Marker for 16 LEDs support. Also, LEDs that are known - to not exist in a given model are not registered with - the LED sysfs class anymore. diff --git a/trunk/Documentation/leds-lp3944.txt b/trunk/Documentation/leds-lp3944.txt deleted file mode 100644 index c6eda18b15ef..000000000000 --- a/trunk/Documentation/leds-lp3944.txt +++ /dev/null @@ -1,50 +0,0 @@ -Kernel driver lp3944 -==================== - - * National Semiconductor LP3944 Fun-light Chip - Prefix: 'lp3944' - Addresses scanned: None (see the Notes section below) - Datasheet: Publicly available at the National Semiconductor website - http://www.national.com/pf/LP/LP3944.html - -Authors: - Antonio Ospite - - -Description ------------ -The LP3944 is a helper chip that can drive up to 8 leds, with two programmable -DIM modes; it could even be used as a gpio expander but this driver assumes it -is used as a led controller. - -The DIM modes are used to set _blink_ patterns for leds, the pattern is -specified supplying two parameters: - - period: from 0s to 1.6s - - duty cycle: percentage of the period the led is on, from 0 to 100 - -Setting a led in DIM0 or DIM1 mode makes it blink according to the pattern. -See the datasheet for details. - -LP3944 can be found on Motorola A910 smartphone, where it drives the rgb -leds, the camera flash light and the lcds power. - - -Notes ------ -The chip is used mainly in embedded contexts, so this driver expects it is -registered using the i2c_board_info mechanism. - -To register the chip at address 0x60 on adapter 0, set the platform data -according to include/linux/leds-lp3944.h, set the i2c board info: - - static struct i2c_board_info __initdata a910_i2c_board_info[] = { - { - I2C_BOARD_INFO("lp3944", 0x60), - .platform_data = &a910_lp3944_leds, - }, - }; - -and register it in the platform init function - - i2c_register_board_info(0, a910_i2c_board_info, - ARRAY_SIZE(a910_i2c_board_info)); diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt index 79f533f38c61..8d999d862d0e 100644 --- a/trunk/Documentation/powerpc/booting-without-of.txt +++ b/trunk/Documentation/powerpc/booting-without-of.txt @@ -1238,7 +1238,1122 @@ descriptions for the SOC devices for which new nodes have been defined; this list will expand as more and more SOC-containing platforms are moved over to use the flattened-device-tree model. -VII - Specifying interrupt information for devices + a) PHY nodes + + Required properties: + + - device_type : Should be "ethernet-phy" + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - reg : The ID number for the phy, usually a small integer + - linux,phandle : phandle for this node; likely referenced by an + ethernet controller node. + + + Example: + + ethernet-phy@0 { + linux,phandle = <2452000> + interrupt-parent = <40000>; + interrupts = <35 1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + + + b) Interrupt controllers + + Some SOC devices contain interrupt controllers that are different + from the standard Open PIC specification. The SOC device nodes for + these types of controllers should be specified just like a standard + OpenPIC controller. Sense and level information should be encoded + as specified in section 2) of this chapter for each device that + specifies an interrupt. + + Example : + + pic@40000 { + linux,phandle = <40000>; + interrupt-controller; + #address-cells = <0>; + reg = <40000 40000>; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + }; + + c) 4xx/Axon EMAC ethernet nodes + + The EMAC ethernet controller in IBM and AMCC 4xx chips, and also + the Axon bridge. To operate this needs to interact with a ths + special McMAL DMA controller, and sometimes an RGMII or ZMII + interface. In addition to the nodes and properties described + below, the node for the OPB bus on which the EMAC sits must have a + correct clock-frequency property. + + i) The EMAC node itself + + Required properties: + - device_type : "network" + + - compatible : compatible list, contains 2 entries, first is + "ibm,emac-CHIP" where CHIP is the host ASIC (440gx, + 405gp, Axon) and second is either "ibm,emac" or + "ibm,emac4". For Axon, thus, we have: "ibm,emac-axon", + "ibm,emac4" + - interrupts : + - interrupt-parent : optional, if needed for interrupt mapping + - reg : + - local-mac-address : 6 bytes, MAC address + - mal-device : phandle of the associated McMAL node + - mal-tx-channel : 1 cell, index of the tx channel on McMAL associated + with this EMAC + - mal-rx-channel : 1 cell, index of the rx channel on McMAL associated + with this EMAC + - cell-index : 1 cell, hardware index of the EMAC cell on a given + ASIC (typically 0x0 and 0x1 for EMAC0 and EMAC1 on + each Axon chip) + - max-frame-size : 1 cell, maximum frame size supported in bytes + - rx-fifo-size : 1 cell, Rx fifo size in bytes for 10 and 100 Mb/sec + operations. + For Axon, 2048 + - tx-fifo-size : 1 cell, Tx fifo size in bytes for 10 and 100 Mb/sec + operations. + For Axon, 2048. + - fifo-entry-size : 1 cell, size of a fifo entry (used to calculate + thresholds). + For Axon, 0x00000010 + - mal-burst-size : 1 cell, MAL burst size (used to calculate thresholds) + in bytes. + For Axon, 0x00000100 (I think ...) + - phy-mode : string, mode of operations of the PHY interface. + Supported values are: "mii", "rmii", "smii", "rgmii", + "tbi", "gmii", rtbi", "sgmii". + For Axon on CAB, it is "rgmii" + - mdio-device : 1 cell, required iff using shared MDIO registers + (440EP). phandle of the EMAC to use to drive the + MDIO lines for the PHY used by this EMAC. + - zmii-device : 1 cell, required iff connected to a ZMII. phandle of + the ZMII device node + - zmii-channel : 1 cell, required iff connected to a ZMII. Which ZMII + channel or 0xffffffff if ZMII is only used for MDIO. + - rgmii-device : 1 cell, required iff connected to an RGMII. phandle + of the RGMII device node. + For Axon: phandle of plb5/plb4/opb/rgmii + - rgmii-channel : 1 cell, required iff connected to an RGMII. Which + RGMII channel is used by this EMAC. + Fox Axon: present, whatever value is appropriate for each + EMAC, that is the content of the current (bogus) "phy-port" + property. + + Optional properties: + - phy-address : 1 cell, optional, MDIO address of the PHY. If absent, + a search is performed. + - phy-map : 1 cell, optional, bitmap of addresses to probe the PHY + for, used if phy-address is absent. bit 0x00000001 is + MDIO address 0. + For Axon it can be absent, though my current driver + doesn't handle phy-address yet so for now, keep + 0x00ffffff in it. + - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec + operations (if absent the value is the same as + rx-fifo-size). For Axon, either absent or 2048. + - tx-fifo-size-gige : 1 cell, Tx fifo size in bytes for 1000 Mb/sec + operations (if absent the value is the same as + tx-fifo-size). For Axon, either absent or 2048. + - tah-device : 1 cell, optional. If connected to a TAH engine for + offload, phandle of the TAH device node. + - tah-channel : 1 cell, optional. If appropriate, channel used on the + TAH engine. + + Example: + + EMAC0: ethernet@40000800 { + device_type = "network"; + compatible = "ibm,emac-440gp", "ibm,emac"; + interrupt-parent = <&UIC1>; + interrupts = <1c 4 1d 4>; + reg = <40000800 70>; + local-mac-address = [00 04 AC E3 1B 1E]; + mal-device = <&MAL0>; + mal-tx-channel = <0 1>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <5dc>; + rx-fifo-size = <1000>; + tx-fifo-size = <800>; + phy-mode = "rmii"; + phy-map = <00000001>; + zmii-device = <&ZMII0>; + zmii-channel = <0>; + }; + + ii) McMAL node + + Required properties: + - device_type : "dma-controller" + - compatible : compatible list, containing 2 entries, first is + "ibm,mcmal-CHIP" where CHIP is the host ASIC (like + emac) and the second is either "ibm,mcmal" or + "ibm,mcmal2". + For Axon, "ibm,mcmal-axon","ibm,mcmal2" + - interrupts : . + For Axon: This is _different_ from the current + firmware. We use the "delayed" interrupts for txeob + and rxeob. Thus we end up with mapping those 5 MPIC + interrupts, all level positive sensitive: 10, 11, 32, + 33, 34 (in decimal) + - dcr-reg : < DCR registers range > + - dcr-parent : if needed for dcr-reg + - num-tx-chans : 1 cell, number of Tx channels + - num-rx-chans : 1 cell, number of Rx channels + + iii) ZMII node + + Required properties: + - compatible : compatible list, containing 2 entries, first is + "ibm,zmii-CHIP" where CHIP is the host ASIC (like + EMAC) and the second is "ibm,zmii". + For Axon, there is no ZMII node. + - reg : + + iv) RGMII node + + Required properties: + - compatible : compatible list, containing 2 entries, first is + "ibm,rgmii-CHIP" where CHIP is the host ASIC (like + EMAC) and the second is "ibm,rgmii". + For Axon, "ibm,rgmii-axon","ibm,rgmii" + - reg : + - revision : as provided by the RGMII new version register if + available. + For Axon: 0x0000012a + + d) Xilinx IP cores + + The Xilinx EDK toolchain ships with a set of IP cores (devices) for use + in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range + of standard device types (network, serial, etc.) and miscellaneous + devices (gpio, LCD, spi, etc). Also, since these devices are + implemented within the fpga fabric every instance of the device can be + synthesised with different options that change the behaviour. + + Each IP-core has a set of parameters which the FPGA designer can use to + control how the core is synthesized. Historically, the EDK tool would + extract the device parameters relevant to device drivers and copy them + into an 'xparameters.h' in the form of #define symbols. This tells the + device drivers how the IP cores are configured, but it requres the kernel + to be recompiled every time the FPGA bitstream is resynthesized. + + The new approach is to export the parameters into the device tree and + generate a new device tree each time the FPGA bitstream changes. The + parameters which used to be exported as #defines will now become + properties of the device node. In general, device nodes for IP-cores + will take the following form: + + (name): (generic-name)@(base-address) { + compatible = "xlnx,(ip-core-name)-(HW_VER)" + [, (list of compatible devices), ...]; + reg = <(baseaddr) (size)>; + interrupt-parent = <&interrupt-controller-phandle>; + interrupts = < ... >; + xlnx,(parameter1) = "(string-value)"; + xlnx,(parameter2) = <(int-value)>; + }; + + (generic-name): an open firmware-style name that describes the + generic class of device. Preferably, this is one word, such + as 'serial' or 'ethernet'. + (ip-core-name): the name of the ip block (given after the BEGIN + directive in system.mhs). Should be in lowercase + and all underscores '_' converted to dashes '-'. + (name): is derived from the "PARAMETER INSTANCE" value. + (parameter#): C_* parameters from system.mhs. The C_ prefix is + dropped from the parameter name, the name is converted + to lowercase and all underscore '_' characters are + converted to dashes '-'. + (baseaddr): the baseaddr parameter value (often named C_BASEADDR). + (HW_VER): from the HW_VER parameter. + (size): the address range size (often C_HIGHADDR - C_BASEADDR + 1). + + Typically, the compatible list will include the exact IP core version + followed by an older IP core version which implements the same + interface or any other device with the same interface. + + 'reg', 'interrupt-parent' and 'interrupts' are all optional properties. + + For example, the following block from system.mhs: + + BEGIN opb_uartlite + PARAMETER INSTANCE = opb_uartlite_0 + PARAMETER HW_VER = 1.00.b + PARAMETER C_BAUDRATE = 115200 + PARAMETER C_DATA_BITS = 8 + PARAMETER C_ODD_PARITY = 0 + PARAMETER C_USE_PARITY = 0 + PARAMETER C_CLK_FREQ = 50000000 + PARAMETER C_BASEADDR = 0xEC100000 + PARAMETER C_HIGHADDR = 0xEC10FFFF + BUS_INTERFACE SOPB = opb_7 + PORT OPB_Clk = CLK_50MHz + PORT Interrupt = opb_uartlite_0_Interrupt + PORT RX = opb_uartlite_0_RX + PORT TX = opb_uartlite_0_TX + PORT OPB_Rst = sys_bus_reset_0 + END + + becomes the following device tree node: + + opb_uartlite_0: serial@ec100000 { + device_type = "serial"; + compatible = "xlnx,opb-uartlite-1.00.b"; + reg = ; + interrupt-parent = <&opb_intc_0>; + interrupts = <1 0>; // got this from the opb_intc parameters + current-speed = ; // standard serial device prop + clock-frequency = ; // standard serial device prop + xlnx,data-bits = <8>; + xlnx,odd-parity = <0>; + xlnx,use-parity = <0>; + }; + + Some IP cores actually implement 2 or more logical devices. In + this case, the device should still describe the whole IP core with + a single node and add a child node for each logical device. The + ranges property can be used to translate from parent IP-core to the + registers of each device. In addition, the parent node should be + compatible with the bus type 'xlnx,compound', and should contain + #address-cells and #size-cells, as with any other bus. (Note: this + makes the assumption that both logical devices have the same bus + binding. If this is not true, then separate nodes should be used + for each logical device). The 'cell-index' property can be used to + enumerate logical devices within an IP core. For example, the + following is the system.mhs entry for the dual ps2 controller found + on the ml403 reference design. + + BEGIN opb_ps2_dual_ref + PARAMETER INSTANCE = opb_ps2_dual_ref_0 + PARAMETER HW_VER = 1.00.a + PARAMETER C_BASEADDR = 0xA9000000 + PARAMETER C_HIGHADDR = 0xA9001FFF + BUS_INTERFACE SOPB = opb_v20_0 + PORT Sys_Intr1 = ps2_1_intr + PORT Sys_Intr2 = ps2_2_intr + PORT Clkin1 = ps2_clk_rx_1 + PORT Clkin2 = ps2_clk_rx_2 + PORT Clkpd1 = ps2_clk_tx_1 + PORT Clkpd2 = ps2_clk_tx_2 + PORT Rx1 = ps2_d_rx_1 + PORT Rx2 = ps2_d_rx_2 + PORT Txpd1 = ps2_d_tx_1 + PORT Txpd2 = ps2_d_tx_2 + END + + It would result in the following device tree nodes: + + opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,compound"; + ranges = <0 a9000000 2000>; + // If this device had extra parameters, then they would + // go here. + ps2@0 { + compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; + reg = <0 40>; + interrupt-parent = <&opb_intc_0>; + interrupts = <3 0>; + cell-index = <0>; + }; + ps2@1000 { + compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; + reg = <1000 40>; + interrupt-parent = <&opb_intc_0>; + interrupts = <3 0>; + cell-index = <0>; + }; + }; + + Also, the system.mhs file defines bus attachments from the processor + to the devices. The device tree structure should reflect the bus + attachments. Again an example; this system.mhs fragment: + + BEGIN ppc405_virtex4 + PARAMETER INSTANCE = ppc405_0 + PARAMETER HW_VER = 1.01.a + BUS_INTERFACE DPLB = plb_v34_0 + BUS_INTERFACE IPLB = plb_v34_0 + END + + BEGIN opb_intc + PARAMETER INSTANCE = opb_intc_0 + PARAMETER HW_VER = 1.00.c + PARAMETER C_BASEADDR = 0xD1000FC0 + PARAMETER C_HIGHADDR = 0xD1000FDF + BUS_INTERFACE SOPB = opb_v20_0 + END + + BEGIN opb_uart16550 + PARAMETER INSTANCE = opb_uart16550_0 + PARAMETER HW_VER = 1.00.d + PARAMETER C_BASEADDR = 0xa0000000 + PARAMETER C_HIGHADDR = 0xa0001FFF + BUS_INTERFACE SOPB = opb_v20_0 + END + + BEGIN plb_v34 + PARAMETER INSTANCE = plb_v34_0 + PARAMETER HW_VER = 1.02.a + END + + BEGIN plb_bram_if_cntlr + PARAMETER INSTANCE = plb_bram_if_cntlr_0 + PARAMETER HW_VER = 1.00.b + PARAMETER C_BASEADDR = 0xFFFF0000 + PARAMETER C_HIGHADDR = 0xFFFFFFFF + BUS_INTERFACE SPLB = plb_v34_0 + END + + BEGIN plb2opb_bridge + PARAMETER INSTANCE = plb2opb_bridge_0 + PARAMETER HW_VER = 1.01.a + PARAMETER C_RNG0_BASEADDR = 0x20000000 + PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF + PARAMETER C_RNG1_BASEADDR = 0x60000000 + PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF + PARAMETER C_RNG2_BASEADDR = 0x80000000 + PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF + PARAMETER C_RNG3_BASEADDR = 0xC0000000 + PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF + BUS_INTERFACE SPLB = plb_v34_0 + BUS_INTERFACE MOPB = opb_v20_0 + END + + Gives this device tree (some properties removed for clarity): + + plb@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,plb-v34-1.02.a"; + device_type = "ibm,plb"; + ranges; // 1:1 translation + + plb_bram_if_cntrl_0: bram@ffff0000 { + reg = ; + } + + opb@20000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <20000000 20000000 20000000 + 60000000 60000000 20000000 + 80000000 80000000 40000000 + c0000000 c0000000 20000000>; + + opb_uart16550_0: serial@a0000000 { + reg = ; + }; + + opb_intc_0: interrupt-controller@d1000fc0 { + reg = ; + }; + }; + }; + + That covers the general approach to binding xilinx IP cores into the + device tree. The following are bindings for specific devices: + + i) Xilinx ML300 Framebuffer + + Simple framebuffer device from the ML300 reference design (also on the + ML403 reference design as well as others). + + Optional properties: + - resolution = : pixel resolution of framebuffer. Some + implementations use a different resolution. + Default is + - virt-resolution = : Size of framebuffer in memory. + Default is . + - rotate-display (empty) : rotate display 180 degrees. + + ii) Xilinx SystemACE + + The Xilinx SystemACE device is used to program FPGAs from an FPGA + bitstream stored on a CF card. It can also be used as a generic CF + interface device. + + Optional properties: + - 8-bit (empty) : Set this property for SystemACE in 8 bit mode + + iii) Xilinx EMAC and Xilinx TEMAC + + Xilinx Ethernet devices. In addition to general xilinx properties + listed above, nodes for these devices should include a phy-handle + property, and may include other common network device properties + like local-mac-address. + + iv) Xilinx Uartlite + + Xilinx uartlite devices are simple fixed speed serial ports. + + Required properties: + - current-speed : Baud rate of uartlite + + v) Xilinx hwicap + + Xilinx hwicap devices provide access to the configuration logic + of the FPGA through the Internal Configuration Access Port + (ICAP). The ICAP enables partial reconfiguration of the FPGA, + readback of the configuration information, and some control over + 'warm boots' of the FPGA fabric. + + Required properties: + - xlnx,family : The family of the FPGA, necessary since the + capabilities of the underlying ICAP hardware + differ between different families. May be + 'virtex2p', 'virtex4', or 'virtex5'. + + vi) Xilinx Uart 16550 + + Xilinx UART 16550 devices are very similar to the NS16550 but with + different register spacing and an offset from the base address. + + Required properties: + - clock-frequency : Frequency of the clock input + - reg-offset : A value of 3 is required + - reg-shift : A value of 2 is required + + e) USB EHCI controllers + + Required properties: + - compatible : should be "usb-ehci". + - reg : should contain at least address and length of the standard EHCI + register set for the device. Optional platform-dependent registers + (debug-port or other) can be also specified here, but only after + definition of standard EHCI registers. + - interrupts : one EHCI interrupt should be described here. + If device registers are implemented in big endian mode, the device + node should have "big-endian-regs" property. + If controller implementation operates with big endian descriptors, + "big-endian-desc" property should be specified. + If both big endian registers and descriptors are used by the controller + implementation, "big-endian" property can be specified instead of having + both "big-endian-regs" and "big-endian-desc". + + Example (Sequoia 440EPx): + ehci@e0000300 { + compatible = "ibm,usb-ehci-440epx", "usb-ehci"; + interrupt-parent = <&UIC0>; + interrupts = <1a 4>; + reg = <0 e0000300 90 0 e0000390 70>; + big-endian; + }; + + f) MDIO on GPIOs + + Currently defined compatibles: + - virtual,gpio-mdio + + MDC and MDIO lines connected to GPIO controllers are listed in the + gpios property as described in section VIII.1 in the following order: + + MDC, MDIO. + + Example: + + mdio { + compatible = "virtual,mdio-gpio"; + #address-cells = <1>; + #size-cells = <0>; + gpios = <&qe_pio_a 11 + &qe_pio_c 6>; + }; + + g) SPI (Serial Peripheral Interface) busses + + SPI busses can be described with a node for the SPI master device + and a set of child nodes for each SPI slave on the bus. For this + discussion, it is assumed that the system's SPI controller is in + SPI master mode. This binding does not describe SPI controllers + in slave mode. + + The SPI master node requires the following properties: + - #address-cells - number of cells required to define a chip select + address on the SPI bus. + - #size-cells - should be zero. + - compatible - name of SPI bus controller following generic names + recommended practice. + No other properties are required in the SPI bus node. It is assumed + that a driver for an SPI bus device will understand that it is an SPI bus. + However, the binding does not attempt to define the specific method for + assigning chip select numbers. Since SPI chip select configuration is + flexible and non-standardized, it is left out of this binding with the + assumption that board specific platform code will be used to manage + chip selects. Individual drivers can define additional properties to + support describing the chip select layout. + + SPI slave nodes must be children of the SPI master node and can + contain the following properties. + - reg - (required) chip select address of device. + - compatible - (required) name of SPI device following generic names + recommended practice + - spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz + - spi-cpol - (optional) Empty property indicating device requires + inverse clock polarity (CPOL) mode + - spi-cpha - (optional) Empty property indicating device requires + shifted clock phase (CPHA) mode + - spi-cs-high - (optional) Empty property indicating device requires + chip select active high + + SPI example for an MPC5200 SPI bus: + spi@f00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; + reg = <0xf00 0x20>; + interrupts = <2 13 0 2 14 0>; + interrupt-parent = <&mpc5200_pic>; + + ethernet-switch@0 { + compatible = "micrel,ks8995m"; + spi-max-frequency = <1000000>; + reg = <0>; + }; + + codec@1 { + compatible = "ti,tlv320aic26"; + spi-max-frequency = <100000>; + reg = <1>; + }; + }; + +VII - Marvell Discovery mv64[345]6x System Controller chips +=========================================================== + +The Marvell mv64[345]60 series of system controller chips contain +many of the peripherals needed to implement a complete computer +system. In this section, we define device tree nodes to describe +the system controller chip itself and each of the peripherals +which it contains. Compatible string values for each node are +prefixed with the string "marvell,", for Marvell Technology Group Ltd. + +1) The /system-controller node + + This node is used to represent the system-controller and must be + present when the system uses a system controller chip. The top-level + system-controller node contains information that is global to all + devices within the system controller chip. The node name begins + with "system-controller" followed by the unit address, which is + the base address of the memory-mapped register set for the system + controller chip. + + Required properties: + + - ranges : Describes the translation of system controller addresses + for memory mapped registers. + - clock-frequency: Contains the main clock frequency for the system + controller chip. + - reg : This property defines the address and size of the + memory-mapped registers contained within the system controller + chip. The address specified in the "reg" property should match + the unit address of the system-controller node. + - #address-cells : Address representation for system controller + devices. This field represents the number of cells needed to + represent the address of the memory-mapped registers of devices + within the system controller chip. + - #size-cells : Size representation for for the memory-mapped + registers within the system controller chip. + - #interrupt-cells : Defines the width of cells used to represent + interrupts. + + Optional properties: + + - model : The specific model of the system controller chip. Such + as, "mv64360", "mv64460", or "mv64560". + - compatible : A string identifying the compatibility identifiers + of the system controller chip. + + The system-controller node contains child nodes for each system + controller device that the platform uses. Nodes should not be created + for devices which exist on the system controller chip but are not used + + Example Marvell Discovery mv64360 system-controller node: + + system-controller@f1000000 { /* Marvell Discovery mv64360 */ + #address-cells = <1>; + #size-cells = <1>; + model = "mv64360"; /* Default */ + compatible = "marvell,mv64360"; + clock-frequency = <133333333>; + reg = <0xf1000000 0x10000>; + virtual-reg = <0xf1000000>; + ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */ + 0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */ + 0xa0000000 0xa0000000 0x4000000 /* User FLASH */ + 0x00000000 0xf1000000 0x0010000 /* Bridge's regs */ + 0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */ + + [ child node definitions... ] + } + +2) Child nodes of /system-controller + + a) Marvell Discovery MDIO bus + + The MDIO is a bus to which the PHY devices are connected. For each + device that exists on this bus, a child node should be created. See + the definition of the PHY node below for an example of how to define + a PHY. + + Required properties: + - #address-cells : Should be <1> + - #size-cells : Should be <0> + - device_type : Should be "mdio" + - compatible : Should be "marvell,mv64360-mdio" + + Example: + + mdio { + #address-cells = <1>; + #size-cells = <0>; + device_type = "mdio"; + compatible = "marvell,mv64360-mdio"; + + ethernet-phy@0 { + ...... + }; + }; + + + b) Marvell Discovery ethernet controller + + The Discover ethernet controller is described with two levels + of nodes. The first level describes an ethernet silicon block + and the second level describes up to 3 ethernet nodes within + that block. The reason for the multiple levels is that the + registers for the node are interleaved within a single set + of registers. The "ethernet-block" level describes the + shared register set, and the "ethernet" nodes describe ethernet + port-specific properties. + + Ethernet block node + + Required properties: + - #address-cells : <1> + - #size-cells : <0> + - compatible : "marvell,mv64360-eth-block" + - reg : Offset and length of the register set for this block + + Example Discovery Ethernet block node: + ethernet-block@2000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "marvell,mv64360-eth-block"; + reg = <0x2000 0x2000>; + ethernet@0 { + ....... + }; + }; + + Ethernet port node + + Required properties: + - device_type : Should be "network". + - compatible : Should be "marvell,mv64360-eth". + - reg : Should be <0>, <1>, or <2>, according to which registers + within the silicon block the device uses. + - interrupts : where a is the interrupt number for the port. + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + - phy : the phandle for the PHY connected to this ethernet + controller. + - local-mac-address : 6 bytes, MAC address + + Example Discovery Ethernet port node: + ethernet@0 { + device_type = "network"; + compatible = "marvell,mv64360-eth"; + reg = <0>; + interrupts = <32>; + interrupt-parent = <&PIC>; + phy = <&PHY0>; + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + + + + c) Marvell Discovery PHY nodes + + Required properties: + - device_type : Should be "ethernet-phy" + - interrupts : where a is the interrupt number for this phy. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - reg : The ID number for the phy, usually a small integer + + Example Discovery PHY node: + ethernet-phy@1 { + device_type = "ethernet-phy"; + compatible = "broadcom,bcm5421"; + interrupts = <76>; /* GPP 12 */ + interrupt-parent = <&PIC>; + reg = <1>; + }; + + + d) Marvell Discovery SDMA nodes + + Represent DMA hardware associated with the MPSC (multiprotocol + serial controllers). + + Required properties: + - compatible : "marvell,mv64360-sdma" + - reg : Offset and length of the register set for this device + - interrupts : where a is the interrupt number for the DMA + device. + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery SDMA node: + sdma@4000 { + compatible = "marvell,mv64360-sdma"; + reg = <0x4000 0xc18>; + virtual-reg = <0xf1004000>; + interrupts = <36>; + interrupt-parent = <&PIC>; + }; + + + e) Marvell Discovery BRG nodes + + Represent baud rate generator hardware associated with the MPSC + (multiprotocol serial controllers). + + Required properties: + - compatible : "marvell,mv64360-brg" + - reg : Offset and length of the register set for this device + - clock-src : A value from 0 to 15 which selects the clock + source for the baud rate generator. This value corresponds + to the CLKS value in the BRGx configuration register. See + the mv64x60 User's Manual. + - clock-frequence : The frequency (in Hz) of the baud rate + generator's input clock. + - current-speed : The current speed setting (presumably by + firmware) of the baud rate generator. + + Example Discovery BRG node: + brg@b200 { + compatible = "marvell,mv64360-brg"; + reg = <0xb200 0x8>; + clock-src = <8>; + clock-frequency = <133333333>; + current-speed = <9600>; + }; + + + f) Marvell Discovery CUNIT nodes + + Represent the Serial Communications Unit device hardware. + + Required properties: + - reg : Offset and length of the register set for this device + + Example Discovery CUNIT node: + cunit@f200 { + reg = <0xf200 0x200>; + }; + + + g) Marvell Discovery MPSCROUTING nodes + + Represent the Discovery's MPSC routing hardware + + Required properties: + - reg : Offset and length of the register set for this device + + Example Discovery CUNIT node: + mpscrouting@b500 { + reg = <0xb400 0xc>; + }; + + + h) Marvell Discovery MPSCINTR nodes + + Represent the Discovery's MPSC DMA interrupt hardware registers + (SDMA cause and mask registers). + + Required properties: + - reg : Offset and length of the register set for this device + + Example Discovery MPSCINTR node: + mpsintr@b800 { + reg = <0xb800 0x100>; + }; + + + i) Marvell Discovery MPSC nodes + + Represent the Discovery's MPSC (Multiprotocol Serial Controller) + serial port. + + Required properties: + - device_type : "serial" + - compatible : "marvell,mv64360-mpsc" + - reg : Offset and length of the register set for this device + - sdma : the phandle for the SDMA node used by this port + - brg : the phandle for the BRG node used by this port + - cunit : the phandle for the CUNIT node used by this port + - mpscrouting : the phandle for the MPSCROUTING node used by this port + - mpscintr : the phandle for the MPSCINTR node used by this port + - cell-index : the hardware index of this cell in the MPSC core + - max_idle : value needed for MPSC CHR3 (Maximum Frame Length) + register + - interrupts : where a is the interrupt number for the MPSC. + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery MPSCINTR node: + mpsc@8000 { + device_type = "serial"; + compatible = "marvell,mv64360-mpsc"; + reg = <0x8000 0x38>; + virtual-reg = <0xf1008000>; + sdma = <&SDMA0>; + brg = <&BRG0>; + cunit = <&CUNIT>; + mpscrouting = <&MPSCROUTING>; + mpscintr = <&MPSCINTR>; + cell-index = <0>; + max_idle = <40>; + interrupts = <40>; + interrupt-parent = <&PIC>; + }; + + + j) Marvell Discovery Watch Dog Timer nodes + + Represent the Discovery's watchdog timer hardware + + Required properties: + - compatible : "marvell,mv64360-wdt" + - reg : Offset and length of the register set for this device + + Example Discovery Watch Dog Timer node: + wdt@b410 { + compatible = "marvell,mv64360-wdt"; + reg = <0xb410 0x8>; + }; + + + k) Marvell Discovery I2C nodes + + Represent the Discovery's I2C hardware + + Required properties: + - device_type : "i2c" + - compatible : "marvell,mv64360-i2c" + - reg : Offset and length of the register set for this device + - interrupts : where a is the interrupt number for the I2C. + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery I2C node: + compatible = "marvell,mv64360-i2c"; + reg = <0xc000 0x20>; + virtual-reg = <0xf100c000>; + interrupts = <37>; + interrupt-parent = <&PIC>; + }; + + + l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes + + Represent the Discovery's PIC hardware + + Required properties: + - #interrupt-cells : <1> + - #address-cells : <0> + - compatible : "marvell,mv64360-pic" + - reg : Offset and length of the register set for this device + - interrupt-controller + + Example Discovery PIC node: + pic { + #interrupt-cells = <1>; + #address-cells = <0>; + compatible = "marvell,mv64360-pic"; + reg = <0x0 0x88>; + interrupt-controller; + }; + + + m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes + + Represent the Discovery's MPP hardware + + Required properties: + - compatible : "marvell,mv64360-mpp" + - reg : Offset and length of the register set for this device + + Example Discovery MPP node: + mpp@f000 { + compatible = "marvell,mv64360-mpp"; + reg = <0xf000 0x10>; + }; + + + n) Marvell Discovery GPP (General Purpose Pins) nodes + + Represent the Discovery's GPP hardware + + Required properties: + - compatible : "marvell,mv64360-gpp" + - reg : Offset and length of the register set for this device + + Example Discovery GPP node: + gpp@f000 { + compatible = "marvell,mv64360-gpp"; + reg = <0xf100 0x20>; + }; + + + o) Marvell Discovery PCI host bridge node + + Represents the Discovery's PCI host bridge device. The properties + for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE + 1275-1994. A typical value for the compatible property is + "marvell,mv64360-pci". + + Example Discovery PCI host bridge node + pci@80000000 { + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "marvell,mv64360-pci"; + reg = <0xcf8 0x8>; + ranges = <0x01000000 0x0 0x0 + 0x88000000 0x0 0x01000000 + 0x02000000 0x0 0x80000000 + 0x80000000 0x0 0x08000000>; + bus-range = <0 255>; + clock-frequency = <66000000>; + interrupt-parent = <&PIC>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = < + /* IDSEL 0x0a */ + 0x5000 0 0 1 &PIC 80 + 0x5000 0 0 2 &PIC 81 + 0x5000 0 0 3 &PIC 91 + 0x5000 0 0 4 &PIC 93 + + /* IDSEL 0x0b */ + 0x5800 0 0 1 &PIC 91 + 0x5800 0 0 2 &PIC 93 + 0x5800 0 0 3 &PIC 80 + 0x5800 0 0 4 &PIC 81 + + /* IDSEL 0x0c */ + 0x6000 0 0 1 &PIC 91 + 0x6000 0 0 2 &PIC 93 + 0x6000 0 0 3 &PIC 80 + 0x6000 0 0 4 &PIC 81 + + /* IDSEL 0x0d */ + 0x6800 0 0 1 &PIC 93 + 0x6800 0 0 2 &PIC 80 + 0x6800 0 0 3 &PIC 81 + 0x6800 0 0 4 &PIC 91 + >; + }; + + + p) Marvell Discovery CPU Error nodes + + Represent the Discovery's CPU error handler device. + + Required properties: + - compatible : "marvell,mv64360-cpu-error" + - reg : Offset and length of the register set for this device + - interrupts : the interrupt number for this device + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery CPU Error node: + cpu-error@0070 { + compatible = "marvell,mv64360-cpu-error"; + reg = <0x70 0x10 0x128 0x28>; + interrupts = <3>; + interrupt-parent = <&PIC>; + }; + + + q) Marvell Discovery SRAM Controller nodes + + Represent the Discovery's SRAM controller device. + + Required properties: + - compatible : "marvell,mv64360-sram-ctrl" + - reg : Offset and length of the register set for this device + - interrupts : the interrupt number for this device + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery SRAM Controller node: + sram-ctrl@0380 { + compatible = "marvell,mv64360-sram-ctrl"; + reg = <0x380 0x80>; + interrupts = <13>; + interrupt-parent = <&PIC>; + }; + + + r) Marvell Discovery PCI Error Handler nodes + + Represent the Discovery's PCI error handler device. + + Required properties: + - compatible : "marvell,mv64360-pci-error" + - reg : Offset and length of the register set for this device + - interrupts : the interrupt number for this device + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery PCI Error Handler node: + pci-error@1d40 { + compatible = "marvell,mv64360-pci-error"; + reg = <0x1d40 0x40 0xc28 0x4>; + interrupts = <12>; + interrupt-parent = <&PIC>; + }; + + + s) Marvell Discovery Memory Controller nodes + + Represent the Discovery's memory controller device. + + Required properties: + - compatible : "marvell,mv64360-mem-ctrl" + - reg : Offset and length of the register set for this device + - interrupts : the interrupt number for this device + - interrupt-parent : the phandle for the interrupt controller + that services interrupts for this device. + + Example Discovery Memory Controller node: + mem-ctrl@1400 { + compatible = "marvell,mv64360-mem-ctrl"; + reg = <0x1400 0x60>; + interrupts = <17>; + interrupt-parent = <&PIC>; + }; + + +VIII - Specifying interrupt information for devices =================================================== The device tree represents the busses and devices of a hardware @@ -1324,7 +2439,56 @@ encodings listed below: 2 = high to low edge sensitive type enabled 3 = low to high edge sensitive type enabled -VIII - Specifying Device Power Management Information (sleep property) +IX - Specifying GPIO information for devices +============================================ + +1) gpios property +----------------- + +Nodes that makes use of GPIOs should define them using `gpios' property, +format of which is: <&gpio-controller1-phandle gpio1-specifier + &gpio-controller2-phandle gpio2-specifier + 0 /* holes are permitted, means no GPIO 3 */ + &gpio-controller4-phandle gpio4-specifier + ...>; + +Note that gpio-specifier length is controller dependent. + +gpio-specifier may encode: bank, pin position inside the bank, +whether pin is open-drain and whether pin is logically inverted. + +Example of the node using GPIOs: + + node { + gpios = <&qe_pio_e 18 0>; + }; + +In this example gpio-specifier is "18 0" and encodes GPIO pin number, +and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller. + +2) gpio-controller nodes +------------------------ + +Every GPIO controller node must have #gpio-cells property defined, +this information will be used to translate gpio-specifiers. + +Example of two SOC GPIO banks defined as gpio-controller nodes: + + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller; + }; + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; + +X - Specifying Device Power Management Information (sleep property) =================================================================== Devices on SOCs often have mechanisms for placing devices into low-power diff --git a/trunk/Documentation/powerpc/dts-bindings/4xx/emac.txt b/trunk/Documentation/powerpc/dts-bindings/4xx/emac.txt deleted file mode 100644 index 2161334a7ca5..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/4xx/emac.txt +++ /dev/null @@ -1,148 +0,0 @@ - 4xx/Axon EMAC ethernet nodes - - The EMAC ethernet controller in IBM and AMCC 4xx chips, and also - the Axon bridge. To operate this needs to interact with a ths - special McMAL DMA controller, and sometimes an RGMII or ZMII - interface. In addition to the nodes and properties described - below, the node for the OPB bus on which the EMAC sits must have a - correct clock-frequency property. - - i) The EMAC node itself - - Required properties: - - device_type : "network" - - - compatible : compatible list, contains 2 entries, first is - "ibm,emac-CHIP" where CHIP is the host ASIC (440gx, - 405gp, Axon) and second is either "ibm,emac" or - "ibm,emac4". For Axon, thus, we have: "ibm,emac-axon", - "ibm,emac4" - - interrupts : - - interrupt-parent : optional, if needed for interrupt mapping - - reg : - - local-mac-address : 6 bytes, MAC address - - mal-device : phandle of the associated McMAL node - - mal-tx-channel : 1 cell, index of the tx channel on McMAL associated - with this EMAC - - mal-rx-channel : 1 cell, index of the rx channel on McMAL associated - with this EMAC - - cell-index : 1 cell, hardware index of the EMAC cell on a given - ASIC (typically 0x0 and 0x1 for EMAC0 and EMAC1 on - each Axon chip) - - max-frame-size : 1 cell, maximum frame size supported in bytes - - rx-fifo-size : 1 cell, Rx fifo size in bytes for 10 and 100 Mb/sec - operations. - For Axon, 2048 - - tx-fifo-size : 1 cell, Tx fifo size in bytes for 10 and 100 Mb/sec - operations. - For Axon, 2048. - - fifo-entry-size : 1 cell, size of a fifo entry (used to calculate - thresholds). - For Axon, 0x00000010 - - mal-burst-size : 1 cell, MAL burst size (used to calculate thresholds) - in bytes. - For Axon, 0x00000100 (I think ...) - - phy-mode : string, mode of operations of the PHY interface. - Supported values are: "mii", "rmii", "smii", "rgmii", - "tbi", "gmii", rtbi", "sgmii". - For Axon on CAB, it is "rgmii" - - mdio-device : 1 cell, required iff using shared MDIO registers - (440EP). phandle of the EMAC to use to drive the - MDIO lines for the PHY used by this EMAC. - - zmii-device : 1 cell, required iff connected to a ZMII. phandle of - the ZMII device node - - zmii-channel : 1 cell, required iff connected to a ZMII. Which ZMII - channel or 0xffffffff if ZMII is only used for MDIO. - - rgmii-device : 1 cell, required iff connected to an RGMII. phandle - of the RGMII device node. - For Axon: phandle of plb5/plb4/opb/rgmii - - rgmii-channel : 1 cell, required iff connected to an RGMII. Which - RGMII channel is used by this EMAC. - Fox Axon: present, whatever value is appropriate for each - EMAC, that is the content of the current (bogus) "phy-port" - property. - - Optional properties: - - phy-address : 1 cell, optional, MDIO address of the PHY. If absent, - a search is performed. - - phy-map : 1 cell, optional, bitmap of addresses to probe the PHY - for, used if phy-address is absent. bit 0x00000001 is - MDIO address 0. - For Axon it can be absent, though my current driver - doesn't handle phy-address yet so for now, keep - 0x00ffffff in it. - - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec - operations (if absent the value is the same as - rx-fifo-size). For Axon, either absent or 2048. - - tx-fifo-size-gige : 1 cell, Tx fifo size in bytes for 1000 Mb/sec - operations (if absent the value is the same as - tx-fifo-size). For Axon, either absent or 2048. - - tah-device : 1 cell, optional. If connected to a TAH engine for - offload, phandle of the TAH device node. - - tah-channel : 1 cell, optional. If appropriate, channel used on the - TAH engine. - - Example: - - EMAC0: ethernet@40000800 { - device_type = "network"; - compatible = "ibm,emac-440gp", "ibm,emac"; - interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = <40000800 70>; - local-mac-address = [00 04 AC E3 1B 1E]; - mal-device = <&MAL0>; - mal-tx-channel = <0 1>; - mal-rx-channel = <0>; - cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; - phy-mode = "rmii"; - phy-map = <00000001>; - zmii-device = <&ZMII0>; - zmii-channel = <0>; - }; - - ii) McMAL node - - Required properties: - - device_type : "dma-controller" - - compatible : compatible list, containing 2 entries, first is - "ibm,mcmal-CHIP" where CHIP is the host ASIC (like - emac) and the second is either "ibm,mcmal" or - "ibm,mcmal2". - For Axon, "ibm,mcmal-axon","ibm,mcmal2" - - interrupts : . - For Axon: This is _different_ from the current - firmware. We use the "delayed" interrupts for txeob - and rxeob. Thus we end up with mapping those 5 MPIC - interrupts, all level positive sensitive: 10, 11, 32, - 33, 34 (in decimal) - - dcr-reg : < DCR registers range > - - dcr-parent : if needed for dcr-reg - - num-tx-chans : 1 cell, number of Tx channels - - num-rx-chans : 1 cell, number of Rx channels - - iii) ZMII node - - Required properties: - - compatible : compatible list, containing 2 entries, first is - "ibm,zmii-CHIP" where CHIP is the host ASIC (like - EMAC) and the second is "ibm,zmii". - For Axon, there is no ZMII node. - - reg : - - iv) RGMII node - - Required properties: - - compatible : compatible list, containing 2 entries, first is - "ibm,rgmii-CHIP" where CHIP is the host ASIC (like - EMAC) and the second is "ibm,rgmii". - For Axon, "ibm,rgmii-axon","ibm,rgmii" - - reg : - - revision : as provided by the RGMII new version register if - available. - For Axon: 0x0000012a - diff --git a/trunk/Documentation/powerpc/dts-bindings/gpio/gpio.txt b/trunk/Documentation/powerpc/dts-bindings/gpio/gpio.txt deleted file mode 100644 index edaa84d288a1..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/gpio/gpio.txt +++ /dev/null @@ -1,50 +0,0 @@ -Specifying GPIO information for devices -============================================ - -1) gpios property ------------------ - -Nodes that makes use of GPIOs should define them using `gpios' property, -format of which is: <&gpio-controller1-phandle gpio1-specifier - &gpio-controller2-phandle gpio2-specifier - 0 /* holes are permitted, means no GPIO 3 */ - &gpio-controller4-phandle gpio4-specifier - ...>; - -Note that gpio-specifier length is controller dependent. - -gpio-specifier may encode: bank, pin position inside the bank, -whether pin is open-drain and whether pin is logically inverted. - -Example of the node using GPIOs: - - node { - gpios = <&qe_pio_e 18 0>; - }; - -In this example gpio-specifier is "18 0" and encodes GPIO pin number, -and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller. - -2) gpio-controller nodes ------------------------- - -Every GPIO controller node must have #gpio-cells property defined, -this information will be used to translate gpio-specifiers. - -Example of two SOC GPIO banks defined as gpio-controller nodes: - - qe_pio_a: gpio-controller@1400 { - #gpio-cells = <2>; - compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; - reg = <0x1400 0x18>; - gpio-controller; - }; - - qe_pio_e: gpio-controller@1460 { - #gpio-cells = <2>; - compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; - reg = <0x1460 0x18>; - gpio-controller; - }; - - diff --git a/trunk/Documentation/powerpc/dts-bindings/gpio/led.txt b/trunk/Documentation/powerpc/dts-bindings/gpio/led.txt index 064db928c3c1..4fe14deedc0a 100644 --- a/trunk/Documentation/powerpc/dts-bindings/gpio/led.txt +++ b/trunk/Documentation/powerpc/dts-bindings/gpio/led.txt @@ -16,17 +16,10 @@ LED sub-node properties: string defining the trigger assigned to the LED. Current triggers are: "backlight" - LED will act as a back-light, controlled by the framebuffer system - "default-on" - LED will turn on, but see "default-state" below + "default-on" - LED will turn on "heartbeat" - LED "double" flashes at a load average based rate "ide-disk" - LED indicates disk activity "timer" - LED flashes at a fixed, configurable rate -- default-state: (optional) The initial state of the LED. Valid - values are "on", "off", and "keep". If the LED is already on or off - and the default-state property is set the to same value, then no - glitch should be produced where the LED momentarily turns off (or - on). The "keep" setting will keep the LED at whatever its current - state is, without producing a glitch. The default is off if this - property is not present. Examples: @@ -37,22 +30,14 @@ leds { gpios = <&mcu_pio 0 1>; /* Active low */ linux,default-trigger = "ide-disk"; }; - - fault { - gpios = <&mcu_pio 1 0>; - /* Keep LED on if BIOS detected hardware fault */ - default-state = "keep"; - }; }; run-control { compatible = "gpio-leds"; red { gpios = <&mpc8572 6 0>; - default-state = "off"; }; green { gpios = <&mpc8572 7 0>; - default-state = "on"; }; } diff --git a/trunk/Documentation/powerpc/dts-bindings/gpio/mdio.txt b/trunk/Documentation/powerpc/dts-bindings/gpio/mdio.txt deleted file mode 100644 index bc9549529014..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/gpio/mdio.txt +++ /dev/null @@ -1,19 +0,0 @@ -MDIO on GPIOs - -Currently defined compatibles: -- virtual,gpio-mdio - -MDC and MDIO lines connected to GPIO controllers are listed in the -gpios property as described in section VIII.1 in the following order: - -MDC, MDIO. - -Example: - -mdio { - compatible = "virtual,mdio-gpio"; - #address-cells = <1>; - #size-cells = <0>; - gpios = <&qe_pio_a 11 - &qe_pio_c 6>; -}; diff --git a/trunk/Documentation/powerpc/dts-bindings/marvell.txt b/trunk/Documentation/powerpc/dts-bindings/marvell.txt deleted file mode 100644 index 3708a2fd4747..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/marvell.txt +++ /dev/null @@ -1,521 +0,0 @@ -Marvell Discovery mv64[345]6x System Controller chips -=========================================================== - -The Marvell mv64[345]60 series of system controller chips contain -many of the peripherals needed to implement a complete computer -system. In this section, we define device tree nodes to describe -the system controller chip itself and each of the peripherals -which it contains. Compatible string values for each node are -prefixed with the string "marvell,", for Marvell Technology Group Ltd. - -1) The /system-controller node - - This node is used to represent the system-controller and must be - present when the system uses a system controller chip. The top-level - system-controller node contains information that is global to all - devices within the system controller chip. The node name begins - with "system-controller" followed by the unit address, which is - the base address of the memory-mapped register set for the system - controller chip. - - Required properties: - - - ranges : Describes the translation of system controller addresses - for memory mapped registers. - - clock-frequency: Contains the main clock frequency for the system - controller chip. - - reg : This property defines the address and size of the - memory-mapped registers contained within the system controller - chip. The address specified in the "reg" property should match - the unit address of the system-controller node. - - #address-cells : Address representation for system controller - devices. This field represents the number of cells needed to - represent the address of the memory-mapped registers of devices - within the system controller chip. - - #size-cells : Size representation for for the memory-mapped - registers within the system controller chip. - - #interrupt-cells : Defines the width of cells used to represent - interrupts. - - Optional properties: - - - model : The specific model of the system controller chip. Such - as, "mv64360", "mv64460", or "mv64560". - - compatible : A string identifying the compatibility identifiers - of the system controller chip. - - The system-controller node contains child nodes for each system - controller device that the platform uses. Nodes should not be created - for devices which exist on the system controller chip but are not used - - Example Marvell Discovery mv64360 system-controller node: - - system-controller@f1000000 { /* Marvell Discovery mv64360 */ - #address-cells = <1>; - #size-cells = <1>; - model = "mv64360"; /* Default */ - compatible = "marvell,mv64360"; - clock-frequency = <133333333>; - reg = <0xf1000000 0x10000>; - virtual-reg = <0xf1000000>; - ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */ - 0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */ - 0xa0000000 0xa0000000 0x4000000 /* User FLASH */ - 0x00000000 0xf1000000 0x0010000 /* Bridge's regs */ - 0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */ - - [ child node definitions... ] - } - -2) Child nodes of /system-controller - - a) Marvell Discovery MDIO bus - - The MDIO is a bus to which the PHY devices are connected. For each - device that exists on this bus, a child node should be created. See - the definition of the PHY node below for an example of how to define - a PHY. - - Required properties: - - #address-cells : Should be <1> - - #size-cells : Should be <0> - - device_type : Should be "mdio" - - compatible : Should be "marvell,mv64360-mdio" - - Example: - - mdio { - #address-cells = <1>; - #size-cells = <0>; - device_type = "mdio"; - compatible = "marvell,mv64360-mdio"; - - ethernet-phy@0 { - ...... - }; - }; - - - b) Marvell Discovery ethernet controller - - The Discover ethernet controller is described with two levels - of nodes. The first level describes an ethernet silicon block - and the second level describes up to 3 ethernet nodes within - that block. The reason for the multiple levels is that the - registers for the node are interleaved within a single set - of registers. The "ethernet-block" level describes the - shared register set, and the "ethernet" nodes describe ethernet - port-specific properties. - - Ethernet block node - - Required properties: - - #address-cells : <1> - - #size-cells : <0> - - compatible : "marvell,mv64360-eth-block" - - reg : Offset and length of the register set for this block - - Example Discovery Ethernet block node: - ethernet-block@2000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "marvell,mv64360-eth-block"; - reg = <0x2000 0x2000>; - ethernet@0 { - ....... - }; - }; - - Ethernet port node - - Required properties: - - device_type : Should be "network". - - compatible : Should be "marvell,mv64360-eth". - - reg : Should be <0>, <1>, or <2>, according to which registers - within the silicon block the device uses. - - interrupts : where a is the interrupt number for the port. - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - phy : the phandle for the PHY connected to this ethernet - controller. - - local-mac-address : 6 bytes, MAC address - - Example Discovery Ethernet port node: - ethernet@0 { - device_type = "network"; - compatible = "marvell,mv64360-eth"; - reg = <0>; - interrupts = <32>; - interrupt-parent = <&PIC>; - phy = <&PHY0>; - local-mac-address = [ 00 00 00 00 00 00 ]; - }; - - - - c) Marvell Discovery PHY nodes - - Required properties: - - device_type : Should be "ethernet-phy" - - interrupts : where a is the interrupt number for this phy. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - reg : The ID number for the phy, usually a small integer - - Example Discovery PHY node: - ethernet-phy@1 { - device_type = "ethernet-phy"; - compatible = "broadcom,bcm5421"; - interrupts = <76>; /* GPP 12 */ - interrupt-parent = <&PIC>; - reg = <1>; - }; - - - d) Marvell Discovery SDMA nodes - - Represent DMA hardware associated with the MPSC (multiprotocol - serial controllers). - - Required properties: - - compatible : "marvell,mv64360-sdma" - - reg : Offset and length of the register set for this device - - interrupts : where a is the interrupt number for the DMA - device. - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery SDMA node: - sdma@4000 { - compatible = "marvell,mv64360-sdma"; - reg = <0x4000 0xc18>; - virtual-reg = <0xf1004000>; - interrupts = <36>; - interrupt-parent = <&PIC>; - }; - - - e) Marvell Discovery BRG nodes - - Represent baud rate generator hardware associated with the MPSC - (multiprotocol serial controllers). - - Required properties: - - compatible : "marvell,mv64360-brg" - - reg : Offset and length of the register set for this device - - clock-src : A value from 0 to 15 which selects the clock - source for the baud rate generator. This value corresponds - to the CLKS value in the BRGx configuration register. See - the mv64x60 User's Manual. - - clock-frequence : The frequency (in Hz) of the baud rate - generator's input clock. - - current-speed : The current speed setting (presumably by - firmware) of the baud rate generator. - - Example Discovery BRG node: - brg@b200 { - compatible = "marvell,mv64360-brg"; - reg = <0xb200 0x8>; - clock-src = <8>; - clock-frequency = <133333333>; - current-speed = <9600>; - }; - - - f) Marvell Discovery CUNIT nodes - - Represent the Serial Communications Unit device hardware. - - Required properties: - - reg : Offset and length of the register set for this device - - Example Discovery CUNIT node: - cunit@f200 { - reg = <0xf200 0x200>; - }; - - - g) Marvell Discovery MPSCROUTING nodes - - Represent the Discovery's MPSC routing hardware - - Required properties: - - reg : Offset and length of the register set for this device - - Example Discovery CUNIT node: - mpscrouting@b500 { - reg = <0xb400 0xc>; - }; - - - h) Marvell Discovery MPSCINTR nodes - - Represent the Discovery's MPSC DMA interrupt hardware registers - (SDMA cause and mask registers). - - Required properties: - - reg : Offset and length of the register set for this device - - Example Discovery MPSCINTR node: - mpsintr@b800 { - reg = <0xb800 0x100>; - }; - - - i) Marvell Discovery MPSC nodes - - Represent the Discovery's MPSC (Multiprotocol Serial Controller) - serial port. - - Required properties: - - device_type : "serial" - - compatible : "marvell,mv64360-mpsc" - - reg : Offset and length of the register set for this device - - sdma : the phandle for the SDMA node used by this port - - brg : the phandle for the BRG node used by this port - - cunit : the phandle for the CUNIT node used by this port - - mpscrouting : the phandle for the MPSCROUTING node used by this port - - mpscintr : the phandle for the MPSCINTR node used by this port - - cell-index : the hardware index of this cell in the MPSC core - - max_idle : value needed for MPSC CHR3 (Maximum Frame Length) - register - - interrupts : where a is the interrupt number for the MPSC. - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery MPSCINTR node: - mpsc@8000 { - device_type = "serial"; - compatible = "marvell,mv64360-mpsc"; - reg = <0x8000 0x38>; - virtual-reg = <0xf1008000>; - sdma = <&SDMA0>; - brg = <&BRG0>; - cunit = <&CUNIT>; - mpscrouting = <&MPSCROUTING>; - mpscintr = <&MPSCINTR>; - cell-index = <0>; - max_idle = <40>; - interrupts = <40>; - interrupt-parent = <&PIC>; - }; - - - j) Marvell Discovery Watch Dog Timer nodes - - Represent the Discovery's watchdog timer hardware - - Required properties: - - compatible : "marvell,mv64360-wdt" - - reg : Offset and length of the register set for this device - - Example Discovery Watch Dog Timer node: - wdt@b410 { - compatible = "marvell,mv64360-wdt"; - reg = <0xb410 0x8>; - }; - - - k) Marvell Discovery I2C nodes - - Represent the Discovery's I2C hardware - - Required properties: - - device_type : "i2c" - - compatible : "marvell,mv64360-i2c" - - reg : Offset and length of the register set for this device - - interrupts : where a is the interrupt number for the I2C. - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery I2C node: - compatible = "marvell,mv64360-i2c"; - reg = <0xc000 0x20>; - virtual-reg = <0xf100c000>; - interrupts = <37>; - interrupt-parent = <&PIC>; - }; - - - l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes - - Represent the Discovery's PIC hardware - - Required properties: - - #interrupt-cells : <1> - - #address-cells : <0> - - compatible : "marvell,mv64360-pic" - - reg : Offset and length of the register set for this device - - interrupt-controller - - Example Discovery PIC node: - pic { - #interrupt-cells = <1>; - #address-cells = <0>; - compatible = "marvell,mv64360-pic"; - reg = <0x0 0x88>; - interrupt-controller; - }; - - - m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes - - Represent the Discovery's MPP hardware - - Required properties: - - compatible : "marvell,mv64360-mpp" - - reg : Offset and length of the register set for this device - - Example Discovery MPP node: - mpp@f000 { - compatible = "marvell,mv64360-mpp"; - reg = <0xf000 0x10>; - }; - - - n) Marvell Discovery GPP (General Purpose Pins) nodes - - Represent the Discovery's GPP hardware - - Required properties: - - compatible : "marvell,mv64360-gpp" - - reg : Offset and length of the register set for this device - - Example Discovery GPP node: - gpp@f000 { - compatible = "marvell,mv64360-gpp"; - reg = <0xf100 0x20>; - }; - - - o) Marvell Discovery PCI host bridge node - - Represents the Discovery's PCI host bridge device. The properties - for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE - 1275-1994. A typical value for the compatible property is - "marvell,mv64360-pci". - - Example Discovery PCI host bridge node - pci@80000000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "marvell,mv64360-pci"; - reg = <0xcf8 0x8>; - ranges = <0x01000000 0x0 0x0 - 0x88000000 0x0 0x01000000 - 0x02000000 0x0 0x80000000 - 0x80000000 0x0 0x08000000>; - bus-range = <0 255>; - clock-frequency = <66000000>; - interrupt-parent = <&PIC>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - /* IDSEL 0x0a */ - 0x5000 0 0 1 &PIC 80 - 0x5000 0 0 2 &PIC 81 - 0x5000 0 0 3 &PIC 91 - 0x5000 0 0 4 &PIC 93 - - /* IDSEL 0x0b */ - 0x5800 0 0 1 &PIC 91 - 0x5800 0 0 2 &PIC 93 - 0x5800 0 0 3 &PIC 80 - 0x5800 0 0 4 &PIC 81 - - /* IDSEL 0x0c */ - 0x6000 0 0 1 &PIC 91 - 0x6000 0 0 2 &PIC 93 - 0x6000 0 0 3 &PIC 80 - 0x6000 0 0 4 &PIC 81 - - /* IDSEL 0x0d */ - 0x6800 0 0 1 &PIC 93 - 0x6800 0 0 2 &PIC 80 - 0x6800 0 0 3 &PIC 81 - 0x6800 0 0 4 &PIC 91 - >; - }; - - - p) Marvell Discovery CPU Error nodes - - Represent the Discovery's CPU error handler device. - - Required properties: - - compatible : "marvell,mv64360-cpu-error" - - reg : Offset and length of the register set for this device - - interrupts : the interrupt number for this device - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery CPU Error node: - cpu-error@0070 { - compatible = "marvell,mv64360-cpu-error"; - reg = <0x70 0x10 0x128 0x28>; - interrupts = <3>; - interrupt-parent = <&PIC>; - }; - - - q) Marvell Discovery SRAM Controller nodes - - Represent the Discovery's SRAM controller device. - - Required properties: - - compatible : "marvell,mv64360-sram-ctrl" - - reg : Offset and length of the register set for this device - - interrupts : the interrupt number for this device - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery SRAM Controller node: - sram-ctrl@0380 { - compatible = "marvell,mv64360-sram-ctrl"; - reg = <0x380 0x80>; - interrupts = <13>; - interrupt-parent = <&PIC>; - }; - - - r) Marvell Discovery PCI Error Handler nodes - - Represent the Discovery's PCI error handler device. - - Required properties: - - compatible : "marvell,mv64360-pci-error" - - reg : Offset and length of the register set for this device - - interrupts : the interrupt number for this device - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery PCI Error Handler node: - pci-error@1d40 { - compatible = "marvell,mv64360-pci-error"; - reg = <0x1d40 0x40 0xc28 0x4>; - interrupts = <12>; - interrupt-parent = <&PIC>; - }; - - - s) Marvell Discovery Memory Controller nodes - - Represent the Discovery's memory controller device. - - Required properties: - - compatible : "marvell,mv64360-mem-ctrl" - - reg : Offset and length of the register set for this device - - interrupts : the interrupt number for this device - - interrupt-parent : the phandle for the interrupt controller - that services interrupts for this device. - - Example Discovery Memory Controller node: - mem-ctrl@1400 { - compatible = "marvell,mv64360-mem-ctrl"; - reg = <0x1400 0x60>; - interrupts = <17>; - interrupt-parent = <&PIC>; - }; - - diff --git a/trunk/Documentation/powerpc/dts-bindings/phy.txt b/trunk/Documentation/powerpc/dts-bindings/phy.txt deleted file mode 100644 index bb8c742eb8c5..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/phy.txt +++ /dev/null @@ -1,25 +0,0 @@ -PHY nodes - -Required properties: - - - device_type : Should be "ethernet-phy" - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - reg : The ID number for the phy, usually a small integer - - linux,phandle : phandle for this node; likely referenced by an - ethernet controller node. - -Example: - -ethernet-phy@0 { - linux,phandle = <2452000> - interrupt-parent = <40000>; - interrupts = <35 1>; - reg = <0>; - device_type = "ethernet-phy"; -}; diff --git a/trunk/Documentation/powerpc/dts-bindings/spi-bus.txt b/trunk/Documentation/powerpc/dts-bindings/spi-bus.txt deleted file mode 100644 index e782add2e457..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/spi-bus.txt +++ /dev/null @@ -1,57 +0,0 @@ -SPI (Serial Peripheral Interface) busses - -SPI busses can be described with a node for the SPI master device -and a set of child nodes for each SPI slave on the bus. For this -discussion, it is assumed that the system's SPI controller is in -SPI master mode. This binding does not describe SPI controllers -in slave mode. - -The SPI master node requires the following properties: -- #address-cells - number of cells required to define a chip select - address on the SPI bus. -- #size-cells - should be zero. -- compatible - name of SPI bus controller following generic names - recommended practice. -No other properties are required in the SPI bus node. It is assumed -that a driver for an SPI bus device will understand that it is an SPI bus. -However, the binding does not attempt to define the specific method for -assigning chip select numbers. Since SPI chip select configuration is -flexible and non-standardized, it is left out of this binding with the -assumption that board specific platform code will be used to manage -chip selects. Individual drivers can define additional properties to -support describing the chip select layout. - -SPI slave nodes must be children of the SPI master node and can -contain the following properties. -- reg - (required) chip select address of device. -- compatible - (required) name of SPI device following generic names - recommended practice -- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz -- spi-cpol - (optional) Empty property indicating device requires - inverse clock polarity (CPOL) mode -- spi-cpha - (optional) Empty property indicating device requires - shifted clock phase (CPHA) mode -- spi-cs-high - (optional) Empty property indicating device requires - chip select active high - -SPI example for an MPC5200 SPI bus: - spi@f00 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; - reg = <0xf00 0x20>; - interrupts = <2 13 0 2 14 0>; - interrupt-parent = <&mpc5200_pic>; - - ethernet-switch@0 { - compatible = "micrel,ks8995m"; - spi-max-frequency = <1000000>; - reg = <0>; - }; - - codec@1 { - compatible = "ti,tlv320aic26"; - spi-max-frequency = <100000>; - reg = <1>; - }; - }; diff --git a/trunk/Documentation/powerpc/dts-bindings/usb-ehci.txt b/trunk/Documentation/powerpc/dts-bindings/usb-ehci.txt deleted file mode 100644 index fa18612f757b..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/usb-ehci.txt +++ /dev/null @@ -1,25 +0,0 @@ -USB EHCI controllers - -Required properties: - - compatible : should be "usb-ehci". - - reg : should contain at least address and length of the standard EHCI - register set for the device. Optional platform-dependent registers - (debug-port or other) can be also specified here, but only after - definition of standard EHCI registers. - - interrupts : one EHCI interrupt should be described here. -If device registers are implemented in big endian mode, the device -node should have "big-endian-regs" property. -If controller implementation operates with big endian descriptors, -"big-endian-desc" property should be specified. -If both big endian registers and descriptors are used by the controller -implementation, "big-endian" property can be specified instead of having -both "big-endian-regs" and "big-endian-desc". - -Example (Sequoia 440EPx): - ehci@e0000300 { - compatible = "ibm,usb-ehci-440epx", "usb-ehci"; - interrupt-parent = <&UIC0>; - interrupts = <1a 4>; - reg = <0 e0000300 90 0 e0000390 70>; - big-endian; - }; diff --git a/trunk/Documentation/powerpc/dts-bindings/xilinx.txt b/trunk/Documentation/powerpc/dts-bindings/xilinx.txt deleted file mode 100644 index 80339fe4300b..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/xilinx.txt +++ /dev/null @@ -1,295 +0,0 @@ - d) Xilinx IP cores - - The Xilinx EDK toolchain ships with a set of IP cores (devices) for use - in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range - of standard device types (network, serial, etc.) and miscellaneous - devices (gpio, LCD, spi, etc). Also, since these devices are - implemented within the fpga fabric every instance of the device can be - synthesised with different options that change the behaviour. - - Each IP-core has a set of parameters which the FPGA designer can use to - control how the core is synthesized. Historically, the EDK tool would - extract the device parameters relevant to device drivers and copy them - into an 'xparameters.h' in the form of #define symbols. This tells the - device drivers how the IP cores are configured, but it requres the kernel - to be recompiled every time the FPGA bitstream is resynthesized. - - The new approach is to export the parameters into the device tree and - generate a new device tree each time the FPGA bitstream changes. The - parameters which used to be exported as #defines will now become - properties of the device node. In general, device nodes for IP-cores - will take the following form: - - (name): (generic-name)@(base-address) { - compatible = "xlnx,(ip-core-name)-(HW_VER)" - [, (list of compatible devices), ...]; - reg = <(baseaddr) (size)>; - interrupt-parent = <&interrupt-controller-phandle>; - interrupts = < ... >; - xlnx,(parameter1) = "(string-value)"; - xlnx,(parameter2) = <(int-value)>; - }; - - (generic-name): an open firmware-style name that describes the - generic class of device. Preferably, this is one word, such - as 'serial' or 'ethernet'. - (ip-core-name): the name of the ip block (given after the BEGIN - directive in system.mhs). Should be in lowercase - and all underscores '_' converted to dashes '-'. - (name): is derived from the "PARAMETER INSTANCE" value. - (parameter#): C_* parameters from system.mhs. The C_ prefix is - dropped from the parameter name, the name is converted - to lowercase and all underscore '_' characters are - converted to dashes '-'. - (baseaddr): the baseaddr parameter value (often named C_BASEADDR). - (HW_VER): from the HW_VER parameter. - (size): the address range size (often C_HIGHADDR - C_BASEADDR + 1). - - Typically, the compatible list will include the exact IP core version - followed by an older IP core version which implements the same - interface or any other device with the same interface. - - 'reg', 'interrupt-parent' and 'interrupts' are all optional properties. - - For example, the following block from system.mhs: - - BEGIN opb_uartlite - PARAMETER INSTANCE = opb_uartlite_0 - PARAMETER HW_VER = 1.00.b - PARAMETER C_BAUDRATE = 115200 - PARAMETER C_DATA_BITS = 8 - PARAMETER C_ODD_PARITY = 0 - PARAMETER C_USE_PARITY = 0 - PARAMETER C_CLK_FREQ = 50000000 - PARAMETER C_BASEADDR = 0xEC100000 - PARAMETER C_HIGHADDR = 0xEC10FFFF - BUS_INTERFACE SOPB = opb_7 - PORT OPB_Clk = CLK_50MHz - PORT Interrupt = opb_uartlite_0_Interrupt - PORT RX = opb_uartlite_0_RX - PORT TX = opb_uartlite_0_TX - PORT OPB_Rst = sys_bus_reset_0 - END - - becomes the following device tree node: - - opb_uartlite_0: serial@ec100000 { - device_type = "serial"; - compatible = "xlnx,opb-uartlite-1.00.b"; - reg = ; - interrupt-parent = <&opb_intc_0>; - interrupts = <1 0>; // got this from the opb_intc parameters - current-speed = ; // standard serial device prop - clock-frequency = ; // standard serial device prop - xlnx,data-bits = <8>; - xlnx,odd-parity = <0>; - xlnx,use-parity = <0>; - }; - - Some IP cores actually implement 2 or more logical devices. In - this case, the device should still describe the whole IP core with - a single node and add a child node for each logical device. The - ranges property can be used to translate from parent IP-core to the - registers of each device. In addition, the parent node should be - compatible with the bus type 'xlnx,compound', and should contain - #address-cells and #size-cells, as with any other bus. (Note: this - makes the assumption that both logical devices have the same bus - binding. If this is not true, then separate nodes should be used - for each logical device). The 'cell-index' property can be used to - enumerate logical devices within an IP core. For example, the - following is the system.mhs entry for the dual ps2 controller found - on the ml403 reference design. - - BEGIN opb_ps2_dual_ref - PARAMETER INSTANCE = opb_ps2_dual_ref_0 - PARAMETER HW_VER = 1.00.a - PARAMETER C_BASEADDR = 0xA9000000 - PARAMETER C_HIGHADDR = 0xA9001FFF - BUS_INTERFACE SOPB = opb_v20_0 - PORT Sys_Intr1 = ps2_1_intr - PORT Sys_Intr2 = ps2_2_intr - PORT Clkin1 = ps2_clk_rx_1 - PORT Clkin2 = ps2_clk_rx_2 - PORT Clkpd1 = ps2_clk_tx_1 - PORT Clkpd2 = ps2_clk_tx_2 - PORT Rx1 = ps2_d_rx_1 - PORT Rx2 = ps2_d_rx_2 - PORT Txpd1 = ps2_d_tx_1 - PORT Txpd2 = ps2_d_tx_2 - END - - It would result in the following device tree nodes: - - opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "xlnx,compound"; - ranges = <0 a9000000 2000>; - // If this device had extra parameters, then they would - // go here. - ps2@0 { - compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; - reg = <0 40>; - interrupt-parent = <&opb_intc_0>; - interrupts = <3 0>; - cell-index = <0>; - }; - ps2@1000 { - compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; - reg = <1000 40>; - interrupt-parent = <&opb_intc_0>; - interrupts = <3 0>; - cell-index = <0>; - }; - }; - - Also, the system.mhs file defines bus attachments from the processor - to the devices. The device tree structure should reflect the bus - attachments. Again an example; this system.mhs fragment: - - BEGIN ppc405_virtex4 - PARAMETER INSTANCE = ppc405_0 - PARAMETER HW_VER = 1.01.a - BUS_INTERFACE DPLB = plb_v34_0 - BUS_INTERFACE IPLB = plb_v34_0 - END - - BEGIN opb_intc - PARAMETER INSTANCE = opb_intc_0 - PARAMETER HW_VER = 1.00.c - PARAMETER C_BASEADDR = 0xD1000FC0 - PARAMETER C_HIGHADDR = 0xD1000FDF - BUS_INTERFACE SOPB = opb_v20_0 - END - - BEGIN opb_uart16550 - PARAMETER INSTANCE = opb_uart16550_0 - PARAMETER HW_VER = 1.00.d - PARAMETER C_BASEADDR = 0xa0000000 - PARAMETER C_HIGHADDR = 0xa0001FFF - BUS_INTERFACE SOPB = opb_v20_0 - END - - BEGIN plb_v34 - PARAMETER INSTANCE = plb_v34_0 - PARAMETER HW_VER = 1.02.a - END - - BEGIN plb_bram_if_cntlr - PARAMETER INSTANCE = plb_bram_if_cntlr_0 - PARAMETER HW_VER = 1.00.b - PARAMETER C_BASEADDR = 0xFFFF0000 - PARAMETER C_HIGHADDR = 0xFFFFFFFF - BUS_INTERFACE SPLB = plb_v34_0 - END - - BEGIN plb2opb_bridge - PARAMETER INSTANCE = plb2opb_bridge_0 - PARAMETER HW_VER = 1.01.a - PARAMETER C_RNG0_BASEADDR = 0x20000000 - PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF - PARAMETER C_RNG1_BASEADDR = 0x60000000 - PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF - PARAMETER C_RNG2_BASEADDR = 0x80000000 - PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF - PARAMETER C_RNG3_BASEADDR = 0xC0000000 - PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF - BUS_INTERFACE SPLB = plb_v34_0 - BUS_INTERFACE MOPB = opb_v20_0 - END - - Gives this device tree (some properties removed for clarity): - - plb@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "xlnx,plb-v34-1.02.a"; - device_type = "ibm,plb"; - ranges; // 1:1 translation - - plb_bram_if_cntrl_0: bram@ffff0000 { - reg = ; - } - - opb@20000000 { - #address-cells = <1>; - #size-cells = <1>; - ranges = <20000000 20000000 20000000 - 60000000 60000000 20000000 - 80000000 80000000 40000000 - c0000000 c0000000 20000000>; - - opb_uart16550_0: serial@a0000000 { - reg = ; - }; - - opb_intc_0: interrupt-controller@d1000fc0 { - reg = ; - }; - }; - }; - - That covers the general approach to binding xilinx IP cores into the - device tree. The following are bindings for specific devices: - - i) Xilinx ML300 Framebuffer - - Simple framebuffer device from the ML300 reference design (also on the - ML403 reference design as well as others). - - Optional properties: - - resolution = : pixel resolution of framebuffer. Some - implementations use a different resolution. - Default is - - virt-resolution = : Size of framebuffer in memory. - Default is . - - rotate-display (empty) : rotate display 180 degrees. - - ii) Xilinx SystemACE - - The Xilinx SystemACE device is used to program FPGAs from an FPGA - bitstream stored on a CF card. It can also be used as a generic CF - interface device. - - Optional properties: - - 8-bit (empty) : Set this property for SystemACE in 8 bit mode - - iii) Xilinx EMAC and Xilinx TEMAC - - Xilinx Ethernet devices. In addition to general xilinx properties - listed above, nodes for these devices should include a phy-handle - property, and may include other common network device properties - like local-mac-address. - - iv) Xilinx Uartlite - - Xilinx uartlite devices are simple fixed speed serial ports. - - Required properties: - - current-speed : Baud rate of uartlite - - v) Xilinx hwicap - - Xilinx hwicap devices provide access to the configuration logic - of the FPGA through the Internal Configuration Access Port - (ICAP). The ICAP enables partial reconfiguration of the FPGA, - readback of the configuration information, and some control over - 'warm boots' of the FPGA fabric. - - Required properties: - - xlnx,family : The family of the FPGA, necessary since the - capabilities of the underlying ICAP hardware - differ between different families. May be - 'virtex2p', 'virtex4', or 'virtex5'. - - vi) Xilinx Uart 16550 - - Xilinx UART 16550 devices are very similar to the NS16550 but with - different register spacing and an offset from the base address. - - Required properties: - - clock-frequency : Frequency of the clock input - - reg-offset : A value of 3 is required - - reg-shift : A value of 2 is required - - diff --git a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt index 939a3dd58148..0d8d23581c44 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt @@ -240,7 +240,6 @@ AD1986A laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) ultra 2-channel with EAPD (Samsung Ultra tablet PC) samsung 2-channel with EAPD (Samsung R65) - samsung-p50 2-channel with HP-automute (Samsung P50) AD1988/AD1988B/AD1989A/AD1989B ============================== diff --git a/trunk/Documentation/spi/spidev_test.c b/trunk/Documentation/spi/spidev_test.c index c1a5aad3c75a..cf0e3ce0d526 100644 --- a/trunk/Documentation/spi/spidev_test.c +++ b/trunk/Documentation/spi/spidev_test.c @@ -99,13 +99,11 @@ void parse_opts(int argc, char *argv[]) { "lsb", 0, 0, 'L' }, { "cs-high", 0, 0, 'C' }, { "3wire", 0, 0, '3' }, - { "no-cs", 0, 0, 'N' }, - { "ready", 0, 0, 'R' }, { NULL, 0, 0, 0 }, }; int c; - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL); + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3", lopts, NULL); if (c == -1) break; @@ -141,12 +139,6 @@ void parse_opts(int argc, char *argv[]) case '3': mode |= SPI_3WIRE; break; - case 'N': - mode |= SPI_NO_CS; - break; - case 'R': - mode |= SPI_READY; - break; default: print_usage(argv[0]); break; diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88 index 0736518b2f88..89093f531727 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx88 +++ b/trunk/Documentation/video4linux/CARDLIST.cx88 @@ -6,8 +6,8 @@ 5 -> Leadtek Winfast 2000XP Expert [107d:6611,107d:6613] 6 -> AverTV Studio 303 (M126) [1461:000b] 7 -> MSI TV-@nywhere Master [1462:8606] - 8 -> Leadtek Winfast DV2000 [107d:6620,107d:6621] - 9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632,107d:6630,107d:6638,107d:6631,107d:6637,107d:663d] + 8 -> Leadtek Winfast DV2000 [107d:6620] + 9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632] 10 -> IODATA GV-VCP3/PCI [10fc:d003] 11 -> Prolink PlayTV PVR 12 -> ASUS PVR-416 [1043:4823,1461:c111] @@ -59,7 +59,7 @@ 58 -> Pinnacle PCTV HD 800i [11bd:0051] 59 -> DViCO FusionHDTV 5 PCI nano [18ac:d530] 60 -> Pinnacle Hybrid PCTV [12ab:1788] - 61 -> Leadtek TV2000 XP Global [107d:6f18,107d:6618] + 61 -> Winfast TV2000 XP Global [107d:6f18] 62 -> PowerColor RA330 [14f1:ea3d] 63 -> Geniatech X8000-MT DVBT [14f1:8852] 64 -> DViCO FusionHDTV DVB-T PRO [18ac:db30] diff --git a/trunk/Documentation/video4linux/CARDLIST.em28xx b/trunk/Documentation/video4linux/CARDLIST.em28xx index 873630e7e53e..a98a688c11b8 100644 --- a/trunk/Documentation/video4linux/CARDLIST.em28xx +++ b/trunk/Documentation/video4linux/CARDLIST.em28xx @@ -65,4 +65,3 @@ 67 -> Terratec Grabby (em2860) [0ccd:0096] 68 -> Terratec AV350 (em2860) [0ccd:0084] 69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313] - 70 -> Evga inDtube (em2882) diff --git a/trunk/Documentation/video4linux/v4l2-framework.txt b/trunk/Documentation/video4linux/v4l2-framework.txt index ba4706afc5fb..d54c1e4c6a9c 100644 --- a/trunk/Documentation/video4linux/v4l2-framework.txt +++ b/trunk/Documentation/video4linux/v4l2-framework.txt @@ -390,30 +390,6 @@ later date. It differs between i2c drivers and as such can be confusing. To see which chip variants are supported you can look in the i2c driver code for the i2c_device_id table. This lists all the possibilities. -There are two more helper functions: - -v4l2_i2c_new_subdev_cfg: this function adds new irq and platform_data -arguments and has both 'addr' and 'probed_addrs' arguments: if addr is not -0 then that will be used (non-probing variant), otherwise the probed_addrs -are probed. - -For example: this will probe for address 0x10: - -struct v4l2_subdev *sd = v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, - "module_foo", "chipid", 0, NULL, 0, I2C_ADDRS(0x10)); - -v4l2_i2c_new_subdev_board uses an i2c_board_info struct which is passed -to the i2c driver and replaces the irq, platform_data and addr arguments. - -If the subdev supports the s_config core ops, then that op is called with -the irq and platform_data arguments after the subdev was setup. The older -v4l2_i2c_new_(probed_)subdev functions will call s_config as well, but with -irq set to 0 and platform_data set to NULL. - -Note that in the next kernel release the functions v4l2_i2c_new_subdev, -v4l2_i2c_new_probed_subdev and v4l2_i2c_new_probed_subdev_addr will all be -replaced by a single v4l2_i2c_new_subdev that is identical to -v4l2_i2c_new_subdev_cfg but without the irq and platform_data arguments. struct video_device ------------------- diff --git a/trunk/Documentation/watchdog/hpwdt.txt b/trunk/Documentation/watchdog/hpwdt.txt index 9c24d5ffbb06..127839e53043 100644 --- a/trunk/Documentation/watchdog/hpwdt.txt +++ b/trunk/Documentation/watchdog/hpwdt.txt @@ -19,41 +19,30 @@ Last reviewed: 06/02/2009 not be updated in a timely fashion and a hardware system reset (also known as an Automatic Server Recovery (ASR)) event will occur. - The hpwdt driver also has four (4) module parameters. They are the following: + The hpwdt driver also has three (3) module parameters. They are the following: soft_margin - allows the user to set the watchdog timer value allow_kdump - allows the user to save off a kernel dump image after an NMI nowayout - basic watchdog parameter that does not allow the timer to be restarted or an impending ASR to be escaped. - priority - determines whether or not the hpwdt driver is first on the - die_notify list to handle NMIs or last. The default value - for this module parameter is 0 or LAST. If the user wants to - enable NMI sourcing then reload the hpwdt driver with - priority=1 (and boot with nmi_watchdog=0). NOTE: More information about watchdog drivers in general, including the ioctl interface to /dev/watchdog can be found in Documentation/watchdog/watchdog-api.txt and Documentation/IPMI.txt. - The priority parameter was introduced due to other kernel software that relied - on handling NMIs (like oprofile). Keeping hpwdt's priority at 0 (or LAST) - enables the users of NMIs for non critical events to be work as expected. - - The NMI sourcing capability is disabled by default due to the inability to + The NMI sourcing capability is disabled when the driver discovers that the + nmi_watchdog is turned on (nmi_watchdog = 1). This is due to the inability to distinguish between "NMI Watchdog Ticks" and "HW generated NMI events" in the Linux kernel. What this means is that the hpwdt nmi handler code is called each time the NMI signal fires off. This could amount to several thousands of NMIs in a matter of seconds. If a user sees the Linux kernel's "dazed and confused" message in the logs or if the system gets into a hung state, then - the hpwdt driver can be reloaded with the "priority" module parameter set - (priority=1). + the user should reboot with nmi_watchdog=0. 1. If the kernel has not been booted with nmi_watchdog turned off then edit /boot/grub/menu.lst and place the nmi_watchdog=0 at the end of the currently booting kernel line. 2. reboot the sever - 3. Once the system comes up perform a rmmod hpwdt - 4. insmod /lib/modules/`uname -r`/kernel/drivers/char/watchdog/hpwdt.ko priority=1 Now, the hpwdt can successfully receive and source the NMI and provide a log message that details the reason for the NMI (as determined by the HP BIOS). diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 381190c7949c..02f6f78b561f 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -230,13 +230,6 @@ L: linux-acenic@sunsite.dk S: Maintained F: drivers/net/acenic* -ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER -P: Peter Feuerer -M: peter@piie.net -W: http://piie.net/?section=acerhdf -S: Maintained -F: drivers/platform/x86/acerhdf.c - ACER WMI LAPTOP EXTRAS P: Carlos Corbacho M: carlos@strangeworlds.co.uk @@ -867,22 +860,12 @@ M: alex@shark-linux.de W: http://www.shark-linux.de/shark.html S: Maintained -ARM/SAMSUNG ARM ARCHITECTURES -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/plat-s3c/ -F: arch/arm/plat-s3c24xx/ - ARM/S3C2410 ARM ARCHITECTURE P: Ben Dooks M: ben-linux@fluff.org L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) W: http://www.fluff.org/ben/linux/ S: Maintained -F: arch/arm/mach-s3c2410/ ARM/S3C2440 ARM ARCHITECTURE P: Ben Dooks @@ -890,39 +873,6 @@ M: ben-linux@fluff.org L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) W: http://www.fluff.org/ben/linux/ S: Maintained -F: arch/arm/mach-s3c2440/ - -ARM/S3C2442 ARM ARCHITECTURE -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/mach-s3c2442/ - -ARM/S3C2443 ARM ARCHITECTURE -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/mach-s3c2443/ - -ARM/S3C6400 ARM ARCHITECTURE -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/mach-s3c6400/ - -ARM/S3C6410 ARM ARCHITECTURE -P: Ben Dooks -M: ben-linux@fluff.org -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) -W: http://www.fluff.org/ben/linux/ -S: Maintained -F: arch/arm/mach-s3c6410/ ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT P: Lennert Buytenhek @@ -963,7 +913,8 @@ M: corentincj@iksaif.net P: Karol Kozimor M: sziwan@users.sourceforge.net L: acpi4asus-user@lists.sourceforge.net -W: http://acpi4asus.sf.net +W: http://sourceforge.net/projects/acpi4asus +W: http://xf.iksaif.net/acpi4asus S: Maintained F: arch/x86/kernel/acpi/boot.c F: drivers/platform/x86/asus_acpi.c @@ -979,7 +930,8 @@ ASUS LAPTOP EXTRAS DRIVER P: Corentin Chary M: corentincj@iksaif.net L: acpi4asus-user@lists.sourceforge.net -W: http://acpi4asus.sf.net +W: http://sourceforge.net/projects/acpi4asus +W: http://xf.iksaif.net/acpi4asus S: Maintained F: drivers/platform/x86/asus-laptop.c @@ -1684,7 +1636,7 @@ P: Mikael Starvik M: starvik@axis.com P: Jesper Nilsson M: jesper.nilsson@axis.com -L: linux-cris-kernel@axis.com +L: dev-etrax@axis.com W: http://developer.axis.com S: Maintained F: arch/cris/ @@ -2130,9 +2082,9 @@ F: drivers/edac/i5400_edac.c EDAC-I82975X P: Ranganathan Desikan -M: ravi@jetztechnologies.com +M: rdesikan@jetzbroadband.com P: Arvind R. -M: arvind@jetztechnologies.com +M: arvind@acarlab.com L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained @@ -2158,7 +2110,7 @@ EEEPC LAPTOP EXTRAS DRIVER P: Corentin Chary M: corentincj@iksaif.net L: acpi4asus-user@lists.sourceforge.net -W: http://acpi4asus.sf.net +W: http://sourceforge.net/projects/acpi4asus S: Maintained F: drivers/platform/x86/eeepc-laptop.c @@ -2530,14 +2482,6 @@ F: drivers/net/wan/pc300too.c F: drivers/net/wan/pci200syn.c F: drivers/net/wan/wanxl* -GENERIC INCLUDE/ASM HEADER FILES -P: Arnd Bergmann -M: arnd@arndb.de -L: linux-arch@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git -S: Maintained -F: include/asm-generic - GFS2 FILE SYSTEM P: Steven Whitehouse M: swhiteho@redhat.com @@ -2851,9 +2795,7 @@ S: Maintained IA64 (Itanium) PLATFORM P: Tony Luck -P: Fenghua Yu M: tony.luck@intel.com -M: fenghua.yu@intel.com L: linux-ia64@vger.kernel.org W: http://www.ia64-linux.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6.git @@ -2882,10 +2824,10 @@ S: Supported F: drivers/scsi/ips.* IDE SUBSYSTEM -P: David S. Miller -M: davem@davemloft.net +P: Bartlomiej Zolnierkiewicz +M: bzolnier@gmail.com L: linux-ide@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6.git S: Maintained F: Documentation/ide/ F: drivers/ide/ @@ -2931,7 +2873,7 @@ P: Dmitry Eremin-Solenikov M: dbaryshkov@gmail.com P: Sergey Lapin M: slapin@ossfans.org -L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) +L: linux-zigbee-devel@lists.sourceforge.net W: http://apps.sourceforge.net/trac/linux-zigbee T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git S: Maintained @@ -5578,8 +5520,8 @@ F: drivers/staging/ STARFIRE/DURALAN NETWORK DRIVER P: Ion Badulescu -M: ionut@badula.org -S: Odd Fixes +M: ionut@cs.columbia.edu +S: Maintained F: drivers/net/starfire* STARMODE RADIO IP (STRIP) PROTOCOL DRIVER @@ -5713,13 +5655,6 @@ F: drivers/misc/tifm* F: drivers/mmc/host/tifm_sd.c F: include/linux/tifm.h -TI TWL4030 SERIES SOC CODEC DRIVER -P: Peter Ujfalusi -M: peter.ujfalusi@nokia.com -L: alsa-devel@alsa-project.org (moderated for non-subscribers) -S: Maintained -F: sound/soc/codecs/twl4030* - TIPC NETWORK LAYER P: Per Liden M: per.liden@ericsson.com diff --git a/trunk/Makefile b/trunk/Makefile index b4c7ef5ab431..46e1c9d03d51 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 31 -EXTRAVERSION = -rc1 +SUBLEVEL = 30 +EXTRAVERSION = NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* @@ -140,13 +140,15 @@ _all: modules endif srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR)) +TOPDIR := $(srctree) +# FIXME - TOPDIR is obsolete, use srctree/objtree objtree := $(CURDIR) src := $(srctree) obj := $(objtree) VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD)) -export srctree objtree VPATH +export srctree objtree VPATH TOPDIR # SUBARCH tells the usermode build what the underlying arch is. That is set @@ -342,8 +344,7 @@ KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ - -Werror-implicit-function-declaration \ - -Wno-format-security + -Werror-implicit-function-declaration KBUILD_AFLAGS := -D__ASSEMBLY__ # Read KERNELRELEASE from include/config/kernel.release (if it exists) diff --git a/trunk/arch/alpha/include/asm/percpu.h b/trunk/arch/alpha/include/asm/percpu.h index b663f1f10b6a..06c5c7a4afd3 100644 --- a/trunk/arch/alpha/include/asm/percpu.h +++ b/trunk/arch/alpha/include/asm/percpu.h @@ -30,7 +30,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; #ifndef MODULE #define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset)) -#define PER_CPU_DEF_ATTRIBUTES +#define PER_CPU_ATTRIBUTES #else /* * To calculate addresses of locally defined variables, GCC uses 32-bit @@ -49,7 +49,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; : "=&r"(__ptr), "=&r"(tmp_gp)); \ (typeof(&per_cpu_var(var)))(__ptr + (offset)); }) -#define PER_CPU_DEF_ATTRIBUTES __used +#define PER_CPU_ATTRIBUTES __used #endif /* MODULE */ @@ -71,7 +71,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS]; #define __get_cpu_var(var) per_cpu_var(var) #define __raw_get_cpu_var(var) per_cpu_var(var) -#define PER_CPU_DEF_ATTRIBUTES +#define PER_CPU_ATTRIBUTES #endif /* SMP */ diff --git a/trunk/arch/arm/Kconfig.debug b/trunk/arch/arm/Kconfig.debug index a89e4734b8f0..a71fd941ade7 100644 --- a/trunk/arch/arm/Kconfig.debug +++ b/trunk/arch/arm/Kconfig.debug @@ -99,6 +99,14 @@ config DEBUG_CLPS711X_UART2 output to the second serial port on these devices. Saying N will cause the debug messages to appear on the first serial port. +config DEBUG_S3C_PORT + depends on DEBUG_LL && PLAT_S3C + bool "Kernel low-level debugging messages via S3C UART" + help + Say Y here if you want debug print routines to go to one of the + S3C internal UARTs. The chosen UART must have been configured + before it is used. + config DEBUG_S3C_UART depends on PLAT_S3C int "S3C UART to use for low-level debug" diff --git a/trunk/arch/arm/configs/s3c2410_defconfig b/trunk/arch/arm/configs/s3c2410_defconfig index b49810461e41..2d58b8fe59be 100644 --- a/trunk/arch/arm/configs/s3c2410_defconfig +++ b/trunk/arch/arm/configs/s3c2410_defconfig @@ -260,7 +260,6 @@ CONFIG_MACH_NEXCODER_2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_MACH_AT2440EVB=y CONFIG_CPU_S3C2442=y -CONFIG_MACH_MINI2440=y # # S3C2442 Machines @@ -2299,6 +2298,7 @@ CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C_PORT=y CONFIG_DEBUG_S3C_UART=0 # diff --git a/trunk/arch/arm/configs/s3c6400_defconfig b/trunk/arch/arm/configs/s3c6400_defconfig index 32860609e057..2e8fa50e9a09 100644 --- a/trunk/arch/arm/configs/s3c6400_defconfig +++ b/trunk/arch/arm/configs/s3c6400_defconfig @@ -816,6 +816,7 @@ CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_S3C_PORT=y CONFIG_DEBUG_S3C_UART=0 # diff --git a/trunk/arch/arm/configs/tct_hammer_defconfig b/trunk/arch/arm/configs/tct_hammer_defconfig index 9d32faef05f6..07dfb98df4f0 100644 --- a/trunk/arch/arm/configs/tct_hammer_defconfig +++ b/trunk/arch/arm/configs/tct_hammer_defconfig @@ -857,6 +857,7 @@ CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_S3C_PORT is not set CONFIG_DEBUG_S3C_UART=0 # diff --git a/trunk/arch/arm/include/asm/page.h b/trunk/arch/arm/include/asm/page.h index 9c746af1bf6e..be962c1349c4 100644 --- a/trunk/arch/arm/include/asm/page.h +++ b/trunk/arch/arm/include/asm/page.h @@ -12,7 +12,7 @@ /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) #ifndef __ASSEMBLY__ diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index b7c3490eaa24..096f600dc8d8 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -98,6 +98,17 @@ int show_interrupts(struct seq_file *p, void *v) return 0; } +/* Handle bad interrupts */ +static struct irq_desc bad_irq_desc = { + .handle_irq = handle_bad_irq, + .lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock), +}; + +#ifdef CONFIG_CPUMASK_OFFSTACK +/* We are not allocating bad_irq_desc.affinity or .pending_mask */ +#error "ARM architecture does not support CONFIG_CPUMASK_OFFSTACK." +#endif + /* * do_IRQ handles all hardware IRQ's. Decoded IRQs should not * come via this function. Instead, they should provide their @@ -113,13 +124,10 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) * Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. */ - if (unlikely(irq >= NR_IRQS)) { - if (printk_ratelimit()) - printk(KERN_WARNING "Bad IRQ%u\n", irq); - ack_bad_irq(irq); - } else { + if (irq >= NR_IRQS) + handle_bad_irq(irq, &bad_irq_desc); + else generic_handle_irq(irq); - } /* AT91 specific workaround */ irq_finish(irq); @@ -157,6 +165,10 @@ void __init init_IRQ(void) for (irq = 0; irq < NR_IRQS; irq++) irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE; +#ifdef CONFIG_SMP + cpumask_setall(bad_irq_desc.affinity); + bad_irq_desc.node = smp_processor_id(); +#endif init_arch_irq(); } diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 69371028a202..4340bf3d2c84 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -6,7 +6,6 @@ #include #include #include -#include OUTPUT_ARCH(arm) ENTRY(stext) @@ -64,7 +63,7 @@ SECTIONS usr/built-in.o(.init.ramfs) __initramfs_end = .; #endif - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __per_cpu_load = .; __per_cpu_start = .; *(.data.percpu.page_aligned) @@ -74,7 +73,7 @@ SECTIONS #ifndef CONFIG_XIP_KERNEL __init_begin = _stext; INIT_DATA - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __init_end = .; #endif } @@ -119,7 +118,7 @@ SECTIONS *(.got) /* Global offset table */ } - RO_DATA(PAGE_SIZE) + RODATA _etext = .; /* End of text and rodata section */ @@ -159,17 +158,17 @@ SECTIONS *(.data.init_task) #ifdef CONFIG_XIP_KERNEL - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __init_begin = .; INIT_DATA - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __init_end = .; #endif - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __nosave_begin = .; *(.data.nosave) - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __nosave_end = .; /* diff --git a/trunk/arch/arm/mach-at91/board-sam9g20ek.c b/trunk/arch/arm/mach-at91/board-sam9g20ek.c index a55398ed1211..cc270beadd5d 100644 --- a/trunk/arch/arm/mach-at91/board-sam9g20ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9g20ek.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include @@ -220,56 +218,6 @@ static struct gpio_led ek_leds[] = { } }; - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { - .gpio = AT91_PIN_PA30, - .code = BTN_3, - .desc = "Button 3", - .active_low = 1, - .wakeup = 1, - }, - { - .gpio = AT91_PIN_PA31, - .code = BTN_4, - .desc = "Button 4", - .active_low = 1, - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */ - at91_set_deglitch(AT91_PIN_PA30, 1); - at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */ - at91_set_deglitch(AT91_PIN_PA31, 1); - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - - static struct i2c_board_info __initdata ek_i2c_devices[] = { { I2C_BOARD_INFO("24c512", 0x50), @@ -297,8 +245,6 @@ static void __init ek_board_init(void) at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); /* LEDs */ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - /* Push Buttons */ - ek_add_device_buttons(); /* PCK0 provides MCLK to the WM8731 */ at91_set_B_periph(AT91_PIN_PC1, 0); /* SSC (for WM8731) */ diff --git a/trunk/arch/arm/mach-at91/board-sam9rlek.c b/trunk/arch/arm/mach-at91/board-sam9rlek.c index f6b5672cabd6..35e12a49d1a6 100644 --- a/trunk/arch/arm/mach-at91/board-sam9rlek.c +++ b/trunk/arch/arm/mach-at91/board-sam9rlek.c @@ -186,21 +186,19 @@ static struct fb_monspecs at91fb_default_monspecs = { static void at91_lcdc_power_control(int on) { if (on) - at91_set_gpio_value(AT91_PIN_PC1, 0); /* power up */ + at91_set_gpio_value(AT91_PIN_PA30, 0); /* power up */ else - at91_set_gpio_value(AT91_PIN_PC1, 1); /* power down */ + at91_set_gpio_value(AT91_PIN_PA30, 1); /* power down */ } /* Driver datas */ static struct atmel_lcdfb_info __initdata ek_lcdc_data = { - .lcdcon_is_backlight = true, .default_bpp = 16, .default_dmacon = ATMEL_LCDC_DMAEN, .default_lcdcon2 = AT91SAM9RL_DEFAULT_LCDCON2, .default_monspecs = &at91fb_default_monspecs, .atmel_lcdfb_power_control = at91_lcdc_power_control, .guard_time = 1, - .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, }; #else diff --git a/trunk/arch/arm/mach-omap1/board-nokia770.c b/trunk/arch/arm/mach-omap1/board-nokia770.c index ed2a48a9ce74..e70fc7c66bbb 100644 --- a/trunk/arch/arm/mach-omap1/board-nokia770.c +++ b/trunk/arch/arm/mach-omap1/board-nokia770.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #define ADS7846_PENDOWN_GPIO 15 @@ -204,11 +205,9 @@ static int nokia770_mmc_get_cover_state(struct device *dev, int slot) static struct omap_mmc_platform_data nokia770_mmc2_data = { .nr_slots = 1, .dma_mask = 0xffffffff, - .max_freq = 12000000, .slots[0] = { .set_power = nokia770_mmc_set_power, .get_cover_state = nokia770_mmc_get_cover_state, - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .name = "mmcblk", }, }; diff --git a/trunk/arch/arm/mach-omap1/mailbox.c b/trunk/arch/arm/mach-omap1/mailbox.c index 6810b4aeb02c..0af4d6c85b47 100644 --- a/trunk/arch/arm/mach-omap1/mailbox.c +++ b/trunk/arch/arm/mach-omap1/mailbox.c @@ -203,5 +203,5 @@ module_exit(omap1_mbox_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions"); -MODULE_AUTHOR("Hiroshi DOYU "); +MODULE_AUTHOR("Hiroshi DOYU" ); MODULE_ALIAS("platform:omap1-mailbox"); diff --git a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c index 9a0bf6744a05..da93b86234ed 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -362,7 +362,6 @@ static struct omap_onenand_platform_data board_onenand_data = { .gpio_irq = 65, .parts = onenand_partitions, .nr_parts = ARRAY_SIZE(onenand_partitions), - .flags = ONENAND_SYNC_READWRITE, }; static void __init board_onenand_init(void) diff --git a/trunk/arch/arm/mach-omap2/gpmc-onenand.c b/trunk/arch/arm/mach-omap2/gpmc-onenand.c index 54fec53a48e7..2fd22f9c5f0e 100644 --- a/trunk/arch/arm/mach-omap2/gpmc-onenand.c +++ b/trunk/arch/arm/mach-omap2/gpmc-onenand.c @@ -31,8 +31,6 @@ static struct platform_device gpmc_onenand_device = { static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) { struct gpmc_timings t; - u32 reg; - int err; const int t_cer = 15; const int t_avdp = 12; @@ -45,11 +43,6 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) const int t_wpl = 40; const int t_wph = 30; - /* Ensure sync read and sync write are disabled */ - reg = readw(onenand_base + ONENAND_REG_SYS_CFG1); - reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE; - writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); - memset(&t, 0, sizeof(t)); t.sync_clk = 0; t.cs_on = 0; @@ -81,16 +74,7 @@ static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base) GPMC_CONFIG1_DEVICESIZE_16 | GPMC_CONFIG1_MUXADDDATA); - err = gpmc_cs_set_timings(cs, &t); - if (err) - return err; - - /* Ensure sync read and sync write are disabled */ - reg = readw(onenand_base + ONENAND_REG_SYS_CFG1); - reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE; - writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); - - return 0; + return gpmc_cs_set_timings(cs, &t); } static void set_onenand_cfg(void __iomem *onenand_base, int latency, @@ -140,8 +124,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, } else if (cfg->flags & ONENAND_SYNC_READWRITE) { sync_read = 1; sync_write = 1; - } else - return omap2_onenand_set_async_mode(cs, onenand_base); + } if (!freq) { /* Very first call freq is not known */ diff --git a/trunk/arch/arm/mach-omap2/id.c b/trunk/arch/arm/mach-omap2/id.c index a98201cc265c..458990e20c60 100644 --- a/trunk/arch/arm/mach-omap2/id.c +++ b/trunk/arch/arm/mach-omap2/id.c @@ -48,28 +48,6 @@ int omap_chip_is(struct omap_chip_id oci) } EXPORT_SYMBOL(omap_chip_is); -int omap_type(void) -{ - u32 val = 0; - - if (cpu_is_omap24xx()) - val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); - else if (cpu_is_omap34xx()) - val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS); - else { - pr_err("Cannot detect omap type!\n"); - goto out; - } - - val &= OMAP2_DEVICETYPE_MASK; - val >>= 8; - -out: - return val; -} -EXPORT_SYMBOL(omap_type); - - /*----------------------------------------------------------------------------*/ #define OMAP_TAP_IDCODE 0x0204 diff --git a/trunk/arch/arm/mach-omap2/mailbox.c b/trunk/arch/arm/mach-omap2/mailbox.c index 6f71f3730c97..fd5b8a5925cc 100644 --- a/trunk/arch/arm/mach-omap2/mailbox.c +++ b/trunk/arch/arm/mach-omap2/mailbox.c @@ -282,12 +282,12 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev) return -ENOMEM; /* DSP or IVA2 IRQ */ - ret = platform_get_irq(pdev, 0); - if (ret < 0) { + mbox_dsp_info.irq = platform_get_irq(pdev, 0); + if (mbox_dsp_info.irq < 0) { dev_err(&pdev->dev, "invalid irq resource\n"); + ret = -ENODEV; goto err_dsp; } - mbox_dsp_info.irq = ret; ret = omap_mbox_register(&pdev->dev, &mbox_dsp_info); if (ret) diff --git a/trunk/arch/arm/mach-omap2/mmc-twl4030.c b/trunk/arch/arm/mach-omap2/mmc-twl4030.c index 1541fd4c8d0f..9756a878fd90 100644 --- a/trunk/arch/arm/mach-omap2/mmc-twl4030.c +++ b/trunk/arch/arm/mach-omap2/mmc-twl4030.c @@ -263,19 +263,8 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd) { int ret = 0; - struct twl_mmc_controller *c = NULL; + struct twl_mmc_controller *c = &hsmmc[1]; struct omap_mmc_platform_data *mmc = dev->platform_data; - int i; - - for (i = 1; i < ARRAY_SIZE(hsmmc); i++) { - if (mmc == hsmmc[i].mmc) { - c = &hsmmc[i]; - break; - } - } - - if (c == NULL) - return -ENODEV; /* If we don't see a Vcc regulator, assume it's a fixed * voltage always-on regulator. diff --git a/trunk/arch/arm/mach-s3c2440/mach-mini2440.c b/trunk/arch/arm/mach-s3c2440/mach-mini2440.c index ec71a6965786..6a5bc3021bdb 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/trunk/arch/arm/mach-s3c2440/mach-mini2440.c @@ -48,6 +48,8 @@ #include #include +#include + #include #include #include @@ -273,7 +275,6 @@ static struct s3c2410_nand_set mini2440_nand_sets[] __initdata = { .nr_chips = 1, .nr_partitions = ARRAY_SIZE(mini2440_default_nand_part), .partitions = mini2440_default_nand_part, - .flash_bbt = 1, /* we use u-boot to create a BBT */ }, }; diff --git a/trunk/arch/arm/mach-s3c2442/mach-gta02.c b/trunk/arch/arm/mach-s3c2442/mach-gta02.c index 0fb385bd9cd9..e23b581aa0e1 100644 --- a/trunk/arch/arm/mach-s3c2442/mach-gta02.c +++ b/trunk/arch/arm/mach-s3c2442/mach-gta02.c @@ -433,7 +433,8 @@ static struct s3c2410_nand_set gta02_nand_sets[] = { */ .name = "neo1973-nand", .nr_chips = 1, - .flash_bbt = 1, + .use_bbt = 1, + .force_soft_ecc = 1, }, }; diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index 7677a4a1cef2..def14ec265b3 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -2457,19 +2457,6 @@ static int __init omap_init_dma(void) setup_irq(irq, &omap24xx_dma_irq); } - /* Enable smartidle idlemodes and autoidle */ - if (cpu_is_omap34xx()) { - u32 v = dma_read(OCP_SYSCONFIG); - v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK | - DMA_SYSCONFIG_SIDLEMODE_MASK | - DMA_SYSCONFIG_AUTOIDLE); - v |= (DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_SMARTIDLE) | - DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) | - DMA_SYSCONFIG_AUTOIDLE); - dma_write(v , OCP_SYSCONFIG); - } - - /* FIXME: Update LCD DMA to work on 24xx */ if (cpu_class_is_omap1()) { r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index 26b387c12423..7fd89ba8d3b5 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -1585,7 +1585,6 @@ static int __init _omap_gpio_init(void) __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); - __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_DEBOUNCE_EN); /* Initialize interface clock ungated, module enabled */ __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); diff --git a/trunk/arch/arm/plat-omap/include/mach/cpu.h b/trunk/arch/arm/plat-omap/include/mach/cpu.h index 285eaa3a8275..fc60c4ebcc28 100644 --- a/trunk/arch/arm/plat-omap/include/mach/cpu.h +++ b/trunk/arch/arm/plat-omap/include/mach/cpu.h @@ -30,17 +30,6 @@ #ifndef __ASM_ARCH_OMAP_CPU_H #define __ASM_ARCH_OMAP_CPU_H -/* - * Omap device type i.e. EMU/HS/TST/GP/BAD - */ -#define OMAP2_DEVICE_TYPE_TEST 0 -#define OMAP2_DEVICE_TYPE_EMU 1 -#define OMAP2_DEVICE_TYPE_SEC 2 -#define OMAP2_DEVICE_TYPE_GP 3 -#define OMAP2_DEVICE_TYPE_BAD 4 - -int omap_type(void); - struct omap_chip_id { u8 oc; u8 type; @@ -435,6 +424,17 @@ IS_OMAP_TYPE(3430, 0x3430) int omap_chip_is(struct omap_chip_id oci); +int omap_type(void); + +/* + * Macro to detect device type i.e. EMU/HS/TST/GP/BAD + */ +#define OMAP2_DEVICE_TYPE_TEST 0 +#define OMAP2_DEVICE_TYPE_EMU 1 +#define OMAP2_DEVICE_TYPE_SEC 2 +#define OMAP2_DEVICE_TYPE_GP 3 +#define OMAP2_DEVICE_TYPE_BAD 4 + void omap2_check_revision(void); #endif /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */ diff --git a/trunk/arch/arm/plat-omap/include/mach/dma.h b/trunk/arch/arm/plat-omap/include/mach/dma.h index 7b939cc01962..8c1eae88737e 100644 --- a/trunk/arch/arm/plat-omap/include/mach/dma.h +++ b/trunk/arch/arm/plat-omap/include/mach/dma.h @@ -389,21 +389,6 @@ #define DMA_THREAD_FIFO_25 (0x02 << 14) #define DMA_THREAD_FIFO_50 (0x03 << 14) -/* DMA4_OCP_SYSCONFIG bits */ -#define DMA_SYSCONFIG_MIDLEMODE_MASK (3 << 12) -#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK (3 << 8) -#define DMA_SYSCONFIG_EMUFREE (1 << 5) -#define DMA_SYSCONFIG_SIDLEMODE_MASK (3 << 3) -#define DMA_SYSCONFIG_SOFTRESET (1 << 2) -#define DMA_SYSCONFIG_AUTOIDLE (1 << 0) - -#define DMA_SYSCONFIG_MIDLEMODE(n) ((n) << 12) -#define DMA_SYSCONFIG_SIDLEMODE(n) ((n) << 3) - -#define DMA_IDLEMODE_SMARTIDLE 0x2 -#define DMA_IDLEMODE_NO_IDLE 0x1 -#define DMA_IDLEMODE_FORCE_IDLE 0x0 - /* Chaining modes*/ #ifndef CONFIG_ARCH_OMAP1 #define OMAP_DMA_STATIC_CHAIN 0x1 diff --git a/trunk/arch/arm/plat-omap/include/mach/io.h b/trunk/arch/arm/plat-omap/include/mach/io.h index 73f483d56ca6..3b2814720569 100644 --- a/trunk/arch/arm/plat-omap/include/mach/io.h +++ b/trunk/arch/arm/plat-omap/include/mach/io.h @@ -201,7 +201,7 @@ #define OMAP2_IO_ADDRESS(pa) IOMEM(__OMAP2_IO_ADDRESS(pa)) #ifdef __ASSEMBLER__ -#define IOMEM(x) (x) +#define IOMEM(x) x #else #define IOMEM(x) ((void __force __iomem *)(x)) diff --git a/trunk/arch/arm/plat-omap/iommu.c b/trunk/arch/arm/plat-omap/iommu.c index 4a0301399013..4cf449fa2cb5 100644 --- a/trunk/arch/arm/plat-omap/iommu.c +++ b/trunk/arch/arm/plat-omap/iommu.c @@ -298,7 +298,7 @@ void flush_iotlb_page(struct iommu *obj, u32 da) if ((start <= da) && (da < start + bytes)) { dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", __func__, start, da, bytes); - iotlb_load_cr(obj, &cr); + iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); } } diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index 4ea73804d21e..65006df3f1b7 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -133,12 +133,7 @@ void __init omap_detect_sram(void) if (cpu_is_omap34xx()) { omap_sram_base = OMAP3_SRAM_PUB_VA; omap_sram_start = OMAP3_SRAM_PUB_PA; - if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || - (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { - omap_sram_size = 0x7000; /* 28K */ - } else { - omap_sram_size = 0x8000; /* 32K */ - } + omap_sram_size = 0x8000; /* 32K */ } else { omap_sram_base = OMAP2_SRAM_PUB_VA; omap_sram_start = OMAP2_SRAM_PUB_PA; diff --git a/trunk/arch/arm/plat-s3c/Makefile b/trunk/arch/arm/plat-s3c/Makefile index 0761766b1833..74bb7cb5da49 100644 --- a/trunk/arch/arm/plat-s3c/Makefile +++ b/trunk/arch/arm/plat-s3c/Makefile @@ -34,7 +34,7 @@ obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o obj-y += dev-i2c0.o obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o -obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += dev-audio.o +obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o diff --git a/trunk/arch/arm/plat-s3c/include/plat/devs.h b/trunk/arch/arm/plat-s3c/include/plat/devs.h index 2e170827e0b0..b5b9c4d46e9a 100644 --- a/trunk/arch/arm/plat-s3c/include/plat/devs.h +++ b/trunk/arch/arm/plat-s3c/include/plat/devs.h @@ -37,7 +37,6 @@ extern struct platform_device s3c_device_i2c1; extern struct platform_device s3c_device_rtc; extern struct platform_device s3c_device_adc; extern struct platform_device s3c_device_sdi; -extern struct platform_device s3c_device_iis; extern struct platform_device s3c_device_hwmon; extern struct platform_device s3c_device_hsmmc0; extern struct platform_device s3c_device_hsmmc1; diff --git a/trunk/arch/arm/plat-s3c24xx/Makefile b/trunk/arch/arm/plat-s3c24xx/Makefile index 579a165c2827..636cb12711df 100644 --- a/trunk/arch/arm/plat-s3c24xx/Makefile +++ b/trunk/arch/arm/plat-s3c24xx/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_PM) += sleep.o -obj-$(CONFIG_S3C24XX_PWM) += pwm.o +obj-$(CONFIG_HAVE_PWM) += pwm.o obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o obj-$(CONFIG_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C24XX_ADC) += adc.o diff --git a/trunk/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/trunk/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c index da7a61728c18..9edf7894eedd 100644 --- a/trunk/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c +++ b/trunk/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c @@ -12,7 +12,8 @@ */ #include -#include + +#include #include #include diff --git a/trunk/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/trunk/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c index 86b9edc67413..f34d0fc69ad8 100644 --- a/trunk/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c +++ b/trunk/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c @@ -12,7 +12,8 @@ */ #include -#include + +#include #include #include diff --git a/trunk/arch/cris/arch-v10/kernel/dma.c b/trunk/arch/cris/arch-v10/kernel/dma.c index d31504b4a19e..929e68666299 100644 --- a/trunk/arch/cris/arch-v10/kernel/dma.c +++ b/trunk/arch/cris/arch-v10/kernel/dma.c @@ -24,7 +24,7 @@ int cris_request_dma(unsigned int dmanr, const char * device_id, unsigned long int gens; int fail = -EINVAL; - if (dmanr >= MAX_DMA_CHANNELS) { + if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) { printk(KERN_CRIT "cris_request_dma: invalid DMA channel %u\n", dmanr); return -EINVAL; } @@ -213,7 +213,7 @@ int cris_request_dma(unsigned int dmanr, const char * device_id, void cris_free_dma(unsigned int dmanr, const char * device_id) { unsigned long flags; - if (dmanr >= MAX_DMA_CHANNELS) { + if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) { printk(KERN_CRIT "cris_free_dma: invalid DMA channel %u\n", dmanr); return; } diff --git a/trunk/arch/cris/arch-v32/drivers/cryptocop.c b/trunk/arch/cris/arch-v32/drivers/cryptocop.c index fd529a0ec758..67c61ea86813 100644 --- a/trunk/arch/cris/arch-v32/drivers/cryptocop.c +++ b/trunk/arch/cris/arch-v32/drivers/cryptocop.c @@ -1395,7 +1395,7 @@ static int create_md5_pad(int alloc_flag, unsigned long long hashed_length, char if (padlen < MD5_MIN_PAD_LENGTH) padlen += MD5_BLOCK_LENGTH; p = kmalloc(padlen, alloc_flag); - if (!p) return -ENOMEM; + if (!pad) return -ENOMEM; *p = 0x80; memset(p+1, 0, padlen - 1); @@ -1427,7 +1427,7 @@ static int create_sha1_pad(int alloc_flag, unsigned long long hashed_length, cha if (padlen < SHA1_MIN_PAD_LENGTH) padlen += SHA1_BLOCK_LENGTH; p = kmalloc(padlen, alloc_flag); - if (!p) return -ENOMEM; + if (!pad) return -ENOMEM; *p = 0x80; memset(p+1, 0, padlen - 1); diff --git a/trunk/arch/cris/arch-v32/kernel/irq.c b/trunk/arch/cris/arch-v32/kernel/irq.c index 57668db25031..d70b445f4a8f 100644 --- a/trunk/arch/cris/arch-v32/kernel/irq.c +++ b/trunk/arch/cris/arch-v32/kernel/irq.c @@ -430,8 +430,8 @@ crisv32_do_multiple(struct pt_regs* regs) masked[i] &= ~TIMER_MASK; do_IRQ(TIMER0_INTR_VECT, regs); } -#endif } +#endif #ifdef IGNORE_MASK /* Remove IRQs that can't be handled as multiple. */ diff --git a/trunk/arch/cris/arch-v32/lib/Makefile b/trunk/arch/cris/arch-v32/lib/Makefile index dd296b9db034..eb4aad1f1158 100644 --- a/trunk/arch/cris/arch-v32/lib/Makefile +++ b/trunk/arch/cris/arch-v32/lib/Makefile @@ -3,5 +3,5 @@ # lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o \ - csumcpfruser.o spinlock.o delay.o strcmp.o + csumcpfruser.o spinlock.o delay.o diff --git a/trunk/arch/cris/arch-v32/lib/strcmp.S b/trunk/arch/cris/arch-v32/lib/strcmp.S deleted file mode 100644 index 8f7a1ee62591..000000000000 --- a/trunk/arch/cris/arch-v32/lib/strcmp.S +++ /dev/null @@ -1,21 +0,0 @@ -; strcmp.S -- CRISv32 version. -; Copyright (C) 2008 AXIS Communications AB -; Written by Edgar E. Iglesias -; -; This source code is licensed under the GNU General Public License, -; Version 2. See the file COPYING for more details. - - .global strcmp - .type strcmp,@function -strcmp: -1: - move.b [$r10+], $r12 - seq $r13 - sub.b [$r11+], $r12 - or.b $r12, $r13 - beq 1b - nop - - ret - movs.b $r12, $r10 - .size strcmp, . - strcmp diff --git a/trunk/arch/cris/include/arch-v32/arch/spinlock.h b/trunk/arch/cris/include/arch-v32/arch/spinlock.h index 367a53ea10c5..129756b96661 100644 --- a/trunk/arch/cris/include/arch-v32/arch/spinlock.h +++ b/trunk/arch/cris/include/arch-v32/arch/spinlock.h @@ -78,7 +78,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) { __raw_spin_lock(&rw->slock); while (rw->lock != RW_LOCK_BIAS); - rw->lock = 0; + rw->lock == 0; __raw_spin_unlock(&rw->slock); } @@ -93,7 +93,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) { __raw_spin_lock(&rw->slock); while (rw->lock != RW_LOCK_BIAS); - rw->lock = RW_LOCK_BIAS; + rw->lock == RW_LOCK_BIAS; __raw_spin_unlock(&rw->slock); } @@ -114,7 +114,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) int ret = 0; __raw_spin_lock(&rw->slock); if (rw->lock == RW_LOCK_BIAS) { - rw->lock = 0; + rw->lock == 0; ret = 1; } __raw_spin_unlock(&rw->slock); diff --git a/trunk/arch/cris/include/asm/string.h b/trunk/arch/cris/include/asm/string.h index d5db39f9eea1..691190e99a27 100644 --- a/trunk/arch/cris/include/asm/string.h +++ b/trunk/arch/cris/include/asm/string.h @@ -11,10 +11,4 @@ extern void *memcpy(void *, const void *, size_t); #define __HAVE_ARCH_MEMSET extern void *memset(void *, int, size_t); -#ifdef CONFIG_ETRAX_ARCH_V32 -/* For v32 we provide strcmp. */ -#define __HAVE_ARCH_STRCMP -extern int strcmp(const char *s1, const char *s2); -#endif - #endif diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index b86e19c9b5b0..8a5bd7a9c6f5 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -7,7 +7,6 @@ config FRV default y select HAVE_IDE select HAVE_ARCH_TRACEHOOK - select HAVE_PERF_COUNTERS config ZONE_DMA bool diff --git a/trunk/arch/frv/include/asm/atomic.h b/trunk/arch/frv/include/asm/atomic.h index 00a57af79afc..0409d981fd39 100644 --- a/trunk/arch/frv/include/asm/atomic.h +++ b/trunk/arch/frv/include/asm/atomic.h @@ -121,72 +121,10 @@ static inline void atomic_dec(atomic_t *v) #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) -/* - * 64-bit atomic ops - */ -typedef struct { - volatile long long counter; -} atomic64_t; - -#define ATOMIC64_INIT(i) { (i) } - -static inline long long atomic64_read(atomic64_t *v) -{ - long long counter; - - asm("ldd%I1 %M1,%0" - : "=e"(counter) - : "m"(v->counter)); - return counter; -} - -static inline void atomic64_set(atomic64_t *v, long long i) -{ - asm volatile("std%I0 %1,%M0" - : "=m"(v->counter) - : "e"(i)); -} - -extern long long atomic64_inc_return(atomic64_t *v); -extern long long atomic64_dec_return(atomic64_t *v); -extern long long atomic64_add_return(long long i, atomic64_t *v); -extern long long atomic64_sub_return(long long i, atomic64_t *v); - -static inline long long atomic64_add_negative(long long i, atomic64_t *v) -{ - return atomic64_add_return(i, v) < 0; -} - -static inline void atomic64_add(long long i, atomic64_t *v) -{ - atomic64_add_return(i, v); -} - -static inline void atomic64_sub(long long i, atomic64_t *v) -{ - atomic64_sub_return(i, v); -} - -static inline void atomic64_inc(atomic64_t *v) -{ - atomic64_inc_return(v); -} - -static inline void atomic64_dec(atomic64_t *v) -{ - atomic64_dec_return(v); -} - -#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0) -#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) -#define atomic64_inc_and_test(v) (atomic64_inc_return((v)) == 0) - /*****************************************************************************/ /* * exchange value with memory */ -extern uint64_t __xchg_64(uint64_t i, volatile void *v); - #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS #define xchg(ptr, x) \ @@ -236,10 +174,8 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v); #define tas(ptr) (xchg((ptr), 1)) -#define atomic_cmpxchg(v, old, new) (cmpxchg(&(v)->counter, old, new)) -#define atomic_xchg(v, new) (xchg(&(v)->counter, new)) -#define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter)) -#define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter)) +#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) { diff --git a/trunk/arch/frv/include/asm/perf_counter.h b/trunk/arch/frv/include/asm/perf_counter.h deleted file mode 100644 index ccf726e61b2e..000000000000 --- a/trunk/arch/frv/include/asm/perf_counter.h +++ /dev/null @@ -1,17 +0,0 @@ -/* FRV performance counter support - * - * Copyright (C) 2009 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 Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ - -#ifndef _ASM_PERF_COUNTER_H -#define _ASM_PERF_COUNTER_H - -#define PERF_COUNTER_INDEX_OFFSET 0 - -#endif /* _ASM_PERF_COUNTER_H */ diff --git a/trunk/arch/frv/include/asm/system.h b/trunk/arch/frv/include/asm/system.h index efd22d9077ac..7742ec000cc4 100644 --- a/trunk/arch/frv/include/asm/system.h +++ b/trunk/arch/frv/include/asm/system.h @@ -208,8 +208,6 @@ extern void free_initmem(void); * - if (*ptr == test) then orig = *ptr; *ptr = test; * - if (*ptr != test) then orig = *ptr; */ -extern uint64_t __cmpxchg_64(uint64_t test, uint64_t new, volatile uint64_t *v); - #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS #define cmpxchg(ptr, test, new) \ diff --git a/trunk/arch/frv/include/asm/unistd.h b/trunk/arch/frv/include/asm/unistd.h index 4a8fb427ce0a..96d78d5d2c41 100644 --- a/trunk/arch/frv/include/asm/unistd.h +++ b/trunk/arch/frv/include/asm/unistd.h @@ -341,12 +341,10 @@ #define __NR_inotify_init1 332 #define __NR_preadv 333 #define __NR_pwritev 334 -#define __NR_rt_tgsigqueueinfo 335 -#define __NR_perf_counter_open 336 #ifdef __KERNEL__ -#define NR_syscalls 337 +#define NR_syscalls 335 #define __ARCH_WANT_IPC_PARSE_VERSION /* #define __ARCH_WANT_OLD_READDIR */ diff --git a/trunk/arch/frv/kernel/entry.S b/trunk/arch/frv/kernel/entry.S index fde1e446b440..356e0e327a89 100644 --- a/trunk/arch/frv/kernel/entry.S +++ b/trunk/arch/frv/kernel/entry.S @@ -1524,7 +1524,5 @@ sys_call_table: .long sys_inotify_init1 .long sys_preadv .long sys_pwritev - .long sys_rt_tgsigqueueinfo /* 335 */ - .long sys_perf_counter_open syscall_table_size = (. - sys_call_table) diff --git a/trunk/arch/frv/kernel/frv_ksyms.c b/trunk/arch/frv/kernel/frv_ksyms.c index a89803b58b9a..0316b3c50eff 100644 --- a/trunk/arch/frv/kernel/frv_ksyms.c +++ b/trunk/arch/frv/kernel/frv_ksyms.c @@ -67,10 +67,6 @@ EXPORT_SYMBOL(atomic_sub_return); EXPORT_SYMBOL(__xchg_32); EXPORT_SYMBOL(__cmpxchg_32); #endif -EXPORT_SYMBOL(atomic64_add_return); -EXPORT_SYMBOL(atomic64_sub_return); -EXPORT_SYMBOL(__xchg_64); -EXPORT_SYMBOL(__cmpxchg_64); EXPORT_SYMBOL(__debug_bug_printk); EXPORT_SYMBOL(__delay_loops_MHz); diff --git a/trunk/arch/frv/lib/Makefile b/trunk/arch/frv/lib/Makefile index 0a377210c89b..08be305c9f44 100644 --- a/trunk/arch/frv/lib/Makefile +++ b/trunk/arch/frv/lib/Makefile @@ -4,5 +4,5 @@ lib-y := \ __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \ - checksum.o memcpy.o memset.o atomic-ops.o atomic64-ops.o \ - outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o perf_counter.o + checksum.o memcpy.o memset.o atomic-ops.o \ + outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o diff --git a/trunk/arch/frv/lib/atomic-ops.S b/trunk/arch/frv/lib/atomic-ops.S index 5e9e6ab5dd0e..ee0ac905fb08 100644 --- a/trunk/arch/frv/lib/atomic-ops.S +++ b/trunk/arch/frv/lib/atomic-ops.S @@ -163,10 +163,11 @@ __cmpxchg_32: ld.p @(gr11,gr0),gr8 orcr cc7,cc7,cc3 subcc gr8,gr9,gr7,icc0 - bnelr icc0,#0 + bne icc0,#0,1f cst.p gr10,@(gr11,gr0) ,cc3,#1 corcc gr29,gr29,gr0 ,cc3,#1 beq icc3,#0,0b +1: bralr .size __cmpxchg_32, .-__cmpxchg_32 diff --git a/trunk/arch/frv/lib/atomic64-ops.S b/trunk/arch/frv/lib/atomic64-ops.S deleted file mode 100644 index b6194eeac127..000000000000 --- a/trunk/arch/frv/lib/atomic64-ops.S +++ /dev/null @@ -1,162 +0,0 @@ -/* kernel atomic64 operations - * - * For an explanation of how atomic ops work in this arch, see: - * Documentation/frv/atomic-ops.txt - * - * Copyright (C) 2009 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 - - .text - .balign 4 - - -############################################################################### -# -# long long atomic64_inc_return(atomic64_t *v) -# -############################################################################### - .globl atomic64_inc_return - .type atomic64_inc_return,@function -atomic64_inc_return: - or.p gr8,gr8,gr10 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - addicc gr9,#1,gr9,icc0 - addxi gr8,#0,gr8,icc0 - cstd.p gr8,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size atomic64_inc_return, .-atomic64_inc_return - -############################################################################### -# -# long long atomic64_dec_return(atomic64_t *v) -# -############################################################################### - .globl atomic64_dec_return - .type atomic64_dec_return,@function -atomic64_dec_return: - or.p gr8,gr8,gr10 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - subicc gr9,#1,gr9,icc0 - subxi gr8,#0,gr8,icc0 - cstd.p gr8,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size atomic64_dec_return, .-atomic64_dec_return - -############################################################################### -# -# long long atomic64_add_return(long long i, atomic64_t *v) -# -############################################################################### - .globl atomic64_add_return - .type atomic64_add_return,@function -atomic64_add_return: - or.p gr8,gr8,gr4 - or gr9,gr9,gr5 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - addcc gr9,gr5,gr9,icc0 - addx gr8,gr4,gr8,icc0 - cstd.p gr8,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size atomic64_add_return, .-atomic64_add_return - -############################################################################### -# -# long long atomic64_sub_return(long long i, atomic64_t *v) -# -############################################################################### - .globl atomic64_sub_return - .type atomic64_sub_return,@function -atomic64_sub_return: - or.p gr8,gr8,gr4 - or gr9,gr9,gr5 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - subcc gr9,gr5,gr9,icc0 - subx gr8,gr4,gr8,icc0 - cstd.p gr8,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size atomic64_sub_return, .-atomic64_sub_return - -############################################################################### -# -# uint64_t __xchg_64(uint64_t i, uint64_t *v) -# -############################################################################### - .globl __xchg_64 - .type __xchg_64,@function -__xchg_64: - or.p gr8,gr8,gr4 - or gr9,gr9,gr5 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 /* set CC3 to true */ - cstd.p gr4,@(gr10,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size __xchg_64, .-__xchg_64 - -############################################################################### -# -# uint64_t __cmpxchg_64(uint64_t test, uint64_t new, uint64_t *v) -# -############################################################################### - .globl __cmpxchg_64 - .type __cmpxchg_64,@function -__cmpxchg_64: - or.p gr8,gr8,gr4 - or gr9,gr9,gr5 -0: - orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ - ckeq icc3,cc7 - ldd.p @(gr12,gr0),gr8 /* LDD.P/ORCR must be atomic */ - orcr cc7,cc7,cc3 - subcc gr8,gr4,gr0,icc0 - subcc.p gr9,gr5,gr0,icc1 - bnelr icc0,#0 - bnelr icc1,#0 - cstd.p gr10,@(gr12,gr0) ,cc3,#1 - corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ - beq icc3,#0,0b - bralr - - .size __cmpxchg_64, .-__cmpxchg_64 - diff --git a/trunk/arch/frv/lib/perf_counter.c b/trunk/arch/frv/lib/perf_counter.c deleted file mode 100644 index 2000feecd571..000000000000 --- a/trunk/arch/frv/lib/perf_counter.c +++ /dev/null @@ -1,19 +0,0 @@ -/* Performance counter handling - * - * Copyright (C) 2009 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 Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ - -#include - -/* - * mark the performance counter as pending - */ -void set_perf_counter_pending(void) -{ -} diff --git a/trunk/arch/h8300/Kconfig.cpu b/trunk/arch/h8300/Kconfig.cpu index 6e2ecff199c5..b65dcfe51d9c 100644 --- a/trunk/arch/h8300/Kconfig.cpu +++ b/trunk/arch/h8300/Kconfig.cpu @@ -13,7 +13,7 @@ config H8300H_GENERIC config H8300H_AKI3068NET bool "AE-3068/69" - select H83068 + select CONFIG_H83068 help AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support More Information. (Japanese Only) @@ -24,7 +24,7 @@ config H8300H_AKI3068NET config H8300H_H8MAX bool "H8MAX" - select H83068 + select CONFIG_H83068 help H8MAX Evaluation Board Support More Information. (Japanese Only) @@ -32,7 +32,7 @@ config H8300H_H8MAX config H8300H_SIM bool "H8/300H Simulator" - select H83007 + select CONFIG_H83007 help GDB Simulator Support More Information. @@ -45,7 +45,7 @@ config H8S_GENERIC config H8S_EDOSK2674 bool "EDOSK-2674" - select H8S2678 + select CONFIG_H8S2768 help Renesas EDOSK-2674 Evaluation Board Support More Information. diff --git a/trunk/arch/ia64/kernel/acpi-processor.c b/trunk/arch/ia64/kernel/acpi-processor.c index dbda7bde6112..cbe6cee5a550 100644 --- a/trunk/arch/ia64/kernel/acpi-processor.c +++ b/trunk/arch/ia64/kernel/acpi-processor.c @@ -71,15 +71,3 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) } EXPORT_SYMBOL(arch_acpi_processor_init_pdc); - -void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr) -{ - if (pr->pdc) { - kfree(pr->pdc->pointer->buffer.pointer); - kfree(pr->pdc->pointer); - kfree(pr->pdc); - pr->pdc = NULL; - } -} - -EXPORT_SYMBOL(arch_acpi_processor_cleanup_pdc); diff --git a/trunk/arch/ia64/kernel/esi.c b/trunk/arch/ia64/kernel/esi.c index d5764a3d74af..ebf4e988e78c 100644 --- a/trunk/arch/ia64/kernel/esi.c +++ b/trunk/arch/ia64/kernel/esi.c @@ -65,7 +65,7 @@ static int __init esi_init (void) } if (!esi) - return -ENODEV; + return -ENODEV;; systab = __va(esi); diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index f1782705b1f7..abce2468a40b 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -5603,7 +5603,7 @@ pfm_interrupt_handler(int irq, void *arg) * /proc/perfmon interface, for debug only */ -#define PFM_PROC_SHOW_HEADER ((void *)(long)nr_cpu_ids+1) +#define PFM_PROC_SHOW_HEADER ((void *)nr_cpu_ids+1) static void * pfm_proc_start(struct seq_file *m, loff_t *pos) diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index e6676fca4828..7053c55b7649 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -192,7 +192,7 @@ struct salinfo_platform_oemdata_parms { static void salinfo_work_to_do(struct salinfo_data *data) { - (void)(down_trylock(&data->mutex) ?: 0); + down_trylock(&data->mutex); up(&data->mutex); } diff --git a/trunk/arch/ia64/kvm/kvm_lib.c b/trunk/arch/ia64/kvm/kvm_lib.c index f1268b8e6f9e..a85cb611ecd7 100644 --- a/trunk/arch/ia64/kvm/kvm_lib.c +++ b/trunk/arch/ia64/kvm/kvm_lib.c @@ -11,11 +11,5 @@ * */ #undef CONFIG_MODULES -#include -#undef CONFIG_KALLSYMS -#undef EXPORT_SYMBOL -#undef EXPORT_SYMBOL_GPL -#define EXPORT_SYMBOL(sym) -#define EXPORT_SYMBOL_GPL(sym) #include "../../../lib/vsprintf.c" #include "../../../lib/ctype.c" diff --git a/trunk/arch/ia64/kvm/process.c b/trunk/arch/ia64/kvm/process.c index bb862fb224f2..a8f84da04b49 100644 --- a/trunk/arch/ia64/kvm/process.c +++ b/trunk/arch/ia64/kvm/process.c @@ -130,7 +130,7 @@ static void collect_interruption(struct kvm_vcpu *vcpu) if (vdcr & IA64_DCR_PP) { vpsr |= IA64_PSR_PP; } else { - vpsr &= ~IA64_PSR_PP; + vpsr &= ~IA64_PSR_PP;; } vcpu_set_psr(vcpu, vpsr); @@ -594,11 +594,11 @@ static void set_pal_call_data(struct kvm_vcpu *vcpu) p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); break; case PAL_BRAND_INFO: - p->u.pal_data.gr29 = gr29; + p->u.pal_data.gr29 = gr29;; p->u.pal_data.gr30 = kvm_trans_pal_call_args(vcpu, gr30); break; default: - p->u.pal_data.gr29 = gr29; + p->u.pal_data.gr29 = gr29;; p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30); } p->u.pal_data.gr28 = gr28; diff --git a/trunk/arch/ia64/kvm/vcpu.c b/trunk/arch/ia64/kvm/vcpu.c index 46b02cbcc874..a2c6c15e4761 100644 --- a/trunk/arch/ia64/kvm/vcpu.c +++ b/trunk/arch/ia64/kvm/vcpu.c @@ -406,7 +406,7 @@ void getreg(unsigned long regnum, unsigned long *val, * Now look at registers in [0-31] range and init correct UNAT */ addr = (unsigned long)regs; - unat = ®s->eml_unat; + unat = ®s->eml_unat;; addr += gr_info[regnum]; diff --git a/trunk/arch/ia64/kvm/vtlb.c b/trunk/arch/ia64/kvm/vtlb.c index 20b3852f7a6e..4290a429bf7c 100644 --- a/trunk/arch/ia64/kvm/vtlb.c +++ b/trunk/arch/ia64/kvm/vtlb.c @@ -135,7 +135,7 @@ struct thash_data *__vtr_lookup(struct kvm_vcpu *vcpu, u64 va, int type) u64 rid; rid = vcpu_get_rr(vcpu, va); - rid = rid & RR_RID_MASK; + rid = rid & RR_RID_MASK;; if (type == D_TLB) { if (vcpu_quick_region_check(vcpu->arch.dtr_regions, va)) { for (trp = (struct thash_data *)&vcpu->arch.dtrs, i = 0; @@ -518,7 +518,7 @@ struct thash_data *vtlb_lookup(struct kvm_vcpu *v, u64 va, int is_data) struct thash_cb *hcb = &v->arch.vtlb; - cch = __vtr_lookup(v, va, is_data); + cch = __vtr_lookup(v, va, is_data);; if (cch) return cch; diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c index 25831c47c579..76645cf6ac5d 100644 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ b/trunk/arch/ia64/sn/kernel/io_common.c @@ -435,8 +435,7 @@ void sn_generate_path(struct pci_bus *pci_bus, char *address) bricktype = MODULE_GET_BTYPE(moduleid); if ((bricktype == L1_BRICKTYPE_191010) || (bricktype == L1_BRICKTYPE_1932)) - sprintf(address + strlen(address), "^%d", - geo_slot(geoid)); + sprintf(address, "%s^%d", address, geo_slot(geoid)); } void __devinit diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 3ca0fe1a9123..b29f0280d712 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -22,26 +22,6 @@ choice config MACH_ALCHEMY bool "Alchemy processor based machines" -config AR7 - bool "Texas Instruments AR7" - select BOOT_ELF32 - select DMA_NONCOHERENT - select CEVT_R4K - select CSRC_R4K - select IRQ_CPU - select NO_EXCEPT_FILL - select SWAP_IO_SPACE - select SYS_HAS_CPU_MIPS32_R1 - select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_GPIO - select GCD - select VLYNQ - help - Support for the Texas Instruments AR7 System-on-a-Chip - family: TNETD7100, 7200 and 7300. - config BASLER_EXCITE bool "Basler eXcite smart camera" select CEVT_R4K @@ -229,7 +209,7 @@ config MIPS_MALTA select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_MIPS_CMP + select SYS_SUPPORTS_MIPS_CMP if BROKEN # because SYNC_R4K is broken select SYS_SUPPORTS_MULTITHREADING select SYS_SUPPORTS_SMARTMIPS help @@ -267,7 +247,6 @@ config MACH_VR41XX select CEVT_R4K select CSRC_R4K select SYS_HAS_CPU_VR41XX - select ARCH_REQUIRE_GPIOLIB config NXP_STB220 bool "NXP STB220 board" @@ -622,7 +601,6 @@ config CAVIUM_OCTEON_SIMULATOR select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM - select SYS_SUPPORTS_HOTPLUG_CPU select SYS_HAS_CPU_CAVIUM_OCTEON help The Octeon simulator is software performance model of the Cavium @@ -637,7 +615,6 @@ config CAVIUM_OCTEON_REFERENCE_BOARD select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM - select SYS_SUPPORTS_HOTPLUG_CPU select SYS_HAS_EARLY_PRINTK select SYS_HAS_CPU_CAVIUM_OCTEON select SWAP_IO_SPACE @@ -807,17 +784,8 @@ config SYS_HAS_EARLY_PRINTK bool config HOTPLUG_CPU - bool "Support for hot-pluggable CPUs" - depends on SMP && HOTPLUG && SYS_SUPPORTS_HOTPLUG_CPU - help - Say Y here to allow turning CPUs off and on. CPUs can be - controlled through /sys/devices/system/cpu. - (Note: power management support will enable this option - automatically on SMP systems. ) - Say N if you want to disable CPU hotplug. - -config SYS_SUPPORTS_HOTPLUG_CPU bool + default n config I8259 bool @@ -1656,7 +1624,7 @@ config MIPS_APSP_KSPD config MIPS_CMP bool "MIPS CMP framework support" depends on SYS_SUPPORTS_MIPS_CMP - select SYNC_R4K + select SYNC_R4K if BROKEN select SYS_SUPPORTS_SMP select SYS_SUPPORTS_SCHED_SMT if SMP select WEAK_ORDERING @@ -2168,11 +2136,11 @@ menu "Power management options" config ARCH_HIBERNATION_POSSIBLE def_bool y - depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP + depends on !SMP config ARCH_SUSPEND_POSSIBLE def_bool y - depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP + depends on !SMP source "kernel/power/Kconfig" diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index 861da514a468..807572a6a4d2 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -172,13 +172,6 @@ libs-y += arch/mips/fw/lib/ # Board-dependent options and extra files # -# -# Texas Instruments AR7 -# -core-$(CONFIG_AR7) += arch/mips/ar7/ -cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7 -load-$(CONFIG_AR7) += 0xffffffff94100000 - # # Acer PICA 61, Mips Magnum 4000 and Olivetti M700. # diff --git a/trunk/arch/mips/ar7/Makefile b/trunk/arch/mips/ar7/Makefile deleted file mode 100644 index 7435e44b3964..000000000000 --- a/trunk/arch/mips/ar7/Makefile +++ /dev/null @@ -1,10 +0,0 @@ - -obj-y := \ - prom.o \ - setup.o \ - memory.o \ - irq.o \ - time.o \ - platform.o \ - gpio.o \ - clock.o diff --git a/trunk/arch/mips/ar7/clock.c b/trunk/arch/mips/ar7/clock.c deleted file mode 100644 index 27dc6663f2fa..000000000000 --- a/trunk/arch/mips/ar7/clock.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) 2007 Felix Fietkau - * Copyright (C) 2007 Eugene Konev - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define BOOT_PLL_SOURCE_MASK 0x3 -#define CPU_PLL_SOURCE_SHIFT 16 -#define BUS_PLL_SOURCE_SHIFT 14 -#define USB_PLL_SOURCE_SHIFT 18 -#define DSP_PLL_SOURCE_SHIFT 22 -#define BOOT_PLL_SOURCE_AFE 0 -#define BOOT_PLL_SOURCE_BUS 0 -#define BOOT_PLL_SOURCE_REF 1 -#define BOOT_PLL_SOURCE_XTAL 2 -#define BOOT_PLL_SOURCE_CPU 3 -#define BOOT_PLL_BYPASS 0x00000020 -#define BOOT_PLL_ASYNC_MODE 0x02000000 -#define BOOT_PLL_2TO1_MODE 0x00008000 - -#define TNETD7200_CLOCK_ID_CPU 0 -#define TNETD7200_CLOCK_ID_DSP 1 -#define TNETD7200_CLOCK_ID_USB 2 - -#define TNETD7200_DEF_CPU_CLK 211000000 -#define TNETD7200_DEF_DSP_CLK 125000000 -#define TNETD7200_DEF_USB_CLK 48000000 - -struct tnetd7300_clock { - u32 ctrl; -#define PREDIV_MASK 0x001f0000 -#define PREDIV_SHIFT 16 -#define POSTDIV_MASK 0x0000001f - u32 unused1[3]; - u32 pll; -#define MUL_MASK 0x0000f000 -#define MUL_SHIFT 12 -#define PLL_MODE_MASK 0x00000001 -#define PLL_NDIV 0x00000800 -#define PLL_DIV 0x00000002 -#define PLL_STATUS 0x00000001 - u32 unused2[3]; -}; - -struct tnetd7300_clocks { - struct tnetd7300_clock bus; - struct tnetd7300_clock cpu; - struct tnetd7300_clock usb; - struct tnetd7300_clock dsp; -}; - -struct tnetd7200_clock { - u32 ctrl; - u32 unused1[3]; -#define DIVISOR_ENABLE_MASK 0x00008000 - u32 mul; - u32 prediv; - u32 postdiv; - u32 postdiv2; - u32 unused2[6]; - u32 cmd; - u32 status; - u32 cmden; - u32 padding[15]; -}; - -struct tnetd7200_clocks { - struct tnetd7200_clock cpu; - struct tnetd7200_clock dsp; - struct tnetd7200_clock usb; -}; - -int ar7_cpu_clock = 150000000; -EXPORT_SYMBOL(ar7_cpu_clock); -int ar7_bus_clock = 125000000; -EXPORT_SYMBOL(ar7_bus_clock); -int ar7_dsp_clock; -EXPORT_SYMBOL(ar7_dsp_clock); - -static void approximate(int base, int target, int *prediv, - int *postdiv, int *mul) -{ - int i, j, k, freq, res = target; - for (i = 1; i <= 16; i++) - for (j = 1; j <= 32; j++) - for (k = 1; k <= 32; k++) { - freq = abs(base / j * i / k - target); - if (freq < res) { - res = freq; - *mul = i; - *prediv = j; - *postdiv = k; - } - } -} - -static void calculate(int base, int target, int *prediv, int *postdiv, - int *mul) -{ - int tmp_gcd, tmp_base, tmp_freq; - - for (*prediv = 1; *prediv <= 32; (*prediv)++) { - tmp_base = base / *prediv; - tmp_gcd = gcd(target, tmp_base); - *mul = target / tmp_gcd; - *postdiv = tmp_base / tmp_gcd; - if ((*mul < 1) || (*mul >= 16)) - continue; - if ((*postdiv > 0) & (*postdiv <= 32)) - break; - } - - if (base / *prediv * *mul / *postdiv != target) { - approximate(base, target, prediv, postdiv, mul); - tmp_freq = base / *prediv * *mul / *postdiv; - printk(KERN_WARNING - "Adjusted requested frequency %d to %d\n", - target, tmp_freq); - } - - printk(KERN_DEBUG "Clocks: prediv: %d, postdiv: %d, mul: %d\n", - *prediv, *postdiv, *mul); -} - -static int tnetd7300_dsp_clock(void) -{ - u32 didr1, didr2; - u8 rev = ar7_chip_rev(); - didr1 = readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x18)); - didr2 = readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x1c)); - if (didr2 & (1 << 23)) - return 0; - if ((rev >= 0x23) && (rev != 0x57)) - return 250000000; - if ((((didr2 & 0x1fff) << 10) | ((didr1 & 0xffc00000) >> 22)) - > 4208000) - return 250000000; - return 0; -} - -static int tnetd7300_get_clock(u32 shift, struct tnetd7300_clock *clock, - u32 *bootcr, u32 bus_clock) -{ - int product; - int base_clock = AR7_REF_CLOCK; - u32 ctrl = readl(&clock->ctrl); - u32 pll = readl(&clock->pll); - int prediv = ((ctrl & PREDIV_MASK) >> PREDIV_SHIFT) + 1; - int postdiv = (ctrl & POSTDIV_MASK) + 1; - int divisor = prediv * postdiv; - int mul = ((pll & MUL_MASK) >> MUL_SHIFT) + 1; - - switch ((*bootcr & (BOOT_PLL_SOURCE_MASK << shift)) >> shift) { - case BOOT_PLL_SOURCE_BUS: - base_clock = bus_clock; - break; - case BOOT_PLL_SOURCE_REF: - base_clock = AR7_REF_CLOCK; - break; - case BOOT_PLL_SOURCE_XTAL: - base_clock = AR7_XTAL_CLOCK; - break; - case BOOT_PLL_SOURCE_CPU: - base_clock = ar7_cpu_clock; - break; - } - - if (*bootcr & BOOT_PLL_BYPASS) - return base_clock / divisor; - - if ((pll & PLL_MODE_MASK) == 0) - return (base_clock >> (mul / 16 + 1)) / divisor; - - if ((pll & (PLL_NDIV | PLL_DIV)) == (PLL_NDIV | PLL_DIV)) { - product = (mul & 1) ? - (base_clock * mul) >> 1 : - (base_clock * (mul - 1)) >> 2; - return product / divisor; - } - - if (mul == 16) - return base_clock / divisor; - - return base_clock * mul / divisor; -} - -static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock, - u32 *bootcr, u32 frequency) -{ - int prediv, postdiv, mul; - int base_clock = ar7_bus_clock; - - switch ((*bootcr & (BOOT_PLL_SOURCE_MASK << shift)) >> shift) { - case BOOT_PLL_SOURCE_BUS: - base_clock = ar7_bus_clock; - break; - case BOOT_PLL_SOURCE_REF: - base_clock = AR7_REF_CLOCK; - break; - case BOOT_PLL_SOURCE_XTAL: - base_clock = AR7_XTAL_CLOCK; - break; - case BOOT_PLL_SOURCE_CPU: - base_clock = ar7_cpu_clock; - break; - } - - calculate(base_clock, frequency, &prediv, &postdiv, &mul); - - writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl); - msleep(1); - writel(4, &clock->pll); - while (readl(&clock->pll) & PLL_STATUS) - ; - writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll); - msleep(75); -} - -static void __init tnetd7300_init_clocks(void) -{ - u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4); - struct tnetd7300_clocks *clocks = - ioremap_nocache(UR8_REGS_CLOCKS, - sizeof(struct tnetd7300_clocks)); - - ar7_bus_clock = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT, - &clocks->bus, bootcr, AR7_AFE_CLOCK); - - if (*bootcr & BOOT_PLL_ASYNC_MODE) - ar7_cpu_clock = tnetd7300_get_clock(CPU_PLL_SOURCE_SHIFT, - &clocks->cpu, bootcr, AR7_AFE_CLOCK); - else - ar7_cpu_clock = ar7_bus_clock; - - if (ar7_dsp_clock == 250000000) - tnetd7300_set_clock(DSP_PLL_SOURCE_SHIFT, &clocks->dsp, - bootcr, ar7_dsp_clock); - - iounmap(clocks); - iounmap(bootcr); -} - -static int tnetd7200_get_clock(int base, struct tnetd7200_clock *clock, - u32 *bootcr, u32 bus_clock) -{ - int divisor = ((readl(&clock->prediv) & 0x1f) + 1) * - ((readl(&clock->postdiv) & 0x1f) + 1); - - if (*bootcr & BOOT_PLL_BYPASS) - return base / divisor; - - return base * ((readl(&clock->mul) & 0xf) + 1) / divisor; -} - - -static void tnetd7200_set_clock(int base, struct tnetd7200_clock *clock, - int prediv, int postdiv, int postdiv2, int mul, u32 frequency) -{ - printk(KERN_INFO - "Clocks: base = %d, frequency = %u, prediv = %d, " - "postdiv = %d, postdiv2 = %d, mul = %d\n", - base, frequency, prediv, postdiv, postdiv2, mul); - - writel(0, &clock->ctrl); - writel(DIVISOR_ENABLE_MASK | ((prediv - 1) & 0x1F), &clock->prediv); - writel((mul - 1) & 0xF, &clock->mul); - - while (readl(&clock->status) & 0x1) - ; /* nop */ - - writel(DIVISOR_ENABLE_MASK | ((postdiv - 1) & 0x1F), &clock->postdiv); - - writel(readl(&clock->cmden) | 1, &clock->cmden); - writel(readl(&clock->cmd) | 1, &clock->cmd); - - while (readl(&clock->status) & 0x1) - ; /* nop */ - - writel(DIVISOR_ENABLE_MASK | ((postdiv2 - 1) & 0x1F), &clock->postdiv2); - - writel(readl(&clock->cmden) | 1, &clock->cmden); - writel(readl(&clock->cmd) | 1, &clock->cmd); - - while (readl(&clock->status) & 0x1) - ; /* nop */ - - writel(readl(&clock->ctrl) | 1, &clock->ctrl); -} - -static int tnetd7200_get_clock_base(int clock_id, u32 *bootcr) -{ - if (*bootcr & BOOT_PLL_ASYNC_MODE) - /* Async */ - switch (clock_id) { - case TNETD7200_CLOCK_ID_DSP: - return AR7_REF_CLOCK; - default: - return AR7_AFE_CLOCK; - } - else - /* Sync */ - if (*bootcr & BOOT_PLL_2TO1_MODE) - /* 2:1 */ - switch (clock_id) { - case TNETD7200_CLOCK_ID_DSP: - return AR7_REF_CLOCK; - default: - return AR7_AFE_CLOCK; - } - else - /* 1:1 */ - return AR7_REF_CLOCK; -} - - -static void __init tnetd7200_init_clocks(void) -{ - u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4); - struct tnetd7200_clocks *clocks = - ioremap_nocache(AR7_REGS_CLOCKS, - sizeof(struct tnetd7200_clocks)); - int cpu_base, cpu_mul, cpu_prediv, cpu_postdiv; - int dsp_base, dsp_mul, dsp_prediv, dsp_postdiv; - int usb_base, usb_mul, usb_prediv, usb_postdiv; - - cpu_base = tnetd7200_get_clock_base(TNETD7200_CLOCK_ID_CPU, bootcr); - dsp_base = tnetd7200_get_clock_base(TNETD7200_CLOCK_ID_DSP, bootcr); - - if (*bootcr & BOOT_PLL_ASYNC_MODE) { - printk(KERN_INFO "Clocks: Async mode\n"); - - printk(KERN_INFO "Clocks: Setting DSP clock\n"); - calculate(dsp_base, TNETD7200_DEF_DSP_CLK, - &dsp_prediv, &dsp_postdiv, &dsp_mul); - ar7_bus_clock = - ((dsp_base / dsp_prediv) * dsp_mul) / dsp_postdiv; - tnetd7200_set_clock(dsp_base, &clocks->dsp, - dsp_prediv, dsp_postdiv * 2, dsp_postdiv, dsp_mul * 2, - ar7_bus_clock); - - printk(KERN_INFO "Clocks: Setting CPU clock\n"); - calculate(cpu_base, TNETD7200_DEF_CPU_CLK, &cpu_prediv, - &cpu_postdiv, &cpu_mul); - ar7_cpu_clock = - ((cpu_base / cpu_prediv) * cpu_mul) / cpu_postdiv; - tnetd7200_set_clock(cpu_base, &clocks->cpu, - cpu_prediv, cpu_postdiv, -1, cpu_mul, - ar7_cpu_clock); - - } else - if (*bootcr & BOOT_PLL_2TO1_MODE) { - printk(KERN_INFO "Clocks: Sync 2:1 mode\n"); - - printk(KERN_INFO "Clocks: Setting CPU clock\n"); - calculate(cpu_base, TNETD7200_DEF_CPU_CLK, &cpu_prediv, - &cpu_postdiv, &cpu_mul); - ar7_cpu_clock = ((cpu_base / cpu_prediv) * cpu_mul) - / cpu_postdiv; - tnetd7200_set_clock(cpu_base, &clocks->cpu, - cpu_prediv, cpu_postdiv, -1, cpu_mul, - ar7_cpu_clock); - - printk(KERN_INFO "Clocks: Setting DSP clock\n"); - calculate(dsp_base, TNETD7200_DEF_DSP_CLK, &dsp_prediv, - &dsp_postdiv, &dsp_mul); - ar7_bus_clock = ar7_cpu_clock / 2; - tnetd7200_set_clock(dsp_base, &clocks->dsp, - dsp_prediv, dsp_postdiv * 2, dsp_postdiv, - dsp_mul * 2, ar7_bus_clock); - } else { - printk(KERN_INFO "Clocks: Sync 1:1 mode\n"); - - printk(KERN_INFO "Clocks: Setting DSP clock\n"); - calculate(dsp_base, TNETD7200_DEF_DSP_CLK, &dsp_prediv, - &dsp_postdiv, &dsp_mul); - ar7_bus_clock = ((dsp_base / dsp_prediv) * dsp_mul) - / dsp_postdiv; - tnetd7200_set_clock(dsp_base, &clocks->dsp, - dsp_prediv, dsp_postdiv * 2, dsp_postdiv, - dsp_mul * 2, ar7_bus_clock); - - ar7_cpu_clock = ar7_bus_clock; - } - - printk(KERN_INFO "Clocks: Setting USB clock\n"); - usb_base = ar7_bus_clock; - calculate(usb_base, TNETD7200_DEF_USB_CLK, &usb_prediv, - &usb_postdiv, &usb_mul); - tnetd7200_set_clock(usb_base, &clocks->usb, - usb_prediv, usb_postdiv, -1, usb_mul, - TNETD7200_DEF_USB_CLK); - - ar7_dsp_clock = ar7_cpu_clock; - - iounmap(clocks); - iounmap(bootcr); -} - -int __init ar7_init_clocks(void) -{ - switch (ar7_chip_id()) { - case AR7_CHIP_7100: - case AR7_CHIP_7200: - tnetd7200_init_clocks(); - break; - case AR7_CHIP_7300: - ar7_dsp_clock = tnetd7300_dsp_clock(); - tnetd7300_init_clocks(); - break; - default: - break; - } - - return 0; -} -arch_initcall(ar7_init_clocks); diff --git a/trunk/arch/mips/ar7/gpio.c b/trunk/arch/mips/ar7/gpio.c deleted file mode 100644 index 74e14a3dbf4a..000000000000 --- a/trunk/arch/mips/ar7/gpio.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2007 Felix Fietkau - * Copyright (C) 2007 Eugene Konev - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include - -static const char *ar7_gpio_list[AR7_GPIO_MAX]; - -int gpio_request(unsigned gpio, const char *label) -{ - if (gpio >= AR7_GPIO_MAX) - return -EINVAL; - - if (ar7_gpio_list[gpio]) - return -EBUSY; - - if (label) - ar7_gpio_list[gpio] = label; - else - ar7_gpio_list[gpio] = "busy"; - - return 0; -} -EXPORT_SYMBOL(gpio_request); - -void gpio_free(unsigned gpio) -{ - BUG_ON(!ar7_gpio_list[gpio]); - ar7_gpio_list[gpio] = NULL; -} -EXPORT_SYMBOL(gpio_free); diff --git a/trunk/arch/mips/ar7/irq.c b/trunk/arch/mips/ar7/irq.c deleted file mode 100644 index c781556c44e4..000000000000 --- a/trunk/arch/mips/ar7/irq.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2006,2007 Felix Fietkau - * Copyright (C) 2006,2007 Eugene Konev - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include -#include -#include - -#define EXCEPT_OFFSET 0x80 -#define PACE_OFFSET 0xA0 -#define CHNLS_OFFSET 0x200 - -#define REG_OFFSET(irq, reg) ((irq) / 32 * 0x4 + reg * 0x10) -#define SEC_REG_OFFSET(reg) (EXCEPT_OFFSET + reg * 0x8) -#define SEC_SR_OFFSET (SEC_REG_OFFSET(0)) /* 0x80 */ -#define CR_OFFSET(irq) (REG_OFFSET(irq, 1)) /* 0x10 */ -#define SEC_CR_OFFSET (SEC_REG_OFFSET(1)) /* 0x88 */ -#define ESR_OFFSET(irq) (REG_OFFSET(irq, 2)) /* 0x20 */ -#define SEC_ESR_OFFSET (SEC_REG_OFFSET(2)) /* 0x90 */ -#define ECR_OFFSET(irq) (REG_OFFSET(irq, 3)) /* 0x30 */ -#define SEC_ECR_OFFSET (SEC_REG_OFFSET(3)) /* 0x98 */ -#define PIR_OFFSET (0x40) -#define MSR_OFFSET (0x44) -#define PM_OFFSET(irq) (REG_OFFSET(irq, 5)) /* 0x50 */ -#define TM_OFFSET(irq) (REG_OFFSET(irq, 6)) /* 0x60 */ - -#define REG(addr) ((u32 *)(KSEG1ADDR(AR7_REGS_IRQ) + addr)) - -#define CHNL_OFFSET(chnl) (CHNLS_OFFSET + (chnl * 4)) - -static int ar7_irq_base; - -static void ar7_unmask_irq(unsigned int irq) -{ - writel(1 << ((irq - ar7_irq_base) % 32), - REG(ESR_OFFSET(irq - ar7_irq_base))); -} - -static void ar7_mask_irq(unsigned int irq) -{ - writel(1 << ((irq - ar7_irq_base) % 32), - REG(ECR_OFFSET(irq - ar7_irq_base))); -} - -static void ar7_ack_irq(unsigned int irq) -{ - writel(1 << ((irq - ar7_irq_base) % 32), - REG(CR_OFFSET(irq - ar7_irq_base))); -} - -static void ar7_unmask_sec_irq(unsigned int irq) -{ - writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET)); -} - -static void ar7_mask_sec_irq(unsigned int irq) -{ - writel(1 << (irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET)); -} - -static void ar7_ack_sec_irq(unsigned int irq) -{ - writel(1 << (irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET)); -} - -static struct irq_chip ar7_irq_type = { - .name = "AR7", - .unmask = ar7_unmask_irq, - .mask = ar7_mask_irq, - .ack = ar7_ack_irq -}; - -static struct irq_chip ar7_sec_irq_type = { - .name = "AR7", - .unmask = ar7_unmask_sec_irq, - .mask = ar7_mask_sec_irq, - .ack = ar7_ack_sec_irq, -}; - -static struct irqaction ar7_cascade_action = { - .handler = no_action, - .name = "AR7 cascade interrupt" -}; - -static void __init ar7_irq_init(int base) -{ - int i; - /* - * Disable interrupts and clear pending - */ - writel(0xffffffff, REG(ECR_OFFSET(0))); - writel(0xff, REG(ECR_OFFSET(32))); - writel(0xffffffff, REG(SEC_ECR_OFFSET)); - writel(0xffffffff, REG(CR_OFFSET(0))); - writel(0xff, REG(CR_OFFSET(32))); - writel(0xffffffff, REG(SEC_CR_OFFSET)); - - ar7_irq_base = base; - - for (i = 0; i < 40; i++) { - writel(i, REG(CHNL_OFFSET(i))); - /* Primary IRQ's */ - set_irq_chip_and_handler(base + i, &ar7_irq_type, - handle_level_irq); - /* Secondary IRQ's */ - if (i < 32) - set_irq_chip_and_handler(base + i + 40, - &ar7_sec_irq_type, - handle_level_irq); - } - - setup_irq(2, &ar7_cascade_action); - setup_irq(ar7_irq_base, &ar7_cascade_action); - set_c0_status(IE_IRQ0); -} - -void __init arch_init_irq(void) -{ - mips_cpu_irq_init(); - ar7_irq_init(8); -} - -static void ar7_cascade(void) -{ - u32 status; - int i, irq; - - /* Primary IRQ's */ - irq = readl(REG(PIR_OFFSET)) & 0x3f; - if (irq) { - do_IRQ(ar7_irq_base + irq); - return; - } - - /* Secondary IRQ's are cascaded through primary '0' */ - writel(1, REG(CR_OFFSET(irq))); - status = readl(REG(SEC_SR_OFFSET)); - for (i = 0; i < 32; i++) { - if (status & 1) { - do_IRQ(ar7_irq_base + i + 40); - return; - } - status >>= 1; - } - - spurious_interrupt(); -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; - if (pending & STATUSF_IP7) /* cpu timer */ - do_IRQ(7); - else if (pending & STATUSF_IP2) /* int0 hardware line */ - ar7_cascade(); - else - spurious_interrupt(); -} diff --git a/trunk/arch/mips/ar7/memory.c b/trunk/arch/mips/ar7/memory.c deleted file mode 100644 index 46fed44825a6..000000000000 --- a/trunk/arch/mips/ar7/memory.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2007 Felix Fietkau - * Copyright (C) 2007 Eugene Konev - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -static int __init memsize(void) -{ - u32 size = (64 << 20); - u32 *addr = (u32 *)KSEG1ADDR(AR7_SDRAM_BASE + size - 4); - u32 *kernel_end = (u32 *)KSEG1ADDR(CPHYSADDR((u32)&_end)); - u32 *tmpaddr = addr; - - while (tmpaddr > kernel_end) { - *tmpaddr = (u32)tmpaddr; - size >>= 1; - tmpaddr -= size >> 2; - } - - do { - tmpaddr += size >> 2; - if (*tmpaddr != (u32)tmpaddr) - break; - size <<= 1; - } while (size < (64 << 20)); - - writel(tmpaddr, &addr); - - return size; -} - -void __init prom_meminit(void) -{ - unsigned long pages; - - pages = memsize() >> PAGE_SHIFT; - add_memory_region(PHYS_OFFSET, pages << PAGE_SHIFT, - BOOT_MEM_RAM); -} - -void __init prom_free_prom_memory(void) -{ - /* Nothing to free */ -} diff --git a/trunk/arch/mips/ar7/platform.c b/trunk/arch/mips/ar7/platform.c deleted file mode 100644 index 542244961780..000000000000 --- a/trunk/arch/mips/ar7/platform.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Copyright (C) 2006,2007 Felix Fietkau - * Copyright (C) 2006,2007 Eugene Konev - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -struct plat_vlynq_data { - struct plat_vlynq_ops ops; - int gpio_bit; - int reset_bit; -}; - - -static int vlynq_on(struct vlynq_device *dev) -{ - int result; - struct plat_vlynq_data *pdata = dev->dev.platform_data; - - result = gpio_request(pdata->gpio_bit, "vlynq"); - if (result) - goto out; - - ar7_device_reset(pdata->reset_bit); - - result = ar7_gpio_disable(pdata->gpio_bit); - if (result) - goto out_enabled; - - result = ar7_gpio_enable(pdata->gpio_bit); - if (result) - goto out_enabled; - - result = gpio_direction_output(pdata->gpio_bit, 0); - if (result) - goto out_gpio_enabled; - - msleep(50); - - gpio_set_value(pdata->gpio_bit, 1); - msleep(50); - - return 0; - -out_gpio_enabled: - ar7_gpio_disable(pdata->gpio_bit); -out_enabled: - ar7_device_disable(pdata->reset_bit); - gpio_free(pdata->gpio_bit); -out: - return result; -} - -static void vlynq_off(struct vlynq_device *dev) -{ - struct plat_vlynq_data *pdata = dev->dev.platform_data; - ar7_gpio_disable(pdata->gpio_bit); - gpio_free(pdata->gpio_bit); - ar7_device_disable(pdata->reset_bit); -} - -static struct resource physmap_flash_resource = { - .name = "mem", - .flags = IORESOURCE_MEM, - .start = 0x10000000, - .end = 0x107fffff, -}; - -static struct resource cpmac_low_res[] = { - { - .name = "regs", - .flags = IORESOURCE_MEM, - .start = AR7_REGS_MAC0, - .end = AR7_REGS_MAC0 + 0x7ff, - }, - { - .name = "irq", - .flags = IORESOURCE_IRQ, - .start = 27, - .end = 27, - }, -}; - -static struct resource cpmac_high_res[] = { - { - .name = "regs", - .flags = IORESOURCE_MEM, - .start = AR7_REGS_MAC1, - .end = AR7_REGS_MAC1 + 0x7ff, - }, - { - .name = "irq", - .flags = IORESOURCE_IRQ, - .start = 41, - .end = 41, - }, -}; - -static struct resource vlynq_low_res[] = { - { - .name = "regs", - .flags = IORESOURCE_MEM, - .start = AR7_REGS_VLYNQ0, - .end = AR7_REGS_VLYNQ0 + 0xff, - }, - { - .name = "irq", - .flags = IORESOURCE_IRQ, - .start = 29, - .end = 29, - }, - { - .name = "mem", - .flags = IORESOURCE_MEM, - .start = 0x04000000, - .end = 0x04ffffff, - }, - { - .name = "devirq", - .flags = IORESOURCE_IRQ, - .start = 80, - .end = 111, - }, -}; - -static struct resource vlynq_high_res[] = { - { - .name = "regs", - .flags = IORESOURCE_MEM, - .start = AR7_REGS_VLYNQ1, - .end = AR7_REGS_VLYNQ1 + 0xff, - }, - { - .name = "irq", - .flags = IORESOURCE_IRQ, - .start = 33, - .end = 33, - }, - { - .name = "mem", - .flags = IORESOURCE_MEM, - .start = 0x0c000000, - .end = 0x0cffffff, - }, - { - .name = "devirq", - .flags = IORESOURCE_IRQ, - .start = 112, - .end = 143, - }, -}; - -static struct resource usb_res[] = { - { - .name = "regs", - .flags = IORESOURCE_MEM, - .start = AR7_REGS_USB, - .end = AR7_REGS_USB + 0xff, - }, - { - .name = "irq", - .flags = IORESOURCE_IRQ, - .start = 32, - .end = 32, - }, - { - .name = "mem", - .flags = IORESOURCE_MEM, - .start = 0x03400000, - .end = 0x034001fff, - }, -}; - -static struct physmap_flash_data physmap_flash_data = { - .width = 2, -}; - -static struct plat_cpmac_data cpmac_low_data = { - .reset_bit = 17, - .power_bit = 20, - .phy_mask = 0x80000000, -}; - -static struct plat_cpmac_data cpmac_high_data = { - .reset_bit = 21, - .power_bit = 22, - .phy_mask = 0x7fffffff, -}; - -static struct plat_vlynq_data vlynq_low_data = { - .ops.on = vlynq_on, - .ops.off = vlynq_off, - .reset_bit = 20, - .gpio_bit = 18, -}; - -static struct plat_vlynq_data vlynq_high_data = { - .ops.on = vlynq_on, - .ops.off = vlynq_off, - .reset_bit = 16, - .gpio_bit = 19, -}; - -static struct platform_device physmap_flash = { - .id = 0, - .name = "physmap-flash", - .dev.platform_data = &physmap_flash_data, - .resource = &physmap_flash_resource, - .num_resources = 1, -}; - -static u64 cpmac_dma_mask = DMA_32BIT_MASK; -static struct platform_device cpmac_low = { - .id = 0, - .name = "cpmac", - .dev = { - .dma_mask = &cpmac_dma_mask, - .coherent_dma_mask = DMA_32BIT_MASK, - .platform_data = &cpmac_low_data, - }, - .resource = cpmac_low_res, - .num_resources = ARRAY_SIZE(cpmac_low_res), -}; - -static struct platform_device cpmac_high = { - .id = 1, - .name = "cpmac", - .dev = { - .dma_mask = &cpmac_dma_mask, - .coherent_dma_mask = DMA_32BIT_MASK, - .platform_data = &cpmac_high_data, - }, - .resource = cpmac_high_res, - .num_resources = ARRAY_SIZE(cpmac_high_res), -}; - -static struct platform_device vlynq_low = { - .id = 0, - .name = "vlynq", - .dev.platform_data = &vlynq_low_data, - .resource = vlynq_low_res, - .num_resources = ARRAY_SIZE(vlynq_low_res), -}; - -static struct platform_device vlynq_high = { - .id = 1, - .name = "vlynq", - .dev.platform_data = &vlynq_high_data, - .resource = vlynq_high_res, - .num_resources = ARRAY_SIZE(vlynq_high_res), -}; - - -static struct gpio_led default_leds[] = { - { - .name = "status", - .gpio = 8, - .active_low = 1, - }, -}; - -static struct gpio_led dsl502t_leds[] = { - { - .name = "status", - .gpio = 9, - .active_low = 1, - }, - { - .name = "ethernet", - .gpio = 7, - .active_low = 1, - }, - { - .name = "usb", - .gpio = 12, - .active_low = 1, - }, -}; - -static struct gpio_led dg834g_leds[] = { - { - .name = "ppp", - .gpio = 6, - .active_low = 1, - }, - { - .name = "status", - .gpio = 7, - .active_low = 1, - }, - { - .name = "adsl", - .gpio = 8, - .active_low = 1, - }, - { - .name = "wifi", - .gpio = 12, - .active_low = 1, - }, - { - .name = "power", - .gpio = 14, - .active_low = 1, - .default_trigger = "default-on", - }, -}; - -static struct gpio_led fb_sl_leds[] = { - { - .name = "1", - .gpio = 7, - }, - { - .name = "2", - .gpio = 13, - .active_low = 1, - }, - { - .name = "3", - .gpio = 10, - .active_low = 1, - }, - { - .name = "4", - .gpio = 12, - .active_low = 1, - }, - { - .name = "5", - .gpio = 9, - .active_low = 1, - }, -}; - -static struct gpio_led fb_fon_leds[] = { - { - .name = "1", - .gpio = 8, - }, - { - .name = "2", - .gpio = 3, - .active_low = 1, - }, - { - .name = "3", - .gpio = 5, - }, - { - .name = "4", - .gpio = 4, - .active_low = 1, - }, - { - .name = "5", - .gpio = 11, - .active_low = 1, - }, -}; - -static struct gpio_led_platform_data ar7_led_data; - -static struct platform_device ar7_gpio_leds = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &ar7_led_data, - } -}; - -static struct platform_device ar7_udc = { - .id = -1, - .name = "ar7_udc", - .resource = usb_res, - .num_resources = ARRAY_SIZE(usb_res), -}; - -static inline unsigned char char2hex(char h) -{ - switch (h) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - return h - '0'; - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - return h - 'A' + 10; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - return h - 'a' + 10; - default: - return 0; - } -} - -static void cpmac_get_mac(int instance, unsigned char *dev_addr) -{ - int i; - char name[5], default_mac[ETH_ALEN], *mac; - - mac = NULL; - sprintf(name, "mac%c", 'a' + instance); - mac = prom_getenv(name); - if (!mac) { - sprintf(name, "mac%c", 'a'); - mac = prom_getenv(name); - } - if (!mac) { - random_ether_addr(default_mac); - mac = default_mac; - } - for (i = 0; i < 6; i++) - dev_addr[i] = (char2hex(mac[i * 3]) << 4) + - char2hex(mac[i * 3 + 1]); -} - -static void __init detect_leds(void) -{ - char *prid, *usb_prod; - - /* Default LEDs */ - ar7_led_data.num_leds = ARRAY_SIZE(default_leds); - ar7_led_data.leds = default_leds; - - /* FIXME: the whole thing is unreliable */ - prid = prom_getenv("ProductID"); - usb_prod = prom_getenv("usb_prod"); - - /* If we can't get the product id from PROM, use the default LEDs */ - if (!prid) - return; - - if (strstr(prid, "Fritz_Box_FON")) { - ar7_led_data.num_leds = ARRAY_SIZE(fb_fon_leds); - ar7_led_data.leds = fb_fon_leds; - } else if (strstr(prid, "Fritz_Box_")) { - ar7_led_data.num_leds = ARRAY_SIZE(fb_sl_leds); - ar7_led_data.leds = fb_sl_leds; - } else if ((!strcmp(prid, "AR7RD") || !strcmp(prid, "AR7DB")) - && usb_prod != NULL && strstr(usb_prod, "DSL-502T")) { - ar7_led_data.num_leds = ARRAY_SIZE(dsl502t_leds); - ar7_led_data.leds = dsl502t_leds; - } else if (strstr(prid, "DG834")) { - ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds); - ar7_led_data.leds = dg834g_leds; - } -} - -static int __init ar7_register_devices(void) -{ - int res; - static struct uart_port uart_port[2]; - - memset(uart_port, 0, sizeof(struct uart_port) * 2); - - uart_port[0].type = PORT_16550A; - uart_port[0].line = 0; - uart_port[0].irq = AR7_IRQ_UART0; - uart_port[0].uartclk = ar7_bus_freq() / 2; - uart_port[0].iotype = UPIO_MEM32; - uart_port[0].mapbase = AR7_REGS_UART0; - uart_port[0].membase = ioremap(uart_port[0].mapbase, 256); - uart_port[0].regshift = 2; - res = early_serial_setup(&uart_port[0]); - if (res) - return res; - - - /* Only TNETD73xx have a second serial port */ - if (ar7_has_second_uart()) { - uart_port[1].type = PORT_16550A; - uart_port[1].line = 1; - uart_port[1].irq = AR7_IRQ_UART1; - uart_port[1].uartclk = ar7_bus_freq() / 2; - uart_port[1].iotype = UPIO_MEM32; - uart_port[1].mapbase = UR8_REGS_UART1; - uart_port[1].membase = ioremap(uart_port[1].mapbase, 256); - uart_port[1].regshift = 2; - res = early_serial_setup(&uart_port[1]); - if (res) - return res; - } - - res = platform_device_register(&physmap_flash); - if (res) - return res; - - ar7_device_disable(vlynq_low_data.reset_bit); - res = platform_device_register(&vlynq_low); - if (res) - return res; - - if (ar7_has_high_vlynq()) { - ar7_device_disable(vlynq_high_data.reset_bit); - res = platform_device_register(&vlynq_high); - if (res) - return res; - } - - if (ar7_has_high_cpmac()) { - cpmac_get_mac(1, cpmac_high_data.dev_addr); - res = platform_device_register(&cpmac_high); - if (res) - return res; - } else { - cpmac_low_data.phy_mask = 0xffffffff; - } - - cpmac_get_mac(0, cpmac_low_data.dev_addr); - res = platform_device_register(&cpmac_low); - if (res) - return res; - - detect_leds(); - res = platform_device_register(&ar7_gpio_leds); - if (res) - return res; - - res = platform_device_register(&ar7_udc); - - return res; -} -arch_initcall(ar7_register_devices); diff --git a/trunk/arch/mips/ar7/prom.c b/trunk/arch/mips/ar7/prom.c deleted file mode 100644 index a320bceb2f9d..000000000000 --- a/trunk/arch/mips/ar7/prom.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute 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 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. - * - * Putting things on the screen/serial line using YAMONs facilities. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define MAX_ENTRY 80 - -struct env_var { - char *name; - char *value; -}; - -static struct env_var adam2_env[MAX_ENTRY]; - -char *prom_getenv(const char *name) -{ - int i; - for (i = 0; (i < MAX_ENTRY) && adam2_env[i].name; i++) - if (!strcmp(name, adam2_env[i].name)) - return adam2_env[i].value; - - return NULL; -} -EXPORT_SYMBOL(prom_getenv); - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - -static void __init ar7_init_cmdline(int argc, char *argv[]) -{ - char *cp; - int actr; - - actr = 1; /* Always ignore argv[0] */ - - cp = &(arcs_cmdline[0]); - while (actr < argc) { - strcpy(cp, argv[actr]); - cp += strlen(argv[actr]); - *cp++ = ' '; - actr++; - } - if (cp != &(arcs_cmdline[0])) { - /* get rid of trailing space */ - --cp; - *cp = '\0'; - } -} - -struct psbl_rec { - u32 psbl_size; - u32 env_base; - u32 env_size; - u32 ffs_base; - u32 ffs_size; -}; - -static __initdata char psp_env_version[] = "TIENV0.8"; - -struct psp_env_chunk { - u8 num; - u8 ctrl; - u16 csum; - u8 len; - char data[11]; -} __attribute__ ((packed)); - -struct psp_var_map_entry { - u8 num; - char *value; -}; - -static struct psp_var_map_entry psp_var_map[] = { - { 1, "cpufrequency" }, - { 2, "memsize" }, - { 3, "flashsize" }, - { 4, "modetty0" }, - { 5, "modetty1" }, - { 8, "maca" }, - { 9, "macb" }, - { 28, "sysfrequency" }, - { 38, "mipsfrequency" }, -}; - -/* - -Well-known variable (num is looked up in table above for matching variable name) -Example: cpufrequency=211968000 -+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+--- -| 01 |CTRL|CHECKSUM | 01 | _2 | _1 | _1 | _9 | _6 | _8 | _0 | _0 | _0 | \0 | FF -+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+--- - -Name=Value pair in a single chunk -Example: NAME=VALUE -+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+--- -| 00 |CTRL|CHECKSUM | 01 | _N | _A | _M | _E | _0 | _V | _A | _L | _U | _E | \0 -+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+--- - -Name=Value pair in 2 chunks (len is the number of chunks) -Example: bootloaderVersion=1.3.7.15 -+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+--- -| 00 |CTRL|CHECKSUM | 02 | _b | _o | _o | _t | _l | _o | _a | _d | _e | _r | _V -+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+--- -| _e | _r | _s | _i | _o | _n | \0 | _1 | _. | _3 | _. | _7 | _. | _1 | _5 | \0 -+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+--- - -Data is padded with 0xFF - -*/ - -#define PSP_ENV_SIZE 4096 - -static char psp_env_data[PSP_ENV_SIZE] = { 0, }; - -static char * __init lookup_psp_var_map(u8 num) -{ - int i; - - for (i = 0; i < sizeof(psp_var_map); i++) - if (psp_var_map[i].num == num) - return psp_var_map[i].value; - - return NULL; -} - -static void __init add_adam2_var(char *name, char *value) -{ - int i; - for (i = 0; i < MAX_ENTRY; i++) { - if (!adam2_env[i].name) { - adam2_env[i].name = name; - adam2_env[i].value = value; - return; - } else if (!strcmp(adam2_env[i].name, name)) { - adam2_env[i].value = value; - return; - } - } -} - -static int __init parse_psp_env(void *psp_env_base) -{ - int i, n; - char *name, *value; - struct psp_env_chunk *chunks = (struct psp_env_chunk *)psp_env_data; - - memcpy_fromio(chunks, psp_env_base, PSP_ENV_SIZE); - - i = 1; - n = PSP_ENV_SIZE / sizeof(struct psp_env_chunk); - while (i < n) { - if ((chunks[i].num == 0xff) || ((i + chunks[i].len) > n)) - break; - value = chunks[i].data; - if (chunks[i].num) { - name = lookup_psp_var_map(chunks[i].num); - } else { - name = value; - value += strlen(name) + 1; - } - if (name) - add_adam2_var(name, value); - i += chunks[i].len; - } - return 0; -} - -static void __init ar7_init_env(struct env_var *env) -{ - int i; - struct psbl_rec *psbl = (struct psbl_rec *)(KSEG1ADDR(0x14000300)); - void *psp_env = (void *)KSEG1ADDR(psbl->env_base); - - if (strcmp(psp_env, psp_env_version) == 0) { - parse_psp_env(psp_env); - } else { - for (i = 0; i < MAX_ENTRY; i++, env++) - if (env->name) - add_adam2_var(env->name, env->value); - } -} - -static void __init console_config(void) -{ -#ifdef CONFIG_SERIAL_8250_CONSOLE - char console_string[40]; - int baud = 0; - char parity = '\0', bits = '\0', flow = '\0'; - char *s, *p; - - if (strstr(prom_getcmdline(), "console=")) - return; - -#ifdef CONFIG_KGDB - if (!strstr(prom_getcmdline(), "nokgdb")) { - strcat(prom_getcmdline(), " console=kgdb"); - kgdb_enabled = 1; - return; - } -#endif - - s = prom_getenv("modetty0"); - if (s) { - baud = simple_strtoul(s, &p, 10); - s = p; - if (*s == ',') - s++; - if (*s) - parity = *s++; - if (*s == ',') - s++; - if (*s) - bits = *s++; - if (*s == ',') - s++; - if (*s == 'h') - flow = 'r'; - } - - if (baud == 0) - baud = 38400; - if (parity != 'n' && parity != 'o' && parity != 'e') - parity = 'n'; - if (bits != '7' && bits != '8') - bits = '8'; - - if (flow == 'r') - sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, - parity, bits, flow); - else - sprintf(console_string, " console=ttyS0,%d%c%c", baud, parity, - bits); - strcat(prom_getcmdline(), console_string); -#endif -} - -void __init prom_init(void) -{ - ar7_init_cmdline(fw_arg0, (char **)fw_arg1); - ar7_init_env((struct env_var *)fw_arg2); - console_config(); -} - -#define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4))) -static inline unsigned int serial_in(int offset) -{ - return readl((void *)PORT(offset)); -} - -static inline void serial_out(int offset, int value) -{ - writel(value, (void *)PORT(offset)); -} - -char prom_getchar(void) -{ - while (!(serial_in(UART_LSR) & UART_LSR_DR)) - ; - return serial_in(UART_RX); -} - -int prom_putchar(char c) -{ - while ((serial_in(UART_LSR) & UART_LSR_TEMT) == 0) - ; - serial_out(UART_TX, c); - return 1; -} - diff --git a/trunk/arch/mips/ar7/setup.c b/trunk/arch/mips/ar7/setup.c deleted file mode 100644 index 6ebb5f16d967..000000000000 --- a/trunk/arch/mips/ar7/setup.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute 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 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. - */ -#include -#include -#include -#include -#include - -#include -#include -#include - -static void ar7_machine_restart(char *command) -{ - u32 *softres_reg = ioremap(AR7_REGS_RESET + - AR7_RESET_SOFTWARE, 1); - writel(1, softres_reg); -} - -static void ar7_machine_halt(void) -{ - while (1) - ; -} - -static void ar7_machine_power_off(void) -{ - u32 *power_reg = (u32 *)ioremap(AR7_REGS_POWER, 1); - u32 power_state = readl(power_reg) | (3 << 30); - writel(power_state, power_reg); - ar7_machine_halt(); -} - -const char *get_system_type(void) -{ - u16 chip_id = ar7_chip_id(); - switch (chip_id) { - case AR7_CHIP_7300: - return "TI AR7 (TNETD7300)"; - case AR7_CHIP_7100: - return "TI AR7 (TNETD7100)"; - case AR7_CHIP_7200: - return "TI AR7 (TNETD7200)"; - default: - return "TI AR7 (Unknown)"; - } -} - -static int __init ar7_init_console(void) -{ - return 0; -} -console_initcall(ar7_init_console); - -/* - * Initializes basic routines and structures pointers, memory size (as - * given by the bios and saves the command line. - */ - -void __init plat_mem_setup(void) -{ - unsigned long io_base; - - _machine_restart = ar7_machine_restart; - _machine_halt = ar7_machine_halt; - pm_power_off = ar7_machine_power_off; - panic_timeout = 3; - - io_base = (unsigned long)ioremap(AR7_REGS_BASE, 0x10000); - if (!io_base) - panic("Can't remap IO base!\n"); - set_io_port_base(io_base); - - prom_meminit(); - - printk(KERN_INFO "%s, ID: 0x%04x, Revision: 0x%02x\n", - get_system_type(), - ar7_chip_id(), ar7_chip_rev()); -} diff --git a/trunk/arch/mips/ar7/time.c b/trunk/arch/mips/ar7/time.c deleted file mode 100644 index a1fba894daa2..000000000000 --- a/trunk/arch/mips/ar7/time.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute 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 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. - * - * Setting up the clock on the MIPS boards. - */ - -#include -#include - -#include -#include - -void __init plat_time_init(void) -{ - mips_hpt_frequency = ar7_cpu_freq() / 2; -} diff --git a/trunk/arch/mips/cavium-octeon/Makefile b/trunk/arch/mips/cavium-octeon/Makefile index d6903c3f3d51..7c0528b0e34c 100644 --- a/trunk/arch/mips/cavium-octeon/Makefile +++ b/trunk/arch/mips/cavium-octeon/Makefile @@ -14,5 +14,9 @@ obj-y += dma-octeon.o flash_setup.o obj-y += octeon-memcpy.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_PCI) += pci-common.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_PCI) += pcie.o +obj-$(CONFIG_PCI_MSI) += msi.o EXTRA_CFLAGS += -Werror diff --git a/trunk/arch/mips/cavium-octeon/dma-octeon.c b/trunk/arch/mips/cavium-octeon/dma-octeon.c index 4b92bfc662db..627c162a6159 100644 --- a/trunk/arch/mips/cavium-octeon/dma-octeon.c +++ b/trunk/arch/mips/cavium-octeon/dma-octeon.c @@ -29,7 +29,7 @@ #include #ifdef CONFIG_PCI -#include +#include "pci-common.h" #endif #define BAR2_PCI_ADDRESS 0x8000000000ul diff --git a/trunk/arch/mips/pci/msi-octeon.c b/trunk/arch/mips/cavium-octeon/msi.c similarity index 88% rename from trunk/arch/mips/pci/msi-octeon.c rename to trunk/arch/mips/cavium-octeon/msi.c index 03742e647657..964b03b75a8f 100644 --- a/trunk/arch/mips/pci/msi-octeon.c +++ b/trunk/arch/mips/cavium-octeon/msi.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2005-2009 Cavium Networks + * Copyright (C) 2005-2007 Cavium Networks */ #include #include @@ -16,7 +16,8 @@ #include #include #include -#include + +#include "pci-common.h" /* * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is @@ -46,8 +47,8 @@ static DEFINE_SPINLOCK(msi_free_irq_bitmask_lock); * programming the MSI control bits [6:4] before calling * pci_enable_msi(). * - * @dev: Device requesting MSI interrupts - * @desc: MSI descriptor + * @param dev Device requesting MSI interrupts + * @param desc MSI descriptor * * Returns 0 on success. */ @@ -212,9 +213,14 @@ void arch_teardown_msi_irq(unsigned int irq) } -/* +/** * Called by the interrupt handling code when an MSI interrupt * occurs. + * + * @param cpl + * @param dev_id + * + * @return */ static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id) { @@ -250,37 +256,31 @@ static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id) } -/* +/** * Initializes the MSI interrupt handling code + * + * @return */ int octeon_msi_initialize(void) { + int r; if (octeon_has_feature(OCTEON_FEATURE_PCIE)) { - if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt, + r = request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt, IRQF_SHARED, - "MSI[0:63]", octeon_msi_interrupt)) - panic("request_irq(OCTEON_IRQ_PCI_MSI0) failed"); + "MSI[0:63]", octeon_msi_interrupt); } else if (octeon_is_pci_host()) { - if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt, + r = request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt, IRQF_SHARED, - "MSI[0:15]", octeon_msi_interrupt)) - panic("request_irq(OCTEON_IRQ_PCI_MSI0) failed"); - - if (request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt, - IRQF_SHARED, - "MSI[16:31]", octeon_msi_interrupt)) - panic("request_irq(OCTEON_IRQ_PCI_MSI1) failed"); - - if (request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt, - IRQF_SHARED, - "MSI[32:47]", octeon_msi_interrupt)) - panic("request_irq(OCTEON_IRQ_PCI_MSI2) failed"); - - if (request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt, - IRQF_SHARED, - "MSI[48:63]", octeon_msi_interrupt)) - panic("request_irq(OCTEON_IRQ_PCI_MSI3) failed"); - + "MSI[0:15]", octeon_msi_interrupt); + r += request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt, + IRQF_SHARED, + "MSI[16:31]", octeon_msi_interrupt); + r += request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt, + IRQF_SHARED, + "MSI[32:47]", octeon_msi_interrupt); + r += request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt, + IRQF_SHARED, + "MSI[48:63]", octeon_msi_interrupt); } return 0; } diff --git a/trunk/arch/mips/cavium-octeon/octeon-irq.c b/trunk/arch/mips/cavium-octeon/octeon-irq.c index 384f1842bfb1..8dfa009e0070 100644 --- a/trunk/arch/mips/cavium-octeon/octeon-irq.c +++ b/trunk/arch/mips/cavium-octeon/octeon-irq.c @@ -7,7 +7,7 @@ */ #include #include -#include +#include #include #include @@ -501,62 +501,3 @@ asmlinkage void plat_irq_dispatch(void) } } } - -#ifdef CONFIG_HOTPLUG_CPU -static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu) -{ - unsigned int isset; -#ifdef CONFIG_SMP - int coreid = cpu_logical_map(cpu); -#else - int coreid = cvmx_get_core_num(); -#endif - int bit = (irq < OCTEON_IRQ_WDOG0) ? - irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0; - if (irq < 64) { - isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) & - (1ull << bit)) >> bit; - } else { - isset = (cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)) & - (1ull << bit)) >> bit; - } - return isset; -} - -void fixup_irqs(void) -{ - int irq; - - for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) - octeon_irq_core_disable_local(irq); - - for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_GPIO15; irq++) { - if (is_irq_enabled_on_cpu(irq, smp_processor_id())) { - /* ciu irq migrates to next cpu */ - octeon_irq_chip_ciu0.disable(irq); - octeon_irq_ciu0_set_affinity(irq, &cpu_online_map); - } - } - -#if 0 - for (irq = OCTEON_IRQ_MBOX0; irq <= OCTEON_IRQ_MBOX1; irq++) - octeon_irq_mailbox_mask(irq); -#endif - for (irq = OCTEON_IRQ_UART0; irq <= OCTEON_IRQ_BOOTDMA; irq++) { - if (is_irq_enabled_on_cpu(irq, smp_processor_id())) { - /* ciu irq migrates to next cpu */ - octeon_irq_chip_ciu0.disable(irq); - octeon_irq_ciu0_set_affinity(irq, &cpu_online_map); - } - } - - for (irq = OCTEON_IRQ_UART2; irq <= OCTEON_IRQ_RESERVED135; irq++) { - if (is_irq_enabled_on_cpu(irq, smp_processor_id())) { - /* ciu irq migrates to next cpu */ - octeon_irq_chip_ciu1.disable(irq); - octeon_irq_ciu1_set_affinity(irq, &cpu_online_map); - } - } -} - -#endif /* CONFIG_HOTPLUG_CPU */ diff --git a/trunk/arch/mips/cavium-octeon/octeon_boot.h b/trunk/arch/mips/cavium-octeon/octeon_boot.h deleted file mode 100644 index 0f7f84accf9a..000000000000 --- a/trunk/arch/mips/cavium-octeon/octeon_boot.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * (C) Copyright 2004, 2005 Cavium Networks - * - * 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 - */ - -#ifndef __OCTEON_BOOT_H__ -#define __OCTEON_BOOT_H__ - -#include - -struct boot_init_vector { - uint32_t stack_addr; - uint32_t code_addr; - uint32_t app_start_func_addr; - uint32_t k0_val; - uint32_t flags; - uint32_t boot_info_addr; - uint32_t pad; - uint32_t pad2; -}; - -/* similar to bootloader's linux_app_boot_info but without global data */ -struct linux_app_boot_info { - uint32_t labi_signature; - uint32_t start_core0_addr; - uint32_t avail_coremask; - uint32_t pci_console_active; - uint32_t icache_prefetch_disable; - uint32_t InitTLBStart_addr; - uint32_t start_app_addr; - uint32_t cur_exception_base; - uint32_t no_mark_private_data; - uint32_t compact_flash_common_base_addr; - uint32_t compact_flash_attribute_base_addr; - uint32_t led_display_base_addr; -}; - -/* If not to copy a lot of bootloader's structures - here is only offset of requested member */ -#define AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK 0x765c - -/* hardcoded in bootloader */ -#define LABI_ADDR_IN_BOOTLOADER 0x700 - -#define LINUX_APP_BOOT_BLOCK_NAME "linux-app-boot" - -#define LABI_SIGNATURE 0xAABBCCDD - -/* from uboot-headers/octeon_mem_map.h */ -#define EXCEPTION_BASE_INCR (4 * 1024) - /* Increment size for exception base addresses (4k minimum) */ -#define EXCEPTION_BASE_BASE 0 -#define BOOTLOADER_PRIV_DATA_BASE (EXCEPTION_BASE_BASE + 0x800) -#define BOOTLOADER_BOOT_VECTOR (BOOTLOADER_PRIV_DATA_BASE) - -#endif /* __OCTEON_BOOT_H__ */ diff --git a/trunk/arch/mips/cavium-octeon/pci-common.c b/trunk/arch/mips/cavium-octeon/pci-common.c new file mode 100644 index 000000000000..cd029f88da7f --- /dev/null +++ b/trunk/arch/mips/cavium-octeon/pci-common.c @@ -0,0 +1,137 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2005-2007 Cavium Networks + */ +#include +#include +#include +#include +#include +#include +#include "pci-common.h" + +typeof(pcibios_map_irq) *octeon_pcibios_map_irq; +enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; + +/** + * Map a PCI device to the appropriate interrupt line + * + * @param dev The Linux PCI device structure for the device to map + * @param slot The slot number for this device on __BUS 0__. Linux + * enumerates through all the bridges and figures out the + * slot on Bus 0 where this device eventually hooks to. + * @param pin The PCI interrupt pin read from the device, then swizzled + * as it goes through each bridge. + * @return Interrupt number for the device + */ +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + if (octeon_pcibios_map_irq) + return octeon_pcibios_map_irq(dev, slot, pin); + else + panic("octeon_pcibios_map_irq doesn't point to a " + "pcibios_map_irq() function"); +} + + +/** + * Called to perform platform specific PCI setup + * + * @param dev + * @return + */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + uint16_t config; + uint32_t dconfig; + int pos; + /* + * Force the Cache line setting to 64 bytes. The standard + * Linux bus scan doesn't seem to set it. Octeon really has + * 128 byte lines, but Intel bridges get really upset if you + * try and set values above 64 bytes. Value is specified in + * 32bit words. + */ + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4); + /* Set latency timers for all devices */ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48); + + /* Enable reporting System errors and parity errors on all devices */ + /* Enable parity checking and error reporting */ + pci_read_config_word(dev, PCI_COMMAND, &config); + config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + pci_write_config_word(dev, PCI_COMMAND, config); + + if (dev->subordinate) { + /* Set latency timers on sub bridges */ + pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48); + /* More bridge error detection */ + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config); + config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR; + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config); + } + + /* Enable the PCIe normal error reporting */ + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (pos) { + /* Update Device Control */ + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config); + /* Correctable Error Reporting */ + config |= PCI_EXP_DEVCTL_CERE; + /* Non-Fatal Error Reporting */ + config |= PCI_EXP_DEVCTL_NFERE; + /* Fatal Error Reporting */ + config |= PCI_EXP_DEVCTL_FERE; + /* Unsupported Request */ + config |= PCI_EXP_DEVCTL_URRE; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config); + } + + /* Find the Advanced Error Reporting capability */ + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); + if (pos) { + /* Clear Uncorrectable Error Status */ + pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, + &dconfig); + pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, + dconfig); + /* Enable reporting of all uncorrectable errors */ + /* Uncorrectable Error Mask - turned on bits disable errors */ + pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0); + /* + * Leave severity at HW default. This only controls if + * errors are reported as uncorrectable or + * correctable, not if the error is reported. + */ + /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */ + /* Clear Correctable Error Status */ + pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig); + pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig); + /* Enable reporting of all correctable errors */ + /* Correctable Error Mask - turned on bits disable errors */ + pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0); + /* Advanced Error Capabilities */ + pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig); + /* ECRC Generation Enable */ + if (config & PCI_ERR_CAP_ECRC_GENC) + config |= PCI_ERR_CAP_ECRC_GENE; + /* ECRC Check Enable */ + if (config & PCI_ERR_CAP_ECRC_CHKC) + config |= PCI_ERR_CAP_ECRC_CHKE; + pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig); + /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */ + /* Report all errors to the root complex */ + pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, + PCI_ERR_ROOT_CMD_COR_EN | + PCI_ERR_ROOT_CMD_NONFATAL_EN | + PCI_ERR_ROOT_CMD_FATAL_EN); + /* Clear the Root status register */ + pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig); + pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig); + } + + return 0; +} diff --git a/trunk/arch/mips/include/asm/octeon/pci-octeon.h b/trunk/arch/mips/cavium-octeon/pci-common.h similarity index 52% rename from trunk/arch/mips/include/asm/octeon/pci-octeon.h rename to trunk/arch/mips/cavium-octeon/pci-common.h index 6ac5d3e3398e..74ae79991e45 100644 --- a/trunk/arch/mips/include/asm/octeon/pci-octeon.h +++ b/trunk/arch/mips/cavium-octeon/pci-common.h @@ -3,29 +3,23 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2005-2009 Cavium Networks + * Copyright (C) 2005-2007 Cavium Networks */ - -#ifndef __PCI_OCTEON_H__ -#define __PCI_OCTEON_H__ +#ifndef __OCTEON_PCI_COMMON_H__ +#define __OCTEON_PCI_COMMON_H__ #include /* Some PCI cards require delays when accessing config space. */ #define PCI_CONFIG_SPACE_DELAY 10000 -/* - * pcibios_map_irq() is defined inside pci-octeon.c. All it does is - * call the Octeon specific version pointed to by this variable. This - * function needs to change for PCI or PCIe based hosts. - */ -extern int (*octeon_pcibios_map_irq)(const struct pci_dev *dev, - u8 slot, u8 pin); +/* pcibios_map_irq() is defined inside pci-common.c. All it does is call the + Octeon specific version pointed to by this variable. This function needs to + change for PCI or PCIe based hosts */ +extern typeof(pcibios_map_irq) *octeon_pcibios_map_irq; -/* - * The following defines are used when octeon_dma_bar_type = - * OCTEON_DMA_BAR_TYPE_BIG - */ +/* The following defines are only used when octeon_dma_bar_type = + OCTEON_DMA_BAR_TYPE_BIG */ #define OCTEON_PCI_BAR1_HOLE_BITS 5 #define OCTEON_PCI_BAR1_HOLE_SIZE (1ul<<(OCTEON_PCI_BAR1_HOLE_BITS+3)) @@ -36,9 +30,9 @@ enum octeon_dma_bar_type { OCTEON_DMA_BAR_TYPE_PCIE }; -/* - * This tells the DMA mapping system in dma-octeon.c how to map PCI - * DMA addresses. +/** + * This is a variable to tell the DMA mapping system in dma-octeon.c + * how to map PCI DMA addresses. */ extern enum octeon_dma_bar_type octeon_dma_bar_type; diff --git a/trunk/arch/mips/pci/pci-octeon.c b/trunk/arch/mips/cavium-octeon/pci.c similarity index 78% rename from trunk/arch/mips/pci/pci-octeon.c rename to trunk/arch/mips/cavium-octeon/pci.c index 9cb0c807f564..67c0ff5e92f1 100644 --- a/trunk/arch/mips/pci/pci-octeon.c +++ b/trunk/arch/mips/cavium-octeon/pci.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2005-2009 Cavium Networks + * Copyright (C) 2005-2007 Cavium Networks */ #include #include @@ -17,7 +17,8 @@ #include #include #include -#include + +#include "pci-common.h" #define USE_OCTEON_INTERNAL_ARBITER @@ -53,126 +54,6 @@ union octeon_pci_address { } s; }; -int __initdata (*octeon_pcibios_map_irq)(const struct pci_dev *dev, - u8 slot, u8 pin); -enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; - -/** - * Map a PCI device to the appropriate interrupt line - * - * @dev: The Linux PCI device structure for the device to map - * @slot: The slot number for this device on __BUS 0__. Linux - * enumerates through all the bridges and figures out the - * slot on Bus 0 where this device eventually hooks to. - * @pin: The PCI interrupt pin read from the device, then swizzled - * as it goes through each bridge. - * Returns Interrupt number for the device - */ -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - if (octeon_pcibios_map_irq) - return octeon_pcibios_map_irq(dev, slot, pin); - else - panic("octeon_pcibios_map_irq not set."); -} - - -/* - * Called to perform platform specific PCI setup - */ -int pcibios_plat_dev_init(struct pci_dev *dev) -{ - uint16_t config; - uint32_t dconfig; - int pos; - /* - * Force the Cache line setting to 64 bytes. The standard - * Linux bus scan doesn't seem to set it. Octeon really has - * 128 byte lines, but Intel bridges get really upset if you - * try and set values above 64 bytes. Value is specified in - * 32bit words. - */ - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4); - /* Set latency timers for all devices */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48); - - /* Enable reporting System errors and parity errors on all devices */ - /* Enable parity checking and error reporting */ - pci_read_config_word(dev, PCI_COMMAND, &config); - config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; - pci_write_config_word(dev, PCI_COMMAND, config); - - if (dev->subordinate) { - /* Set latency timers on sub bridges */ - pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48); - /* More bridge error detection */ - pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config); - config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR; - pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config); - } - - /* Enable the PCIe normal error reporting */ - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (pos) { - /* Update Device Control */ - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config); - /* Correctable Error Reporting */ - config |= PCI_EXP_DEVCTL_CERE; - /* Non-Fatal Error Reporting */ - config |= PCI_EXP_DEVCTL_NFERE; - /* Fatal Error Reporting */ - config |= PCI_EXP_DEVCTL_FERE; - /* Unsupported Request */ - config |= PCI_EXP_DEVCTL_URRE; - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config); - } - - /* Find the Advanced Error Reporting capability */ - pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); - if (pos) { - /* Clear Uncorrectable Error Status */ - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, - &dconfig); - pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, - dconfig); - /* Enable reporting of all uncorrectable errors */ - /* Uncorrectable Error Mask - turned on bits disable errors */ - pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0); - /* - * Leave severity at HW default. This only controls if - * errors are reported as uncorrectable or - * correctable, not if the error is reported. - */ - /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */ - /* Clear Correctable Error Status */ - pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig); - pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig); - /* Enable reporting of all correctable errors */ - /* Correctable Error Mask - turned on bits disable errors */ - pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0); - /* Advanced Error Capabilities */ - pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig); - /* ECRC Generation Enable */ - if (config & PCI_ERR_CAP_ECRC_GENC) - config |= PCI_ERR_CAP_ECRC_GENE; - /* ECRC Check Enable */ - if (config & PCI_ERR_CAP_ECRC_CHKC) - config |= PCI_ERR_CAP_ECRC_CHKE; - pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig); - /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */ - /* Report all errors to the root complex */ - pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, - PCI_ERR_ROOT_CMD_COR_EN | - PCI_ERR_ROOT_CMD_NONFATAL_EN | - PCI_ERR_ROOT_CMD_FATAL_EN); - /* Clear the Root status register */ - pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig); - pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig); - } - - return 0; -} - /** * Return the mapping of PCI device number to IRQ line. Each * character in the return string represents the interrupt @@ -255,8 +136,9 @@ int __init octeon_pci_pcibios_map_irq(const struct pci_dev *dev, } -/* +/** * Read a value from configuration space + * */ static int octeon_read_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 *val) @@ -292,8 +174,15 @@ static int octeon_read_config(struct pci_bus *bus, unsigned int devfn, } -/* +/** * Write a value to PCI configuration space + * + * @bus: + * @devfn: + * @reg: + * @size: + * @val: + * Returns */ static int octeon_write_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 val) @@ -362,8 +251,10 @@ static struct pci_controller octeon_pci_controller = { }; -/* +/** * Low level initialize the Octeon PCI controller + * + * Returns */ static void octeon_pci_initialize(void) { @@ -507,7 +398,7 @@ static void octeon_pci_initialize(void) pci_int_arb_cfg.s.en = 1; /* Internal arbiter enable */ cvmx_write_csr(CVMX_NPI_PCI_INT_ARB_CFG, pci_int_arb_cfg.u64); } -#endif /* USE_OCTEON_INTERNAL_ARBITER */ +#endif /* USE_OCTEON_INTERNAL_ARBITER */ /* * Preferrably written to 1 to set MLTD. [RDSATI,TRTAE, @@ -566,8 +457,10 @@ static void octeon_pci_initialize(void) } -/* +/** * Initialize the Octeon PCI controller + * + * Returns */ static int __init octeon_pci_setup(void) { diff --git a/trunk/arch/mips/pci/pcie-octeon.c b/trunk/arch/mips/cavium-octeon/pcie.c similarity index 98% rename from trunk/arch/mips/pci/pcie-octeon.c rename to trunk/arch/mips/cavium-octeon/pcie.c index 75262247f3e4..49d14081b3b5 100644 --- a/trunk/arch/mips/pci/pcie-octeon.c +++ b/trunk/arch/mips/cavium-octeon/pcie.c @@ -18,7 +18,8 @@ #include #include #include -#include + +#include "pci-common.h" union cvmx_pcie_address { uint64_t u64; @@ -975,13 +976,13 @@ static int cvmx_pcie_rc_initialize(int pcie_port) /** * Map a PCI device to the appropriate interrupt line * - * @dev: The Linux PCI device structure for the device to map - * @slot: The slot number for this device on __BUS 0__. Linux + * @param dev The Linux PCI device structure for the device to map + * @param slot The slot number for this device on __BUS 0__. Linux * enumerates through all the bridges and figures out the * slot on Bus 0 where this device eventually hooks to. - * @pin: The PCI interrupt pin read from the device, then swizzled + * @param pin The PCI interrupt pin read from the device, then swizzled * as it goes through each bridge. - * Returns Interrupt number for the device + * @return Interrupt number for the device */ int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) @@ -1024,12 +1025,12 @@ int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, /** * Read a value from configuration space * - * @bus: - * @devfn: - * @reg: - * @size: - * @val: - * Returns + * @param bus + * @param devfn + * @param reg + * @param size + * @param val + * @return */ static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus, unsigned int devfn, int reg, int size, @@ -1155,12 +1156,12 @@ static int octeon_pcie1_read_config(struct pci_bus *bus, unsigned int devfn, /** * Write a value to PCI configuration space * - * @bus: - * @devfn: - * @reg: - * @size: - * @val: - * Returns + * @param bus + * @param devfn + * @param reg + * @param size + * @param val + * @return */ static inline int octeon_pcie_write_config(int pcie_port, struct pci_bus *bus, unsigned int devfn, int reg, @@ -1253,7 +1254,7 @@ static struct pci_controller octeon_pcie1_controller = { /** * Initialize the Octeon PCIe controllers * - * Returns + * @return */ static int __init octeon_pcie_setup(void) { diff --git a/trunk/arch/mips/cavium-octeon/setup.c b/trunk/arch/mips/cavium-octeon/setup.c index da559249cc2f..5f4e49ba4713 100644 --- a/trunk/arch/mips/cavium-octeon/setup.c +++ b/trunk/arch/mips/cavium-octeon/setup.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include /* for memset */ #include diff --git a/trunk/arch/mips/cavium-octeon/smp.c b/trunk/arch/mips/cavium-octeon/smp.c index 0b891a9c6253..24e0ad63980a 100644 --- a/trunk/arch/mips/cavium-octeon/smp.c +++ b/trunk/arch/mips/cavium-octeon/smp.c @@ -5,7 +5,6 @@ * * Copyright (C) 2004-2008 Cavium Networks */ -#include #include #include #include @@ -20,16 +19,10 @@ #include -#include "octeon_boot.h" - volatile unsigned long octeon_processor_boot = 0xff; volatile unsigned long octeon_processor_sp; volatile unsigned long octeon_processor_gp; -#ifdef CONFIG_HOTPLUG_CPU -static unsigned int InitTLBStart_addr; -#endif - static irqreturn_t mailbox_interrupt(int irq, void *dev_id) { const int coreid = cvmx_get_core_num(); @@ -74,28 +67,8 @@ static inline void octeon_send_ipi_mask(cpumask_t mask, unsigned int action) } /** - * Detect available CPUs, populate cpu_possible_map + * Detect available CPUs, populate phys_cpu_present_map */ -static void octeon_smp_hotplug_setup(void) -{ -#ifdef CONFIG_HOTPLUG_CPU - uint32_t labi_signature; - - labi_signature = - cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - LABI_ADDR_IN_BOOTLOADER + - offsetof(struct linux_app_boot_info, - labi_signature))); - if (labi_signature != LABI_SIGNATURE) - pr_err("The bootloader version on this board is incorrect\n"); - InitTLBStart_addr = - cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - LABI_ADDR_IN_BOOTLOADER + - offsetof(struct linux_app_boot_info, - InitTLBStart_addr))); -#endif -} - static void octeon_smp_setup(void) { const int coreid = cvmx_get_core_num(); @@ -118,9 +91,6 @@ static void octeon_smp_setup(void) cpus++; } } - cpu_present_map = cpu_possible_map; - - octeon_smp_hotplug_setup(); } /** @@ -158,17 +128,6 @@ static void octeon_init_secondary(void) const int coreid = cvmx_get_core_num(); union cvmx_ciu_intx_sum0 interrupt_enable; -#ifdef CONFIG_HOTPLUG_CPU - unsigned int cur_exception_base; - - cur_exception_base = cvmx_read64_uint32( - CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - LABI_ADDR_IN_BOOTLOADER + - offsetof(struct linux_app_boot_info, - cur_exception_base))); - /* cur_exception_base is incremented in bootloader after setting */ - write_c0_ebase((unsigned int)(cur_exception_base - EXCEPTION_BASE_INCR)); -#endif octeon_check_cpu_bist(); octeon_init_cvmcount(); /* @@ -240,193 +199,6 @@ static void octeon_cpus_done(void) #endif } -#ifdef CONFIG_HOTPLUG_CPU - -/* State of each CPU. */ -DEFINE_PER_CPU(int, cpu_state); - -extern void fixup_irqs(void); - -static DEFINE_SPINLOCK(smp_reserve_lock); - -static int octeon_cpu_disable(void) -{ - unsigned int cpu = smp_processor_id(); - - if (cpu == 0) - return -EBUSY; - - spin_lock(&smp_reserve_lock); - - cpu_clear(cpu, cpu_online_map); - cpu_clear(cpu, cpu_callin_map); - local_irq_disable(); - fixup_irqs(); - local_irq_enable(); - - flush_cache_all(); - local_flush_tlb_all(); - - spin_unlock(&smp_reserve_lock); - - return 0; -} - -static void octeon_cpu_die(unsigned int cpu) -{ - int coreid = cpu_logical_map(cpu); - uint32_t avail_coremask; - struct cvmx_bootmem_named_block_desc *block_desc; - -#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG - /* Disable the watchdog */ - cvmx_ciu_wdogx_t ciu_wdog; - ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu)); - ciu_wdog.s.mode = 0; - cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64); -#endif - - while (per_cpu(cpu_state, cpu) != CPU_DEAD) - cpu_relax(); - - /* - * This is a bit complicated strategics of getting/settig available - * cores mask, copied from bootloader - */ - /* LINUX_APP_BOOT_BLOCK is initialized in bootoct binary */ - block_desc = cvmx_bootmem_find_named_block(LINUX_APP_BOOT_BLOCK_NAME); - - if (!block_desc) { - avail_coremask = - cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - LABI_ADDR_IN_BOOTLOADER + - offsetof - (struct linux_app_boot_info, - avail_coremask))); - } else { /* alternative, already initialized */ - avail_coremask = - cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - block_desc->base_addr + - AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK)); - } - - avail_coremask |= 1 << coreid; - - /* Setting avail_coremask for bootoct binary */ - if (!block_desc) { - cvmx_write64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - LABI_ADDR_IN_BOOTLOADER + - offsetof(struct linux_app_boot_info, - avail_coremask)), - avail_coremask); - } else { - cvmx_write64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - block_desc->base_addr + - AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK), - avail_coremask); - } - - pr_info("Reset core %d. Available Coremask = %x \n", coreid, - avail_coremask); - cvmx_write_csr(CVMX_CIU_PP_RST, 1 << coreid); - cvmx_write_csr(CVMX_CIU_PP_RST, 0); -} - -void play_dead(void) -{ - int coreid = cvmx_get_core_num(); - - idle_task_exit(); - octeon_processor_boot = 0xff; - per_cpu(cpu_state, coreid) = CPU_DEAD; - - while (1) /* core will be reset here */ - ; -} - -extern void kernel_entry(unsigned long arg1, ...); - -static void start_after_reset(void) -{ - kernel_entry(0, 0, 0); /* set a2 = 0 for secondary core */ -} - -int octeon_update_boot_vector(unsigned int cpu) -{ - - int coreid = cpu_logical_map(cpu); - unsigned int avail_coremask; - struct cvmx_bootmem_named_block_desc *block_desc; - struct boot_init_vector *boot_vect = - (struct boot_init_vector *) cvmx_phys_to_ptr(0x0 + - BOOTLOADER_BOOT_VECTOR); - - block_desc = cvmx_bootmem_find_named_block(LINUX_APP_BOOT_BLOCK_NAME); - - if (!block_desc) { - avail_coremask = - cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - LABI_ADDR_IN_BOOTLOADER + - offsetof(struct linux_app_boot_info, - avail_coremask))); - } else { /* alternative, already initialized */ - avail_coremask = - cvmx_read64_uint32(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, - block_desc->base_addr + - AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK)); - } - - if (!(avail_coremask & (1 << coreid))) { - /* core not available, assume, that catched by simple-executive */ - cvmx_write_csr(CVMX_CIU_PP_RST, 1 << coreid); - cvmx_write_csr(CVMX_CIU_PP_RST, 0); - } - - boot_vect[coreid].app_start_func_addr = - (uint32_t) (unsigned long) start_after_reset; - boot_vect[coreid].code_addr = InitTLBStart_addr; - - CVMX_SYNC; - - cvmx_write_csr(CVMX_CIU_NMI, (1 << coreid) & avail_coremask); - - return 0; -} - -static int __cpuinit octeon_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - - switch (action) { - case CPU_UP_PREPARE: - octeon_update_boot_vector(cpu); - break; - case CPU_ONLINE: - pr_info("Cpu %d online\n", cpu); - break; - case CPU_DEAD: - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block __cpuinitdata octeon_cpu_notifier = { - .notifier_call = octeon_cpu_callback, -}; - -static int __cpuinit register_cavium_notifier(void) -{ - register_hotcpu_notifier(&octeon_cpu_notifier); - - return 0; -} - -late_initcall(register_cavium_notifier); - -#endif /* CONFIG_HOTPLUG_CPU */ - struct plat_smp_ops octeon_smp_ops = { .send_ipi_single = octeon_send_ipi_single, .send_ipi_mask = octeon_send_ipi_mask, @@ -436,8 +208,4 @@ struct plat_smp_ops octeon_smp_ops = { .boot_secondary = octeon_boot_secondary, .smp_setup = octeon_smp_setup, .prepare_cpus = octeon_prepare_cpus, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_disable = octeon_cpu_disable, - .cpu_die = octeon_cpu_die, -#endif }; diff --git a/trunk/arch/mips/cobalt/buttons.c b/trunk/arch/mips/cobalt/buttons.c index 4eaec8b46e0c..9e143989c7b8 100644 --- a/trunk/arch/mips/cobalt/buttons.c +++ b/trunk/arch/mips/cobalt/buttons.c @@ -1,7 +1,7 @@ /* * Cobalt buttons platform device. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/cobalt/lcd.c b/trunk/arch/mips/cobalt/lcd.c index 0f1cd90f37ed..0720e4fae311 100644 --- a/trunk/arch/mips/cobalt/lcd.c +++ b/trunk/arch/mips/cobalt/lcd.c @@ -1,7 +1,7 @@ /* * Registration of Cobalt LCD platform device. * - * Copyright (C) 2008 Yoichi Yuasa + * Copyright (C) 2008 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/cobalt/led.c b/trunk/arch/mips/cobalt/led.c index d3ce6fa1dc74..1c6ebd468b07 100644 --- a/trunk/arch/mips/cobalt/led.c +++ b/trunk/arch/mips/cobalt/led.c @@ -1,7 +1,7 @@ /* * Registration of Cobalt LED platform device. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/cobalt/mtd.c b/trunk/arch/mips/cobalt/mtd.c index 691d620b6766..2b088ef3839a 100644 --- a/trunk/arch/mips/cobalt/mtd.c +++ b/trunk/arch/mips/cobalt/mtd.c @@ -1,7 +1,7 @@ /* * Registration of Cobalt MTD device. * - * Copyright (C) 2006 Yoichi Yuasa + * Copyright (C) 2006 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/cobalt/rtc.c b/trunk/arch/mips/cobalt/rtc.c index 3ab39898b4e4..e70794b8bcba 100644 --- a/trunk/arch/mips/cobalt/rtc.c +++ b/trunk/arch/mips/cobalt/rtc.c @@ -1,7 +1,7 @@ /* * Registration of Cobalt RTC platform device. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/cobalt/serial.c b/trunk/arch/mips/cobalt/serial.c index 7cb51f57275e..53b8d0d6da90 100644 --- a/trunk/arch/mips/cobalt/serial.c +++ b/trunk/arch/mips/cobalt/serial.c @@ -1,7 +1,7 @@ /* * Registration of Cobalt UART platform device. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/cobalt/time.c b/trunk/arch/mips/cobalt/time.c index 0162f9edc693..4a570e7145fe 100644 --- a/trunk/arch/mips/cobalt/time.c +++ b/trunk/arch/mips/cobalt/time.c @@ -1,7 +1,7 @@ /* * Cobalt time initialization. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/configs/ar7_defconfig b/trunk/arch/mips/configs/ar7_defconfig deleted file mode 100644 index dad5b6769d74..000000000000 --- a/trunk/arch/mips/configs/ar7_defconfig +++ /dev/null @@ -1,1182 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.30 -# Wed Jun 24 14:08:59 2009 -# -CONFIG_MIPS=y - -# -# Machine selection -# -# CONFIG_MACH_ALCHEMY is not set -CONFIG_AR7=y -# CONFIG_BASLER_EXCITE is not set -# CONFIG_BCM47XX is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set -# CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_NEC_MARKEINS is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_NXP_STB220 is not set -# CONFIG_NXP_STB225 is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_PMC_MSP is not set -# CONFIG_PMC_YOSEMITE is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP28 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SNI_RM is not set -# CONFIG_MACH_TX39XX is not set -# CONFIG_MACH_TX49XX is not set -# CONFIG_MIKROTIK_RB532 is not set -# CONFIG_WR_PPMC is not set -# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set -# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set -# CONFIG_ALCHEMY_GPIO_INDIRECT is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_SUPPORTS_OPROFILE=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y -CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_CEVT_R4K_LIB=y -CONFIG_CEVT_R4K=y -CONFIG_CSRC_R4K_LIB=y -CONFIG_CSRC_R4K=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_EARLY_PRINTK=y -CONFIG_SYS_HAS_EARLY_PRINTK=y -# CONFIG_HOTPLUG_CPU is not set -# CONFIG_NO_IOPORT is not set -CONFIG_GENERIC_GPIO=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_NO_EXCEPT_FILL=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_BOOT_ELF32=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 - -# -# CPU selection -# -# CONFIG_CPU_LOONGSON2 is not set -CONFIG_CPU_MIPS32_R1=y -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R5500 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -# CONFIG_CPU_CAVIUM_OCTEON is not set -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_CPU_MIPS32=y -CONFIG_CPU_MIPSR1=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_HARDWARE_WATCHPOINTS=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_32KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -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_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# 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_TICK_ONESHOT=y -# CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_48 is not set -CONFIG_HZ_100=y -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=100 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_KEXEC=y -# CONFIG_SECCOMP is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU 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_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -CONFIG_RELAY=y -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -CONFIG_RD_LZMA=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -# CONFIG_KALLSYMS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -# CONFIG_ELF_CORE is not set -# CONFIG_PCSPKR_PLATFORM is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=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 is not set -CONFIG_STRIP_ASM_SYMS=y -# CONFIG_COMPAT_BRK is not set -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_SLOW_WORK is not set -# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -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_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_INTEGRITY is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" -CONFIG_PROBE_INITRD_HEADER=y -# CONFIG_FREEZER is not set - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -# CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_MMU=y -# CONFIG_PCCARD is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_HAVE_AOUT is not set -# CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -# CONFIG_PM is not set -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -CONFIG_IP_MROUTE=y -# CONFIG_IP_PIMSM_V1 is not set -# CONFIG_IP_PIMSM_V2 is not set -CONFIG_ARPD=y -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -CONFIG_TCP_CONG_ADVANCED=y -# CONFIG_TCP_CONG_BIC is not set -# CONFIG_TCP_CONG_CUBIC is not set -CONFIG_TCP_CONG_WESTWOOD=y -# CONFIG_TCP_CONG_HTCP is not set -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_SCALABLE is not set -# CONFIG_TCP_CONG_LP is not set -# CONFIG_TCP_CONG_VENO is not set -# CONFIG_TCP_CONG_YEAH is not set -# CONFIG_TCP_CONG_ILLINOIS is not set -# CONFIG_DEFAULT_BIC is not set -# CONFIG_DEFAULT_CUBIC is not set -# CONFIG_DEFAULT_HTCP is not set -# CONFIG_DEFAULT_VEGAS is not set -CONFIG_DEFAULT_WESTWOOD=y -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="westwood" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y -# CONFIG_BRIDGE_NETFILTER is not set - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set -CONFIG_NF_CONNTRACK=m -# CONFIG_NF_CT_ACCT is not set -CONFIG_NF_CONNTRACK_MARK=y -# CONFIG_NF_CONNTRACK_EVENTS is not set -# CONFIG_NF_CT_PROTO_DCCP is not set -# CONFIG_NF_CT_PROTO_SCTP is not set -# CONFIG_NF_CT_PROTO_UDPLITE is not set -# CONFIG_NF_CONNTRACK_AMANDA is not set -CONFIG_NF_CONNTRACK_FTP=m -# CONFIG_NF_CONNTRACK_H323 is not set -CONFIG_NF_CONNTRACK_IRC=m -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -# CONFIG_NF_CONNTRACK_PPTP is not set -# CONFIG_NF_CONNTRACK_SANE is not set -# CONFIG_NF_CONNTRACK_SIP is not set -CONFIG_NF_CONNTRACK_TFTP=m -# CONFIG_NF_CT_NETLINK is not set -# CONFIG_NETFILTER_TPROXY is not set -CONFIG_NETFILTER_XTABLES=m -# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_HL is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set -# CONFIG_NETFILTER_XT_TARGET_MARK is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set -# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_HELPER is not set -# CONFIG_NETFILTER_XT_MATCH_HL is not set -# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set -# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_NETFILTER_XT_MATCH_STATE=m -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_TIME is not set -# CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_IP_VS is not set - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=m -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=m -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_MATCH_AH is not set -# CONFIG_IP_NF_MATCH_ECN is not set -# CONFIG_IP_NF_MATCH_TTL is not set -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -# CONFIG_IP_NF_TARGET_ULOG is not set -CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -# CONFIG_IP_NF_TARGET_NETMAP is not set -# CONFIG_IP_NF_TARGET_REDIRECT is not set -# CONFIG_NF_NAT_SNMP_BASIC is not set -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT_TFTP=m -# CONFIG_NF_NAT_AMANDA is not set -# CONFIG_NF_NAT_PPTP is not set -# CONFIG_NF_NAT_H323 is not set -# CONFIG_NF_NAT_SIP is not set -CONFIG_IP_NF_MANGLE=m -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_RAW=m -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -CONFIG_ATM=m -# CONFIG_ATM_CLIP is not set -# CONFIG_ATM_LANE is not set -CONFIG_ATM_BR2684=m -CONFIG_ATM_BR2684_IPFILTER=y -CONFIG_STP=y -CONFIG_BRIDGE=y -# CONFIG_NET_DSA is not set -CONFIG_VLAN_8021Q=y -# CONFIG_VLAN_8021Q_GVRP is not set -# CONFIG_DECNET is not set -CONFIG_LLC=y -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# 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=y - -# -# Queueing/Scheduling -# -# CONFIG_NET_SCH_CBQ is not set -# CONFIG_NET_SCH_HTB is not set -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_ATM is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_MULTIQ is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_DSMARK is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_DRR is not set -# CONFIG_NET_SCH_INGRESS is not set - -# -# Classification -# -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_TCINDEX is not set -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_FW is not set -# CONFIG_NET_CLS_U32 is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_EMATCH is not set -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=y -# CONFIG_NET_ACT_GACT is not set -# CONFIG_NET_ACT_MIRRED is not set -# CONFIG_NET_ACT_IPT is not set -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set -# CONFIG_NET_ACT_SIMP is not set -# CONFIG_NET_ACT_SKBEDIT is not set -CONFIG_NET_SCH_FIFO=y -# CONFIG_DCB is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -CONFIG_HAMRADIO=y - -# -# Packet Radio protocols -# -# CONFIG_AX25 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_FIB_RULES=y -CONFIG_WIRELESS=y -CONFIG_CFG80211=m -# CONFIG_CFG80211_REG_DEBUG is not set -# CONFIG_CFG80211_DEBUGFS is not set -# CONFIG_WIRELESS_OLD_REGULATORY is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WIRELESS_EXT_SYSFS=y -# CONFIG_LIB80211 is not set -CONFIG_MAC80211=m -CONFIG_MAC80211_DEFAULT_PS=y -CONFIG_MAC80211_DEFAULT_PS_VALUE=1 - -# -# Rate control algorithm selection -# -CONFIG_MAC80211_RC_PID=y -CONFIG_MAC80211_RC_MINSTREL=y -CONFIG_MAC80211_RC_DEFAULT_PID=y -# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set -CONFIG_MAC80211_RC_DEFAULT="pid" -# CONFIG_MAC80211_MESH is not set -# CONFIG_MAC80211_LEDS is not set -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_WIMAX is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_FIRMWARE_IN_KERNEL is not set -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -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 is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -CONFIG_MTD_COMPLEX_MAPPINGS=y -CONFIG_MTD_PHYSMAP=y -# CONFIG_MTD_PHYSMAP_COMPAT is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# 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 -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_MISC_DEVICES=y -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_93CX6 is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -# CONFIG_IFB 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_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_LSI_ET1011C_PHY is not set -CONFIG_FIXED_PHY=y -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_AX88796 is not set -# CONFIG_SMC91X is not set -# CONFIG_DM9000 is not set -# CONFIG_ETHOC is not set -# CONFIG_DNET is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -# CONFIG_B44 is not set -# CONFIG_KS8842 is not set -CONFIG_CPMAC=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -CONFIG_WLAN_80211=y -# CONFIG_LIBERTAS is not set -# CONFIG_LIBERTAS_THINFIRM is not set -# CONFIG_MAC80211_HWSIM is not set -# CONFIG_P54_COMMON is not set -# CONFIG_HOSTAP is not set -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set -# CONFIG_RT2X00 is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# -# CONFIG_WAN is not set -CONFIG_ATM_DRIVERS=y -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_TCP is not set -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_MPPE is not set -CONFIG_PPPOE=m -CONFIG_PPPOATM=m -# CONFIG_PPPOL2TP is not set -# CONFIG_SLIP is not set -CONFIG_SLHC=m -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_DEVKMEM is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set -# CONFIG_SPI is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_AR7_WDT=y -CONFIG_SSB_POSSIBLE=y - -# -# Sonics Silicon Backplane -# -CONFIG_SSB=y -# CONFIG_SSB_SILENT is not set -# CONFIG_SSB_DEBUG is not set -CONFIG_SSB_SERIAL=y -CONFIG_SSB_DRIVER_MIPS=y -CONFIG_SSB_EMBEDDED=y -CONFIG_SSB_DRIVER_EXTIF=y - -# -# Multifunction device drivers -# -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_REGULATOR is not set -# CONFIG_MEDIA_SUPPORT is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -# CONFIG_LEDS_GPIO is not set - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - -# -# iptables trigger is under Netfilter config (LED target) -# -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set - -# -# TI VLYNQ -# -CONFIG_VLYNQ=y -# CONFIG_STAGING is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -# CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY is not set -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# 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 -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -# CONFIG_PROC_PAGE_MONITOR is not set -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 -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -CONFIG_JFFS2_SUMMARY=y -# CONFIG_JFFS2_FS_XATTR is not set -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_JFFS2_CMODE_NONE is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE is not set -# CONFIG_JFFS2_CMODE_FAVOURLZO is not set -# CONFIG_CRAMFS is not set -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# 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 is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set -# CONFIG_NLS is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_FRAME_WARN=1024 -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_TRACING_SUPPORT=y -# CONFIG_FTRACE is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_CMDLINE="rootfstype=squashfs,jffs2" - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_ALGAPI2=m -CONFIG_CRYPTO_AEAD2=m -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_BLKCIPHER2=m -CONFIG_CRYPTO_HASH2=m -CONFIG_CRYPTO_RNG2=m -CONFIG_CRYPTO_PCOMP=m -CONFIG_CRYPTO_MANAGER=m -CONFIG_CRYPTO_MANAGER2=m -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -CONFIG_CRYPTO_WORKQUEUE=m -# 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=m -# 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=m -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=m -# 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 is not set -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set -# CONFIG_CRC_T10DIF is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_NLATTR=y diff --git a/trunk/arch/mips/gt64120/wrppmc/serial.c b/trunk/arch/mips/gt64120/wrppmc/serial.c index 6f9d0858f596..5ec1c2ffd3a5 100644 --- a/trunk/arch/mips/gt64120/wrppmc/serial.c +++ b/trunk/arch/mips/gt64120/wrppmc/serial.c @@ -1,7 +1,7 @@ /* * Registration of WRPPMC UART platform device. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/amon.h b/trunk/arch/mips/include/asm/amon.h deleted file mode 100644 index c3dc1a68dd8d..000000000000 --- a/trunk/arch/mips/include/asm/amon.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Amon support - */ - -int amon_cpu_avail(int); -void amon_cpu_start(int, unsigned long, unsigned long, - unsigned long, unsigned long); diff --git a/trunk/arch/mips/include/asm/bug.h b/trunk/arch/mips/include/asm/bug.h index 6cf29c26e873..08ea46863fe5 100644 --- a/trunk/arch/mips/include/asm/bug.h +++ b/trunk/arch/mips/include/asm/bug.h @@ -1,7 +1,6 @@ #ifndef __ASM_BUG_H #define __ASM_BUG_H -#include #include #ifdef CONFIG_BUG diff --git a/trunk/arch/mips/include/asm/bugs.h b/trunk/arch/mips/include/asm/bugs.h index b160a706795d..9dc10df32078 100644 --- a/trunk/arch/mips/include/asm/bugs.h +++ b/trunk/arch/mips/include/asm/bugs.h @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/mips/include/asm/ds1287.h b/trunk/arch/mips/include/asm/ds1287.h index 3af0b8fb3b8c..ba1702e86931 100644 --- a/trunk/arch/mips/include/asm/ds1287.h +++ b/trunk/arch/mips/include/asm/ds1287.h @@ -1,7 +1,7 @@ /* * DS1287 timer functions. * - * Copyright (C) 2008 Yoichi Yuasa + * Copyright (C) 2008 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/elf.h b/trunk/arch/mips/include/asm/elf.h index 7990694cda22..d58f128aa747 100644 --- a/trunk/arch/mips/include/asm/elf.h +++ b/trunk/arch/mips/include/asm/elf.h @@ -316,13 +316,9 @@ extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs); extern int dump_task_regs(struct task_struct *, elf_gregset_t *); extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); -#ifndef ELF_CORE_COPY_REGS #define ELF_CORE_COPY_REGS(elf_regs, regs) \ elf_dump_regs((elf_greg_t *)&(elf_regs), regs); -#endif -#ifndef ELF_CORE_COPY_TASK_REGS #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) -#endif #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \ dump_task_fpu(tsk, elf_fpregs) diff --git a/trunk/arch/mips/include/asm/gcmpregs.h b/trunk/arch/mips/include/asm/gcmpregs.h index 36fd969d64d6..d74a8a4ca861 100644 --- a/trunk/arch/mips/include/asm/gcmpregs.h +++ b/trunk/arch/mips/include/asm/gcmpregs.h @@ -114,6 +114,4 @@ #define GCMP_CCB_DINTGROUP_OFS 0x0030 /* DINT Group Participate */ #define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */ -extern int __init gcmp_probe(unsigned long, unsigned long); - #endif /* _ASM_GCMPREGS_H */ diff --git a/trunk/arch/mips/include/asm/gic.h b/trunk/arch/mips/include/asm/gic.h index 10292e37c1f7..954807d9d66a 100644 --- a/trunk/arch/mips/include/asm/gic.h +++ b/trunk/arch/mips/include/asm/gic.h @@ -20,11 +20,7 @@ #define GIC_TRIG_EDGE 1 #define GIC_TRIG_LEVEL 0 -#if CONFIG_SMP -#define GIC_NUM_INTRS (24 + NR_CPUS * 2) -#else #define GIC_NUM_INTRS 32 -#endif #define MSK(n) ((1 << (n)) - 1) #define REG32(addr) (*(volatile unsigned int *) (addr)) @@ -487,7 +483,5 @@ extern void gic_init(unsigned long gic_base_addr, extern unsigned int gic_get_int(void); extern void gic_send_ipi(unsigned int intr); -extern unsigned int plat_ipi_call_int_xlate(unsigned int); -extern unsigned int plat_ipi_resched_int_xlate(unsigned int); #endif /* _ASM_GICREGS_H */ diff --git a/trunk/arch/mips/include/asm/irq.h b/trunk/arch/mips/include/asm/irq.h index 09b08d05ff72..4f1eed107b08 100644 --- a/trunk/arch/mips/include/asm/irq.h +++ b/trunk/arch/mips/include/asm/irq.h @@ -10,7 +10,6 @@ #define _ASM_IRQ_H #include -#include #include diff --git a/trunk/arch/mips/include/asm/irq_gt641xx.h b/trunk/arch/mips/include/asm/irq_gt641xx.h index 250a2407b599..f9a7c3ac2e66 100644 --- a/trunk/arch/mips/include/asm/irq_gt641xx.h +++ b/trunk/arch/mips/include/asm/irq_gt641xx.h @@ -1,7 +1,7 @@ /* * Galileo/Marvell GT641xx IRQ definitions. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/mach-ar7/ar7.h b/trunk/arch/mips/include/asm/mach-ar7/ar7.h deleted file mode 100644 index de71694614de..000000000000 --- a/trunk/arch/mips/include/asm/mach-ar7/ar7.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2006,2007 Felix Fietkau - * Copyright (C) 2006,2007 Eugene Konev - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __AR7_H__ -#define __AR7_H__ - -#include -#include -#include - -#include - -#define AR7_SDRAM_BASE 0x14000000 - -#define AR7_REGS_BASE 0x08610000 - -#define AR7_REGS_MAC0 (AR7_REGS_BASE + 0x0000) -#define AR7_REGS_GPIO (AR7_REGS_BASE + 0x0900) -/* 0x08610A00 - 0x08610BFF (512 bytes, 128 bytes / clock) */ -#define AR7_REGS_POWER (AR7_REGS_BASE + 0x0a00) -#define AR7_REGS_CLOCKS (AR7_REGS_POWER + 0x80) -#define UR8_REGS_CLOCKS (AR7_REGS_POWER + 0x20) -#define AR7_REGS_UART0 (AR7_REGS_BASE + 0x0e00) -#define AR7_REGS_USB (AR7_REGS_BASE + 0x1200) -#define AR7_REGS_RESET (AR7_REGS_BASE + 0x1600) -#define AR7_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1800) -#define AR7_REGS_DCL (AR7_REGS_BASE + 0x1a00) -#define AR7_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1c00) -#define AR7_REGS_MDIO (AR7_REGS_BASE + 0x1e00) -#define AR7_REGS_IRQ (AR7_REGS_BASE + 0x2400) -#define AR7_REGS_MAC1 (AR7_REGS_BASE + 0x2800) - -#define AR7_REGS_WDT (AR7_REGS_BASE + 0x1f00) -#define UR8_REGS_WDT (AR7_REGS_BASE + 0x0b00) -#define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00) - -#define AR7_RESET_PEREPHERIAL 0x0 -#define AR7_RESET_SOFTWARE 0x4 -#define AR7_RESET_STATUS 0x8 - -#define AR7_RESET_BIT_CPMAC_LO 17 -#define AR7_RESET_BIT_CPMAC_HI 21 -#define AR7_RESET_BIT_MDIO 22 -#define AR7_RESET_BIT_EPHY 26 - -/* GPIO control registers */ -#define AR7_GPIO_INPUT 0x0 -#define AR7_GPIO_OUTPUT 0x4 -#define AR7_GPIO_DIR 0x8 -#define AR7_GPIO_ENABLE 0xc - -#define AR7_CHIP_7100 0x18 -#define AR7_CHIP_7200 0x2b -#define AR7_CHIP_7300 0x05 - -/* Interrupts */ -#define AR7_IRQ_UART0 15 -#define AR7_IRQ_UART1 16 - -/* Clocks */ -#define AR7_AFE_CLOCK 35328000 -#define AR7_REF_CLOCK 25000000 -#define AR7_XTAL_CLOCK 24000000 - -struct plat_cpmac_data { - int reset_bit; - int power_bit; - u32 phy_mask; - char dev_addr[6]; -}; - -struct plat_dsl_data { - int reset_bit_dsl; - int reset_bit_sar; -}; - -extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock; - -static inline u16 ar7_chip_id(void) -{ - return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff; -} - -static inline u8 ar7_chip_rev(void) -{ - return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff; -} - -static inline int ar7_cpu_freq(void) -{ - return ar7_cpu_clock; -} - -static inline int ar7_bus_freq(void) -{ - return ar7_bus_clock; -} - -static inline int ar7_vbus_freq(void) -{ - return ar7_bus_clock / 2; -} -#define ar7_cpmac_freq ar7_vbus_freq - -static inline int ar7_dsp_freq(void) -{ - return ar7_dsp_clock; -} - -static inline int ar7_has_high_cpmac(void) -{ - u16 chip_id = ar7_chip_id(); - switch (chip_id) { - case AR7_CHIP_7100: - case AR7_CHIP_7200: - return 0; - case AR7_CHIP_7300: - return 1; - default: - return -ENXIO; - } -} -#define ar7_has_high_vlynq ar7_has_high_cpmac -#define ar7_has_second_uart ar7_has_high_cpmac - -static inline void ar7_device_enable(u32 bit) -{ - void *reset_reg = - (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL); - writel(readl(reset_reg) | (1 << bit), reset_reg); - msleep(20); -} - -static inline void ar7_device_disable(u32 bit) -{ - void *reset_reg = - (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL); - writel(readl(reset_reg) & ~(1 << bit), reset_reg); - msleep(20); -} - -static inline void ar7_device_reset(u32 bit) -{ - ar7_device_disable(bit); - ar7_device_enable(bit); -} - -static inline void ar7_device_on(u32 bit) -{ - void *power_reg = (void *)KSEG1ADDR(AR7_REGS_POWER); - writel(readl(power_reg) | (1 << bit), power_reg); - msleep(20); -} - -static inline void ar7_device_off(u32 bit) -{ - void *power_reg = (void *)KSEG1ADDR(AR7_REGS_POWER); - writel(readl(power_reg) & ~(1 << bit), power_reg); - msleep(20); -} - -#endif /* __AR7_H__ */ diff --git a/trunk/arch/mips/include/asm/mach-ar7/gpio.h b/trunk/arch/mips/include/asm/mach-ar7/gpio.h deleted file mode 100644 index cbe9c4f126df..000000000000 --- a/trunk/arch/mips/include/asm/mach-ar7/gpio.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2007 Florian Fainelli - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __AR7_GPIO_H__ -#define __AR7_GPIO_H__ - -#include - -#define AR7_GPIO_MAX 32 - -extern int gpio_request(unsigned gpio, const char *label); -extern void gpio_free(unsigned gpio); - -/* Common GPIO layer */ -static inline int gpio_get_value(unsigned gpio) -{ - void __iomem *gpio_in = - (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_INPUT); - - return readl(gpio_in) & (1 << gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ - void __iomem *gpio_out = - (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_OUTPUT); - unsigned tmp; - - tmp = readl(gpio_out) & ~(1 << gpio); - if (value) - tmp |= 1 << gpio; - writel(tmp, gpio_out); -} - -static inline int gpio_direction_input(unsigned gpio) -{ - void __iomem *gpio_dir = - (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_DIR); - - if (gpio >= AR7_GPIO_MAX) - return -EINVAL; - - writel(readl(gpio_dir) | (1 << gpio), gpio_dir); - - return 0; -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ - void __iomem *gpio_dir = - (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_DIR); - - if (gpio >= AR7_GPIO_MAX) - return -EINVAL; - - gpio_set_value(gpio, value); - writel(readl(gpio_dir) & ~(1 << gpio), gpio_dir); - - return 0; -} - -static inline int gpio_to_irq(unsigned gpio) -{ - return -EINVAL; -} - -static inline int irq_to_gpio(unsigned irq) -{ - return -EINVAL; -} - -/* Board specific GPIO functions */ -static inline int ar7_gpio_enable(unsigned gpio) -{ - void __iomem *gpio_en = - (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_ENABLE); - - writel(readl(gpio_en) | (1 << gpio), gpio_en); - - return 0; -} - -static inline int ar7_gpio_disable(unsigned gpio) -{ - void __iomem *gpio_en = - (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_ENABLE); - - writel(readl(gpio_en) & ~(1 << gpio), gpio_en); - - return 0; -} - -#include - -#endif diff --git a/trunk/arch/mips/include/asm/mach-ar7/irq.h b/trunk/arch/mips/include/asm/mach-ar7/irq.h deleted file mode 100644 index 39e9757e3d93..000000000000 --- a/trunk/arch/mips/include/asm/mach-ar7/irq.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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. - * - * Shamelessly copied from asm-mips/mach-emma2rh/ - * Copyright (C) 2003 by Ralf Baechle - */ -#ifndef __ASM_AR7_IRQ_H -#define __ASM_AR7_IRQ_H - -#define NR_IRQS 256 - -#include_next - -#endif /* __ASM_AR7_IRQ_H */ diff --git a/trunk/arch/mips/include/asm/mach-ar7/prom.h b/trunk/arch/mips/include/asm/mach-ar7/prom.h deleted file mode 100644 index 088f61fe85ea..000000000000 --- a/trunk/arch/mips/include/asm/mach-ar7/prom.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Florian Fainelli - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __PROM_H__ -#define __PROM_H__ - -extern char *prom_getenv(const char *name); -extern void prom_meminit(void); - -#endif /* __PROM_H__ */ diff --git a/trunk/arch/mips/include/asm/mach-ar7/spaces.h b/trunk/arch/mips/include/asm/mach-ar7/spaces.h deleted file mode 100644 index ac28f273449c..000000000000 --- a/trunk/arch/mips/include/asm/mach-ar7/spaces.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle - * Copyright (C) 2000, 2002 Maciej W. Rozycki - * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc. - */ -#ifndef _ASM_AR7_SPACES_H -#define _ASM_AR7_SPACES_H - -/* - * This handles the memory map. - * We handle pages at KSEG0 for kernels with 32 bit address space. - */ -#define PAGE_OFFSET 0x94000000UL -#define PHYS_OFFSET 0x14000000UL - -#include - -#endif /* __ASM_AR7_SPACES_H */ diff --git a/trunk/arch/mips/include/asm/mach-ar7/war.h b/trunk/arch/mips/include/asm/mach-ar7/war.h deleted file mode 100644 index f4862b563080..000000000000 --- a/trunk/arch/mips/include/asm/mach-ar7/war.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle - */ -#ifndef __ASM_MIPS_MACH_AR7_WAR_H -#define __ASM_MIPS_MACH_AR7_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 0 -#define MIPS_CACHE_SYNC_WAR 0 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define RM9000_CDEX_SMP_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 0 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_AR7_WAR_H */ diff --git a/trunk/arch/mips/include/asm/mach-cobalt/irq.h b/trunk/arch/mips/include/asm/mach-cobalt/irq.h index 9da9acf5dcba..57c8c9ac5851 100644 --- a/trunk/arch/mips/include/asm/mach-cobalt/irq.h +++ b/trunk/arch/mips/include/asm/mach-cobalt/irq.h @@ -8,7 +8,7 @@ * Copyright (C) 1997 Cobalt Microserver * Copyright (C) 1997, 2003 Ralf Baechle * Copyright (C) 2001-2003 Liam Davies (ldavies@agile.tv) - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa */ #ifndef _ASM_COBALT_IRQ_H #define _ASM_COBALT_IRQ_H diff --git a/trunk/arch/mips/include/asm/mach-cobalt/mach-gt64120.h b/trunk/arch/mips/include/asm/mach-cobalt/mach-gt64120.h index f8afec3f2943..ae9c5523c7ef 100644 --- a/trunk/arch/mips/include/asm/mach-cobalt/mach-gt64120.h +++ b/trunk/arch/mips/include/asm/mach-cobalt/mach-gt64120.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Yoichi Yuasa + * Copyright (C) 2006 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/mmu_context.h b/trunk/arch/mips/include/asm/mmu_context.h index d3bea88d8744..d7f3eb03ad12 100644 --- a/trunk/arch/mips/include/asm/mmu_context.h +++ b/trunk/arch/mips/include/asm/mmu_context.h @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mips/include/asm/page.h b/trunk/arch/mips/include/asm/page.h index 96a14a426a7c..dc0eaa731281 100644 --- a/trunk/arch/mips/include/asm/page.h +++ b/trunk/arch/mips/include/asm/page.h @@ -165,14 +165,7 @@ typedef struct { unsigned long pgprot; } pgprot_t; #ifdef CONFIG_FLATMEM -#define pfn_valid(pfn) \ -({ \ - unsigned long __pfn = (pfn); \ - /* avoid include hell */ \ - extern unsigned long min_low_pfn; \ - \ - __pfn >= min_low_pfn && __pfn < max_mapnr; \ -}) +#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr) #elif defined(CONFIG_SPARSEMEM) diff --git a/trunk/arch/mips/include/asm/reg.h b/trunk/arch/mips/include/asm/reg.h index 910e71a12466..634b55d7e7f6 100644 --- a/trunk/arch/mips/include/asm/reg.h +++ b/trunk/arch/mips/include/asm/reg.h @@ -69,7 +69,7 @@ #endif -#if defined(CONFIG_64BIT) && !defined(WANT_COMPAT_REG_H) +#ifdef CONFIG_64BIT #define EF_R0 0 #define EF_R1 1 diff --git a/trunk/arch/mips/include/asm/smp-ops.h b/trunk/arch/mips/include/asm/smp-ops.h index fd545547b8aa..64ffc0290b84 100644 --- a/trunk/arch/mips/include/asm/smp-ops.h +++ b/trunk/arch/mips/include/asm/smp-ops.h @@ -26,10 +26,6 @@ struct plat_smp_ops { void (*boot_secondary)(int cpu, struct task_struct *idle); void (*smp_setup)(void); void (*prepare_cpus)(unsigned int max_cpus); -#ifdef CONFIG_HOTPLUG_CPU - int (*cpu_disable)(void); - void (*cpu_die)(unsigned int cpu); -#endif }; extern void register_smp_ops(struct plat_smp_ops *ops); diff --git a/trunk/arch/mips/include/asm/smp.h b/trunk/arch/mips/include/asm/smp.h index aaa2d4ab26dc..40e5ef1d4d26 100644 --- a/trunk/arch/mips/include/asm/smp.h +++ b/trunk/arch/mips/include/asm/smp.h @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -41,7 +40,6 @@ extern int __cpu_logical_map[NR_CPUS]; /* Octeon - Tell another core to flush its icache */ #define SMP_ICACHE_FLUSH 0x4 -extern volatile cpumask_t cpu_callin_map; extern void asmlinkage smp_bootstrap(void); @@ -57,24 +55,6 @@ static inline void smp_send_reschedule(int cpu) mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF); } -#ifdef CONFIG_HOTPLUG_CPU -static inline int __cpu_disable(void) -{ - extern struct plat_smp_ops *mp_ops; /* private */ - - return mp_ops->cpu_disable(); -} - -static inline void __cpu_die(unsigned int cpu) -{ - extern struct plat_smp_ops *mp_ops; /* private */ - - mp_ops->cpu_die(cpu); -} - -extern void play_dead(void); -#endif - extern asmlinkage void smp_call_function_interrupt(void); extern void arch_send_call_function_single_ipi(int cpu); diff --git a/trunk/arch/mips/include/asm/sn/addrs.h b/trunk/arch/mips/include/asm/sn/addrs.h index 2367b56dcdef..3a56d90abfa6 100644 --- a/trunk/arch/mips/include/asm/sn/addrs.h +++ b/trunk/arch/mips/include/asm/sn/addrs.h @@ -11,7 +11,6 @@ #ifndef __ASSEMBLY__ -#include #include #endif /* !__ASSEMBLY__ */ diff --git a/trunk/arch/mips/include/asm/swab.h b/trunk/arch/mips/include/asm/swab.h index 97c2f81b4b43..99993c0d6c12 100644 --- a/trunk/arch/mips/include/asm/swab.h +++ b/trunk/arch/mips/include/asm/swab.h @@ -38,11 +38,7 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x) } #define __arch_swab32 __arch_swab32 -/* - * Having already checked for CONFIG_CPU_MIPSR2, enable the - * optimized version for 64-bit kernel on r2 CPUs. - */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_CPU_MIPS64_R2 static inline __attribute_const__ __u64 __arch_swab64(__u64 x) { __asm__( @@ -54,6 +50,6 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 x) return x; } #define __arch_swab64 __arch_swab64 -#endif /* CONFIG_64BIT */ +#endif /* CONFIG_CPU_MIPS64_R2 */ #endif /* CONFIG_CPU_MIPSR2 */ #endif /* _ASM_SWAB_H */ diff --git a/trunk/arch/mips/include/asm/unistd.h b/trunk/arch/mips/include/asm/unistd.h index b70c49fdda26..40005010827c 100644 --- a/trunk/arch/mips/include/asm/unistd.h +++ b/trunk/arch/mips/include/asm/unistd.h @@ -352,18 +352,16 @@ #define __NR_inotify_init1 (__NR_Linux + 329) #define __NR_preadv (__NR_Linux + 330) #define __NR_pwritev (__NR_Linux + 331) -#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332) -#define __NR_perf_counter_open (__NR_Linux + 333) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 333 +#define __NR_Linux_syscalls 331 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 333 +#define __NR_O32_Linux_syscalls 331 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -662,18 +660,16 @@ #define __NR_inotify_init1 (__NR_Linux + 288) #define __NR_preadv (__NR_Linux + 289) #define __NR_pwritev (__NR_Linux + 290) -#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291) -#define __NR_perf_counter_open (__NR_Linux + 292) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 292 +#define __NR_Linux_syscalls 290 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 292 +#define __NR_64_Linux_syscalls 290 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -976,18 +972,16 @@ #define __NR_inotify_init1 (__NR_Linux + 292) #define __NR_preadv (__NR_Linux + 293) #define __NR_pwritev (__NR_Linux + 294) -#define __NR_rt_tgsigqueueinfo (__NR_Linux + 295) -#define __NR_perf_counter_open (__NR_Linux + 296) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 296 +#define __NR_Linux_syscalls 294 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 296 +#define __NR_N32_Linux_syscalls 294 #ifdef __KERNEL__ diff --git a/trunk/arch/mips/include/asm/vr41xx/capcella.h b/trunk/arch/mips/include/asm/vr41xx/capcella.h index fcc6569414fa..e0ee05a3dfcc 100644 --- a/trunk/arch/mips/include/asm/vr41xx/capcella.h +++ b/trunk/arch/mips/include/asm/vr41xx/capcella.h @@ -1,7 +1,7 @@ /* * capcella.h, Include file for ZAO Networks Capcella. * - * Copyright (C) 2002-2004 Yoichi Yuasa + * Copyright (C) 2002-2004 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/vr41xx/giu.h b/trunk/arch/mips/include/asm/vr41xx/giu.h index 6a90bc1d916b..0bcdd3a5c256 100644 --- a/trunk/arch/mips/include/asm/vr41xx/giu.h +++ b/trunk/arch/mips/include/asm/vr41xx/giu.h @@ -1,7 +1,7 @@ /* * Include file for NEC VR4100 series General-purpose I/O Unit. * - * Copyright (C) 2005-2009 Yoichi Yuasa + * Copyright (C) 2005 Yoichi Yuasa * * 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 @@ -41,8 +41,7 @@ typedef enum { IRQ_SIGNAL_HOLD, } irq_signal_t; -extern void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, - irq_signal_t signal); +extern void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal); typedef enum { IRQ_LEVEL_LOW, @@ -51,6 +50,23 @@ typedef enum { extern void vr41xx_set_irq_level(unsigned int pin, irq_level_t level); +typedef enum { + GPIO_DATA_LOW, + GPIO_DATA_HIGH, + GPIO_DATA_INVAL, +} gpio_data_t; + +extern gpio_data_t vr41xx_gpio_get_pin(unsigned int pin); +extern int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data); + +typedef enum { + GPIO_INPUT, + GPIO_OUTPUT, + GPIO_OUTPUT_DISABLE, +} gpio_direction_t; + +extern int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir); + typedef enum { GPIO_PULL_DOWN, GPIO_PULL_UP, diff --git a/trunk/arch/mips/include/asm/vr41xx/irq.h b/trunk/arch/mips/include/asm/vr41xx/irq.h index b07f7321751d..d315dfbc08f2 100644 --- a/trunk/arch/mips/include/asm/vr41xx/irq.h +++ b/trunk/arch/mips/include/asm/vr41xx/irq.h @@ -7,7 +7,7 @@ * Copyright (C) 2001, 2002 Paul Mundt * Copyright (C) 2002 MontaVista Software, Inc. * Copyright (C) 2002 TimeSys Corp. - * Copyright (C) 2003-2006 Yoichi Yuasa + * Copyright (C) 2003-2006 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/vr41xx/mpc30x.h b/trunk/arch/mips/include/asm/vr41xx/mpc30x.h index 130d09d8c8cb..1d67df843dc3 100644 --- a/trunk/arch/mips/include/asm/vr41xx/mpc30x.h +++ b/trunk/arch/mips/include/asm/vr41xx/mpc30x.h @@ -1,7 +1,7 @@ /* * mpc30x.h, Include file for Victor MP-C303/304. * - * Copyright (C) 2002-2004 Yoichi Yuasa + * Copyright (C) 2002-2004 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/vr41xx/pci.h b/trunk/arch/mips/include/asm/vr41xx/pci.h index c231a3d6cfd8..6fc01ce19777 100644 --- a/trunk/arch/mips/include/asm/vr41xx/pci.h +++ b/trunk/arch/mips/include/asm/vr41xx/pci.h @@ -1,7 +1,7 @@ /* * Include file for NEC VR4100 series PCI Control Unit. * - * Copyright (C) 2004-2005 Yoichi Yuasa + * Copyright (C) 2004-2005 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/vr41xx/siu.h b/trunk/arch/mips/include/asm/vr41xx/siu.h index ca806bc4ddc8..da9f6e373409 100644 --- a/trunk/arch/mips/include/asm/vr41xx/siu.h +++ b/trunk/arch/mips/include/asm/vr41xx/siu.h @@ -1,7 +1,7 @@ /* * Include file for NEC VR4100 series Serial Interface Unit. * - * Copyright (C) 2005-2008 Yoichi Yuasa + * Copyright (C) 2005-2008 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/vr41xx/tb0219.h b/trunk/arch/mips/include/asm/vr41xx/tb0219.h index c78e8243b447..dc981b4be0a4 100644 --- a/trunk/arch/mips/include/asm/vr41xx/tb0219.h +++ b/trunk/arch/mips/include/asm/vr41xx/tb0219.h @@ -1,7 +1,7 @@ /* * tb0219.h, Include file for TANBAC TB0219. * - * Copyright (C) 2002-2004 Yoichi Yuasa + * Copyright (C) 2002-2004 Yoichi Yuasa * * Modified for TANBAC TB0219: * Copyright (C) 2003 Megasolution Inc. diff --git a/trunk/arch/mips/include/asm/vr41xx/tb0226.h b/trunk/arch/mips/include/asm/vr41xx/tb0226.h index 36f5f798e416..de527dcfa5f3 100644 --- a/trunk/arch/mips/include/asm/vr41xx/tb0226.h +++ b/trunk/arch/mips/include/asm/vr41xx/tb0226.h @@ -1,7 +1,7 @@ /* * tb0226.h, Include file for TANBAC TB0226. * - * Copyright (C) 2002-2004 Yoichi Yuasa + * Copyright (C) 2002-2004 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/include/asm/vr41xx/vr41xx.h b/trunk/arch/mips/include/asm/vr41xx/vr41xx.h index 7b96a43b72ba..22be64971cc6 100644 --- a/trunk/arch/mips/include/asm/vr41xx/vr41xx.h +++ b/trunk/arch/mips/include/asm/vr41xx/vr41xx.h @@ -7,7 +7,7 @@ * Copyright (C) 2001, 2002 Paul Mundt * Copyright (C) 2002 MontaVista Software, Inc. * Copyright (C) 2002 TimeSys Corp. - * Copyright (C) 2003-2008 Yoichi Yuasa + * Copyright (C) 2003-2008 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/jazz/irq.c b/trunk/arch/mips/jazz/irq.c index 7fd170d007e7..d9b6a5b5399d 100644 --- a/trunk/arch/mips/jazz/irq.c +++ b/trunk/arch/mips/jazz/irq.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/kernel/binfmt_elfo32.c b/trunk/arch/mips/kernel/binfmt_elfo32.c index ff448233dab5..e1333d7319e2 100644 --- a/trunk/arch/mips/kernel/binfmt_elfo32.c +++ b/trunk/arch/mips/kernel/binfmt_elfo32.c @@ -53,23 +53,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) #include - -/* - * When this file is selected, we are definitely running a 64bit kernel. - * So using the right regs define in asm/reg.h - */ -#define WANT_COMPAT_REG_H - -/* These MUST be defined before elf.h gets included */ -extern void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs); -#define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs); -#define ELF_CORE_COPY_TASK_REGS(_tsk, _dest) \ -({ \ - int __res = 1; \ - elf32_core_copy_regs(*(_dest), task_pt_regs(_tsk)); \ - __res; \ -}) - #include #include #include @@ -127,6 +110,9 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) value->tv_usec = rem / NSEC_PER_USEC; } +#undef ELF_CORE_COPY_REGS +#define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs); + void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs) { int i; diff --git a/trunk/arch/mips/kernel/cevt-bcm1480.c b/trunk/arch/mips/kernel/cevt-bcm1480.c index e02f79b1eb51..a5182a207696 100644 --- a/trunk/arch/mips/kernel/cevt-bcm1480.c +++ b/trunk/arch/mips/kernel/cevt-bcm1480.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/kernel/cevt-ds1287.c b/trunk/arch/mips/kernel/cevt-ds1287.c index 6996da4d74a2..1ada45ea0700 100644 --- a/trunk/arch/mips/kernel/cevt-ds1287.c +++ b/trunk/arch/mips/kernel/cevt-ds1287.c @@ -1,7 +1,7 @@ /* * DS1287 clockevent driver * - * Copyright (C) 2008 Yoichi Yuasa + * Copyright (C) 2008 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/kernel/cevt-gt641xx.c b/trunk/arch/mips/kernel/cevt-gt641xx.c index 92351e00ae0e..e9b787feedcb 100644 --- a/trunk/arch/mips/kernel/cevt-gt641xx.c +++ b/trunk/arch/mips/kernel/cevt-gt641xx.c @@ -1,7 +1,7 @@ /* * GT641xx clockevent routines. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/kernel/cevt-r4k.c b/trunk/arch/mips/kernel/cevt-r4k.c index 2652362ce047..0015e442572b 100644 --- a/trunk/arch/mips/kernel/cevt-r4k.c +++ b/trunk/arch/mips/kernel/cevt-r4k.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/kernel/cevt-sb1250.c b/trunk/arch/mips/kernel/cevt-sb1250.c index ac5903d1b20e..340f53e5c6b1 100644 --- a/trunk/arch/mips/kernel/cevt-sb1250.c +++ b/trunk/arch/mips/kernel/cevt-sb1250.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/kernel/cevt-smtc.c b/trunk/arch/mips/kernel/cevt-smtc.c index 98bd7de75778..df6f5bc60572 100644 --- a/trunk/arch/mips/kernel/cevt-smtc.c +++ b/trunk/arch/mips/kernel/cevt-smtc.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 1abe9905c9c1..b13b8eb30596 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/kernel/csrc-ioasic.c b/trunk/arch/mips/kernel/csrc-ioasic.c index 23da108506b0..b551f48d3a07 100644 --- a/trunk/arch/mips/kernel/csrc-ioasic.c +++ b/trunk/arch/mips/kernel/csrc-ioasic.c @@ -1,7 +1,7 @@ /* * DEC I/O ASIC's counter clocksource * - * Copyright (C) 2008 Yoichi Yuasa + * Copyright (C) 2008 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/kernel/i8253.c b/trunk/arch/mips/kernel/i8253.c index f7d8d5d0ddbf..ed20e7fe65e3 100644 --- a/trunk/arch/mips/kernel/i8253.c +++ b/trunk/arch/mips/kernel/i8253.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/kernel/irq-gic.c b/trunk/arch/mips/kernel/irq-gic.c index d2072cd38592..3f43c2e3aa5a 100644 --- a/trunk/arch/mips/kernel/irq-gic.c +++ b/trunk/arch/mips/kernel/irq-gic.c @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -107,7 +106,9 @@ static unsigned int gic_irq_startup(unsigned int irq) { pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); irq -= _irqbase; - GIC_SET_INTR_MASK(irq, 1); + /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */ + GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))), + 1 << (irq % 32)); return 0; } @@ -118,7 +119,8 @@ static void gic_irq_ack(unsigned int irq) #endif pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); irq -= _irqbase; - GIC_CLR_INTR_MASK(irq, 1); + GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))), + 1 << (irq % 32)); if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) { if (!gic_wedgeb2bok) @@ -135,14 +137,18 @@ static void gic_mask_irq(unsigned int irq) { pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); irq -= _irqbase; - GIC_CLR_INTR_MASK(irq, 1); + /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */ + GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))), + 1 << (irq % 32)); } static void gic_unmask_irq(unsigned int irq) { pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); irq -= _irqbase; - GIC_SET_INTR_MASK(irq, 1); + /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */ + GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))), + 1 << (irq % 32)); } #ifdef CONFIG_SMP @@ -247,10 +253,6 @@ static void __init gic_basic_init(void) if (cpu == X) continue; - if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 && - _intrmap[i].ipiflag == 0) - continue; - setup_intr(_intrmap[i].intrnum, _intrmap[i].cpunum, _intrmap[i].pin, diff --git a/trunk/arch/mips/kernel/irq-gt641xx.c b/trunk/arch/mips/kernel/irq-gt641xx.c index ebcc5f7ad9c2..1b81b131f43c 100644 --- a/trunk/arch/mips/kernel/irq-gt641xx.c +++ b/trunk/arch/mips/kernel/irq-gt641xx.c @@ -1,7 +1,7 @@ /* * GT641xx IRQ routines. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/kernel/kgdb.c b/trunk/arch/mips/kernel/kgdb.c index 50c9bb880667..6e152c80cd4a 100644 --- a/trunk/arch/mips/kernel/kgdb.c +++ b/trunk/arch/mips/kernel/kgdb.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index c09d681b7181..1eaaa450e20c 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -50,15 +50,10 @@ */ void __noreturn cpu_idle(void) { - int cpu; - - /* CPU is going idle. */ - cpu = smp_processor_id(); - /* endless idle loop with no priority at all */ while (1) { tick_nohz_stop_sched_tick(1); - while (!need_resched() && cpu_online(cpu)) { + while (!need_resched()) { #ifdef CONFIG_MIPS_MT_SMTC extern void smtc_idle_loop_hook(void); @@ -67,12 +62,6 @@ void __noreturn cpu_idle(void) if (cpu_wait) (*cpu_wait)(); } -#ifdef CONFIG_HOTPLUG_CPU - if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) && - (system_state == SYSTEM_RUNNING || - system_state == SYSTEM_BOOTING)) - play_dead(); -#endif tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index 20a86e08fd58..0b31b9bda048 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -652,8 +652,6 @@ einval: li v0, -ENOSYS sys sys_inotify_init1 1 sys sys_preadv 6 /* 4330 */ sys sys_pwritev 6 - sys sys_rt_tgsigqueueinfo 4 - sys sys_perf_counter_open 5 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index b046130d4c5d..c647fd6e722f 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -489,6 +489,4 @@ sys_call_table: PTR sys_inotify_init1 PTR sys_preadv PTR sys_pwritev /* 5390 */ - PTR sys_rt_tgsigqueueinfo - PTR sys_perf_counter_open .size sys_call_table,.-sys_call_table diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index 15874f9812cc..93cc672f4522 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -415,6 +415,4 @@ EXPORT(sysn32_call_table) PTR sys_inotify_init1 PTR sys_preadv PTR sys_pwritev - PTR compat_sys_rt_tgsigqueueinfo /* 5295 */ - PTR sys_perf_counter_open .size sysn32_call_table,.-sysn32_call_table diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 781e0f1e9533..a5598b2339dd 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -535,6 +535,4 @@ sys_call_table: PTR sys_inotify_init1 PTR compat_sys_preadv /* 4330 */ PTR compat_sys_pwritev - PTR compat_sys_rt_tgsigqueueinfo - PTR sys_perf_counter_open .size sys_call_table,.-sys_call_table diff --git a/trunk/arch/mips/kernel/smp-cmp.c b/trunk/arch/mips/kernel/smp-cmp.c index ad0ff5dc4d59..f27beca4b26d 100644 --- a/trunk/arch/mips/kernel/smp-cmp.c +++ b/trunk/arch/mips/kernel/smp-cmp.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -37,24 +36,80 @@ #include #include #include -#include -#include + +/* + * Crude manipulation of the CPU masks to control which + * which CPU's are brought online during initialisation + * + * Beware... this needs to be called after CPU discovery + * but before CPU bringup + */ +static int __init allowcpus(char *str) +{ + cpumask_t cpu_allow_map; + char buf[256]; + int len; + + cpus_clear(cpu_allow_map); + if (cpulist_parse(str, &cpu_allow_map) == 0) { + cpu_set(0, cpu_allow_map); + cpus_and(cpu_possible_map, cpu_possible_map, cpu_allow_map); + len = cpulist_scnprintf(buf, sizeof(buf)-1, &cpu_possible_map); + buf[len] = '\0'; + pr_debug("Allowable CPUs: %s\n", buf); + return 1; + } else + return 0; +} +__setup("allowcpus=", allowcpus); static void ipi_call_function(unsigned int cpu) { + unsigned int action = 0; + pr_debug("CPU%d: %s cpu %d status %08x\n", smp_processor_id(), __func__, cpu, read_c0_status()); - gic_send_ipi(plat_ipi_call_int_xlate(cpu)); + switch (cpu) { + case 0: + action = GIC_IPI_EXT_INTR_CALLFNC_VPE0; + break; + case 1: + action = GIC_IPI_EXT_INTR_CALLFNC_VPE1; + break; + case 2: + action = GIC_IPI_EXT_INTR_CALLFNC_VPE2; + break; + case 3: + action = GIC_IPI_EXT_INTR_CALLFNC_VPE3; + break; + } + gic_send_ipi(action); } static void ipi_resched(unsigned int cpu) { + unsigned int action = 0; + pr_debug("CPU%d: %s cpu %d status %08x\n", smp_processor_id(), __func__, cpu, read_c0_status()); - gic_send_ipi(plat_ipi_resched_int_xlate(cpu)); + switch (cpu) { + case 0: + action = GIC_IPI_EXT_INTR_RESCHED_VPE0; + break; + case 1: + action = GIC_IPI_EXT_INTR_RESCHED_VPE1; + break; + case 2: + action = GIC_IPI_EXT_INTR_RESCHED_VPE2; + break; + case 3: + action = GIC_IPI_EXT_INTR_RESCHED_VPE3; + break; + } + gic_send_ipi(action); } /* @@ -150,7 +205,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle) (unsigned long)(gp + sizeof(struct thread_info))); #endif - amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0); + amon_cpu_start(cpu, pc, sp, gp, a0); } /* diff --git a/trunk/arch/mips/kernel/smp-up.c b/trunk/arch/mips/kernel/smp-up.c index 2508d55d68fd..878e3733bbb2 100644 --- a/trunk/arch/mips/kernel/smp-up.c +++ b/trunk/arch/mips/kernel/smp-up.c @@ -55,18 +55,6 @@ static void __init up_prepare_cpus(unsigned int max_cpus) { } -#ifdef CONFIG_HOTPLUG_CPU -static int up_cpu_disable(void) -{ - return -ENOSYS; -} - -static void up_cpu_die(unsigned int cpu) -{ - BUG(); -} -#endif - struct plat_smp_ops up_smp_ops = { .send_ipi_single = up_send_ipi_single, .send_ipi_mask = up_send_ipi_mask, @@ -76,8 +64,4 @@ struct plat_smp_ops up_smp_ops = { .boot_secondary = up_boot_secondary, .smp_setup = up_smp_setup, .prepare_cpus = up_prepare_cpus, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_disable = up_cpu_disable, - .cpu_die = up_cpu_die, -#endif }; diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index bc7d9b05e2f4..c937506a03aa 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -45,7 +44,7 @@ #include #endif /* CONFIG_MIPS_MT_SMTC */ -volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ +static volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ @@ -201,8 +200,6 @@ void __devinit smp_prepare_boot_cpu(void) * and keep control until "cpu_online(cpu)" is set. Note: cpu is * physical, not logical. */ -static struct task_struct *cpu_idle_thread[NR_CPUS]; - int __cpuinit __cpu_up(unsigned int cpu) { struct task_struct *idle; @@ -212,16 +209,9 @@ int __cpuinit __cpu_up(unsigned int cpu) * The following code is purely to make sure * Linux can schedule processes on this slave. */ - if (!cpu_idle_thread[cpu]) { - idle = fork_idle(cpu); - cpu_idle_thread[cpu] = idle; - - if (IS_ERR(idle)) - panic(KERN_ERR "Fork failed for CPU %d", cpu); - } else { - idle = cpu_idle_thread[cpu]; - init_idle(idle, cpu); - } + idle = fork_idle(cpu); + if (IS_ERR(idle)) + panic(KERN_ERR "Fork failed for CPU %d", cpu); mp_ops->boot_secondary(cpu, idle); diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index 8a0626cbb108..37d51cd124e9 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/kernel/sync-r4k.c b/trunk/arch/mips/kernel/sync-r4k.c index 05dd170a83f7..9021108eb9c1 100644 --- a/trunk/arch/mips/kernel/sync-r4k.c +++ b/trunk/arch/mips/kernel/sync-r4k.c @@ -1,7 +1,7 @@ /* * Count register synchronisation. * - * All CPUs will have their count registers synchronised to the CPU0 next time + * All CPUs will have their count registers synchronised to the CPU0 expirelo * value. This can cause a small timewarp for CPU0. All other CPU's should * not have done anything significant (but they may have had interrupts * enabled briefly - prom_smp_finish() should not be responsible for enabling @@ -13,22 +13,21 @@ #include #include #include -#include +#include -#include #include #include +#include #include -static atomic_t __cpuinitdata count_start_flag = ATOMIC_INIT(0); -static atomic_t __cpuinitdata count_count_start = ATOMIC_INIT(0); -static atomic_t __cpuinitdata count_count_stop = ATOMIC_INIT(0); -static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0); +static atomic_t __initdata count_start_flag = ATOMIC_INIT(0); +static atomic_t __initdata count_count_start = ATOMIC_INIT(0); +static atomic_t __initdata count_count_stop = ATOMIC_INIT(0); #define COUNTON 100 #define NR_LOOPS 5 -void __cpuinit synchronise_count_master(void) +void __init synchronise_count_master(void) { int i; unsigned long flags; @@ -43,20 +42,19 @@ void __cpuinit synchronise_count_master(void) return; #endif - printk(KERN_INFO "Synchronize counters across %u CPUs: ", - num_online_cpus()); + pr_info("Checking COUNT synchronization across %u CPUs: ", + num_online_cpus()); local_irq_save(flags); /* * Notify the slaves that it's time to start */ - atomic_set(&count_reference, read_c0_count()); atomic_set(&count_start_flag, 1); smp_wmb(); - /* Count will be initialised to current timer for all CPU's */ - initcount = read_c0_count(); + /* Count will be initialised to expirelo for all CPU's */ + initcount = expirelo; /* * We loop a few times to get a primed instruction cache, @@ -108,7 +106,7 @@ void __cpuinit synchronise_count_master(void) printk("done.\n"); } -void __cpuinit synchronise_count_slave(void) +void __init synchronise_count_slave(void) { int i; unsigned long flags; @@ -133,8 +131,8 @@ void __cpuinit synchronise_count_slave(void) while (!atomic_read(&count_start_flag)) mb(); - /* Count will be initialised to next expire for all CPU's */ - initcount = atomic_read(&count_reference); + /* Count will be initialised to expirelo for all CPU's */ + initcount = expirelo; ncpus = num_online_cpus(); for (i = 0; i < NR_LOOPS; i++) { @@ -158,3 +156,4 @@ void __cpuinit synchronise_count_slave(void) local_irq_restore(flags); } #undef NR_LOOPS +#endif diff --git a/trunk/arch/mips/kernel/topology.c b/trunk/arch/mips/kernel/topology.c index cf3eb61fad12..660e44ed44d7 100644 --- a/trunk/arch/mips/kernel/topology.c +++ b/trunk/arch/mips/kernel/topology.c @@ -17,10 +17,7 @@ static int __init topology_init(void) #endif /* CONFIG_NUMA */ for_each_present_cpu(i) { - struct cpu *c = &per_cpu(cpu_devices, i); - - c->hotpluggable = 1; - ret = register_cpu(c, i); + ret = register_cpu(&per_cpu(cpu_devices, i), i); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " "failed (%d)\n", i, ret); diff --git a/trunk/arch/mips/kernel/vpe.c b/trunk/arch/mips/kernel/vpe.c index 07b9ec2c6e3d..3ca5f42e819d 100644 --- a/trunk/arch/mips/kernel/vpe.c +++ b/trunk/arch/mips/kernel/vpe.c @@ -1387,7 +1387,7 @@ static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, return len; out_einval: - return -EINVAL; + return -EINVAL;; } static struct device_attribute vpe_class_attributes[] = { diff --git a/trunk/arch/mips/mipssim/sim_time.c b/trunk/arch/mips/mipssim/sim_time.c index 0cea932f1241..881ecbc1fa23 100644 --- a/trunk/arch/mips/mipssim/sim_time.c +++ b/trunk/arch/mips/mipssim/sim_time.c @@ -91,7 +91,6 @@ unsigned __cpuinit get_c0_compare_int(void) mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; } else { #endif - { if (cpu_has_vint) set_vi_handler(cp0_compare_irq, mips_timer_dispatch); mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; diff --git a/trunk/arch/mips/mm/c-octeon.c b/trunk/arch/mips/mm/c-octeon.c index b165cdcb2818..44d01a0a8490 100644 --- a/trunk/arch/mips/mm/c-octeon.c +++ b/trunk/arch/mips/mm/c-octeon.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/mm/c-r3k.c b/trunk/arch/mips/mm/c-r3k.c index 54e5f7b9f440..5500c20c79ae 100644 --- a/trunk/arch/mips/mm/c-r3k.c +++ b/trunk/arch/mips/mm/c-r3k.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index 6721ee2b1e8b..71fe4cb778cd 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/mm/c-tx39.c b/trunk/arch/mips/mm/c-tx39.c index 6515b4418714..f7c8f9ce39c1 100644 --- a/trunk/arch/mips/mm/c-tx39.c +++ b/trunk/arch/mips/mm/c-tx39.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/mm/highmem.c b/trunk/arch/mips/mm/highmem.c index e274fda329f4..2b1309b2580a 100644 --- a/trunk/arch/mips/mm/highmem.c +++ b/trunk/arch/mips/mm/highmem.c @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/trunk/arch/mips/mm/init.c b/trunk/arch/mips/mm/init.c index 0e820508ff23..c5511294a9ee 100644 --- a/trunk/arch/mips/mm/init.c +++ b/trunk/arch/mips/mm/init.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/mm/page.c b/trunk/arch/mips/mm/page.c index f5c73754d664..48060c635acd 100644 --- a/trunk/arch/mips/mm/page.c +++ b/trunk/arch/mips/mm/page.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/mm/tlb-r3k.c b/trunk/arch/mips/mm/tlb-r3k.c index 0f5ab236ab69..1c0048a6f5cf 100644 --- a/trunk/arch/mips/mm/tlb-r3k.c +++ b/trunk/arch/mips/mm/tlb-r3k.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/mm/tlb-r4k.c b/trunk/arch/mips/mm/tlb-r4k.c index cee502caf398..f60fe513eb60 100644 --- a/trunk/arch/mips/mm/tlb-r4k.c +++ b/trunk/arch/mips/mm/tlb-r4k.c @@ -10,7 +10,6 @@ */ #include #include -#include #include #include diff --git a/trunk/arch/mips/mm/tlb-r8k.c b/trunk/arch/mips/mm/tlb-r8k.c index 2b82f23df1a1..4ec95cc2df2f 100644 --- a/trunk/arch/mips/mm/tlb-r8k.c +++ b/trunk/arch/mips/mm/tlb-r8k.c @@ -10,7 +10,6 @@ */ #include #include -#include #include #include diff --git a/trunk/arch/mips/mm/tlbex.c b/trunk/arch/mips/mm/tlbex.c index 9a17bf8395df..8f606ead826e 100644 --- a/trunk/arch/mips/mm/tlbex.c +++ b/trunk/arch/mips/mm/tlbex.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/mips/mti-malta/malta-init.c b/trunk/arch/mips/mti-malta/malta-init.c index 27c807b67fea..475038a141a6 100644 --- a/trunk/arch/mips/mti-malta/malta-init.c +++ b/trunk/arch/mips/mti-malta/malta-init.c @@ -30,7 +30,6 @@ #include #include -#include #include #include #include @@ -193,8 +192,6 @@ extern struct plat_smp_ops msmtc_smp_ops; void __init prom_init(void) { - int result; - prom_argc = fw_arg0; _prom_argv = (int *) fw_arg1; _prom_envp = (int *) fw_arg2; @@ -361,21 +358,12 @@ void __init prom_init(void) #ifdef CONFIG_SERIAL_8250_CONSOLE console_config(); #endif - /* Early detection of CMP support */ - result = gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); - #ifdef CONFIG_MIPS_CMP - if (result) - register_smp_ops(&cmp_smp_ops); + register_smp_ops(&cmp_smp_ops); #endif #ifdef CONFIG_MIPS_MT_SMP -#ifdef CONFIG_MIPS_CMP - if (!result) - register_smp_ops(&vsmp_smp_ops); -#else register_smp_ops(&vsmp_smp_ops); #endif -#endif #ifdef CONFIG_MIPS_MT_SMTC register_smp_ops(&msmtc_smp_ops); #endif diff --git a/trunk/arch/mips/mti-malta/malta-int.c b/trunk/arch/mips/mti-malta/malta-int.c index a8756f82c31b..ea176113fea9 100644 --- a/trunk/arch/mips/mti-malta/malta-int.c +++ b/trunk/arch/mips/mti-malta/malta-int.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -331,21 +330,6 @@ static struct irqaction irq_call = { .flags = IRQF_DISABLED|IRQF_PERCPU, .name = "IPI_call" }; - -static int gic_resched_int_base; -static int gic_call_int_base; -#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) -#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) - -unsigned int plat_ipi_call_int_xlate(unsigned int cpu) -{ - return GIC_CALL_INT(cpu); -} - -unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) -{ - return GIC_RESCHED_INT(cpu); -} #endif /* CONFIG_MIPS_MT_SMP */ static struct irqaction i8259irq = { @@ -385,7 +369,7 @@ static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); * Interrupts and CPUs/Core Interrupts. The nature of the External * Interrupts is also defined here - polarity/trigger. */ -static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { +static struct gic_intr_map gic_intr_map[] = { { GIC_EXT_INTR(0), X, X, X, X, 0 }, { GIC_EXT_INTR(1), X, X, X, X, 0 }, { GIC_EXT_INTR(2), X, X, X, X, 0 }, @@ -402,14 +386,21 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { { GIC_EXT_INTR(13), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { GIC_EXT_INTR(14), 0, GIC_MAP_TO_NMI_MSK, GIC_POL_POS, GIC_TRIG_LEVEL, 0 }, { GIC_EXT_INTR(15), X, X, X, X, 0 }, -/* This is the end of the general interrupts now we do IPI ones */ + { GIC_EXT_INTR(16), 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(17), 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(18), 1, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(19), 1, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(20), 2, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(21), 2, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(22), 3, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, + { GIC_EXT_INTR(23), 3, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_EDGE, 1 }, }; #endif /* * GCMP needs to be detected before any SMP initialisation */ -int __init gcmp_probe(unsigned long addr, unsigned long size) +static int __init gcmp_probe(unsigned long addr, unsigned long size) { if (gcmp_present >= 0) return gcmp_present; @@ -424,36 +415,28 @@ int __init gcmp_probe(unsigned long addr, unsigned long size) } #if defined(CONFIG_MIPS_MT_SMP) -static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) -{ - int intr = baseintr + cpu; - gic_intr_map[intr].intrnum = GIC_EXT_INTR(intr); - gic_intr_map[intr].cpunum = cpu; - gic_intr_map[intr].pin = cpupin; - gic_intr_map[intr].polarity = GIC_POL_POS; - gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; - gic_intr_map[intr].ipiflag = 1; - ipi_map[cpu] |= (1 << (cpupin + 2)); -} - static void __init fill_ipi_map(void) { - int cpu; + int i; - for (cpu = 0; cpu < NR_CPUS; cpu++) { - fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); - fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); + for (i = 0; i < ARRAY_SIZE(gic_intr_map); i++) { + if (gic_intr_map[i].ipiflag && (gic_intr_map[i].cpunum != X)) + ipi_map[gic_intr_map[i].cpunum] |= + (1 << (gic_intr_map[i].pin + 2)); } } #endif void __init arch_init_irq(void) { + int gic_present, gcmp_present; + init_i8259_irqs(); if (!cpu_has_veic) mips_cpu_irq_init(); + gcmp_present = gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); if (gcmp_present) { GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK; gic_present = 1; @@ -530,10 +513,24 @@ void __init arch_init_irq(void) if (gic_present) { /* FIXME */ int i; - - gic_call_int_base = GIC_NUM_INTRS - NR_CPUS; - gic_resched_int_base = gic_call_int_base - NR_CPUS; - + struct { + unsigned int resched; + unsigned int call; + } ipiirq[] = { + { + .resched = GIC_IPI_EXT_INTR_RESCHED_VPE0, + .call = GIC_IPI_EXT_INTR_CALLFNC_VPE0}, + { + .resched = GIC_IPI_EXT_INTR_RESCHED_VPE1, + .call = GIC_IPI_EXT_INTR_CALLFNC_VPE1 + }, { + .resched = GIC_IPI_EXT_INTR_RESCHED_VPE2, + .call = GIC_IPI_EXT_INTR_CALLFNC_VPE2 + }, { + .resched = GIC_IPI_EXT_INTR_RESCHED_VPE3, + .call = GIC_IPI_EXT_INTR_CALLFNC_VPE3 + } + }; fill_ipi_map(); gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); if (!gcmp_present) { @@ -555,15 +552,12 @@ void __init arch_init_irq(void) printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status()); write_c0_status(0x1100dc00); printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status()); - for (i = 0; i < NR_CPUS; i++) { - setup_irq(MIPS_GIC_IRQ_BASE + - GIC_RESCHED_INT(i), &irq_resched); - setup_irq(MIPS_GIC_IRQ_BASE + - GIC_CALL_INT(i), &irq_call); - set_irq_handler(MIPS_GIC_IRQ_BASE + - GIC_RESCHED_INT(i), handle_percpu_irq); - set_irq_handler(MIPS_GIC_IRQ_BASE + - GIC_CALL_INT(i), handle_percpu_irq); + for (i = 0; i < ARRAY_SIZE(ipiirq); i++) { + setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, &irq_resched); + setup_irq(MIPS_GIC_IRQ_BASE + ipiirq[i].call, &irq_call); + + set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].resched, handle_percpu_irq); + set_irq_handler(MIPS_GIC_IRQ_BASE + ipiirq[i].call, handle_percpu_irq); } } else { /* set up ipi interrupts */ diff --git a/trunk/arch/mips/mti-malta/malta-reset.c b/trunk/arch/mips/mti-malta/malta-reset.c index f48d60e84290..42dee4da37ba 100644 --- a/trunk/arch/mips/mti-malta/malta-reset.c +++ b/trunk/arch/mips/mti-malta/malta-reset.c @@ -28,6 +28,9 @@ #include #include +static void mips_machine_restart(char *command); +static void mips_machine_halt(void); + static void mips_machine_restart(char *command) { unsigned int __iomem *softres_reg = diff --git a/trunk/arch/mips/pci/Makefile b/trunk/arch/mips/pci/Makefile index 63d8a297c58d..e8a97f59e066 100644 --- a/trunk/arch/mips/pci/Makefile +++ b/trunk/arch/mips/pci/Makefile @@ -52,8 +52,3 @@ obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o -obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o - -ifdef CONFIG_PCI_MSI -obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o -endif diff --git a/trunk/arch/mips/pci/fixup-capcella.c b/trunk/arch/mips/pci/fixup-capcella.c index 1c02f5737367..1416bca6d1a3 100644 --- a/trunk/arch/mips/pci/fixup-capcella.c +++ b/trunk/arch/mips/pci/fixup-capcella.c @@ -1,7 +1,7 @@ /* * fixup-cappcela.c, The ZAO Networks Capcella specific PCI fixups. * - * Copyright (C) 2002,2004 Yoichi Yuasa + * Copyright (C) 2002,2004 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/pci/fixup-mpc30x.c b/trunk/arch/mips/pci/fixup-mpc30x.c index e08f49cb6875..591159625722 100644 --- a/trunk/arch/mips/pci/fixup-mpc30x.c +++ b/trunk/arch/mips/pci/fixup-mpc30x.c @@ -1,7 +1,7 @@ /* * fixup-mpc30x.c, The Victor MP-C303/304 specific PCI fixups. * - * Copyright (C) 2002,2004 Yoichi Yuasa + * Copyright (C) 2002,2004 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/pci/fixup-tb0219.c b/trunk/arch/mips/pci/fixup-tb0219.c index 8084b17d4406..ed87733f6796 100644 --- a/trunk/arch/mips/pci/fixup-tb0219.c +++ b/trunk/arch/mips/pci/fixup-tb0219.c @@ -2,7 +2,7 @@ * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups. * * Copyright (C) 2003 Megasolution Inc. - * Copyright (C) 2004-2005 Yoichi Yuasa + * Copyright (C) 2004-2005 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/pci/fixup-tb0226.c b/trunk/arch/mips/pci/fixup-tb0226.c index 4196ccf3ea3d..e3eedf4bf9bd 100644 --- a/trunk/arch/mips/pci/fixup-tb0226.c +++ b/trunk/arch/mips/pci/fixup-tb0226.c @@ -1,7 +1,7 @@ /* * fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups. * - * Copyright (C) 2002-2005 Yoichi Yuasa + * Copyright (C) 2002-2005 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/pci/fixup-tb0287.c b/trunk/arch/mips/pci/fixup-tb0287.c index 2fe29db43725..267ab3dc3d42 100644 --- a/trunk/arch/mips/pci/fixup-tb0287.c +++ b/trunk/arch/mips/pci/fixup-tb0287.c @@ -1,7 +1,7 @@ /* * fixup-tb0287.c, The TANBAC TB0287 specific PCI fixups. * - * Copyright (C) 2005 Yoichi Yuasa + * Copyright (C) 2005 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/pci/ops-vr41xx.c b/trunk/arch/mips/pci/ops-vr41xx.c index 28962a7c6606..900c6b32576c 100644 --- a/trunk/arch/mips/pci/ops-vr41xx.c +++ b/trunk/arch/mips/pci/ops-vr41xx.c @@ -2,8 +2,8 @@ * ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series. * * Copyright (C) 2001-2003 MontaVista Software Inc. - * Author: Yoichi Yuasa - * Copyright (C) 2004-2005 Yoichi Yuasa + * Author: Yoichi Yuasa + * Copyright (C) 2004-2005 Yoichi Yuasa * * 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 @@ -21,7 +21,7 @@ */ /* * Changes: - * MontaVista Software Inc. + * MontaVista Software Inc. or * - New creation, NEC VR4122 and VR4131 are supported. */ #include diff --git a/trunk/arch/mips/pci/pci-ip27.c b/trunk/arch/mips/pci/pci-ip27.c index a0e726eb039a..dda6f2058665 100644 --- a/trunk/arch/mips/pci/pci-ip27.c +++ b/trunk/arch/mips/pci/pci-ip27.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/pci/pci-vr41xx.c b/trunk/arch/mips/pci/pci-vr41xx.c index 56525711f8b7..d1e049b55f34 100644 --- a/trunk/arch/mips/pci/pci-vr41xx.c +++ b/trunk/arch/mips/pci/pci-vr41xx.c @@ -2,8 +2,8 @@ * pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series. * * Copyright (C) 2001-2003 MontaVista Software Inc. - * Author: Yoichi Yuasa - * Copyright (C) 2004-2008 Yoichi Yuasa + * Author: Yoichi Yuasa + * Copyright (C) 2004-2008 Yoichi Yuasa * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) * * This program is free software; you can redistribute it and/or modify @@ -22,7 +22,7 @@ */ /* * Changes: - * MontaVista Software Inc. + * MontaVista Software Inc. or * - New creation, NEC VR4122 and VR4131 are supported. */ #include diff --git a/trunk/arch/mips/pci/pci-vr41xx.h b/trunk/arch/mips/pci/pci-vr41xx.h index 6b1ae2eb1c06..8a35e32b8376 100644 --- a/trunk/arch/mips/pci/pci-vr41xx.h +++ b/trunk/arch/mips/pci/pci-vr41xx.h @@ -2,8 +2,8 @@ * pci-vr41xx.h, Include file for PCI Control Unit of the NEC VR4100 series. * * Copyright (C) 2002 MontaVista Software Inc. - * Author: Yoichi Yuasa - * Copyright (C) 2004-2005 Yoichi Yuasa + * Author: Yoichi Yuasa + * Copyright (C) 2004-2005 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/pmc-sierra/yosemite/smp.c b/trunk/arch/mips/pmc-sierra/yosemite/smp.c index 8ace27716232..f78c29b68d77 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/smp.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/smp.c @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/trunk/arch/mips/power/hibernate.S b/trunk/arch/mips/power/hibernate.S index 4b8174b382d7..486bd3fd01a1 100644 --- a/trunk/arch/mips/power/hibernate.S +++ b/trunk/arch/mips/power/hibernate.S @@ -43,6 +43,15 @@ LEAF(swsusp_arch_resume) bne t1, t3, 1b PTR_L t0, PBE_NEXT(t0) bnez t0, 0b + /* flush caches to make sure context is in memory */ + PTR_L t0, __flush_cache_all + jalr t0 + /* flush tlb entries */ +#ifdef CONFIG_SMP + jal flush_tlb_all +#else + jal local_flush_tlb_all +#endif PTR_LA t0, saved_regs PTR_L ra, PT_R31(t0) PTR_L sp, PT_R29(t0) diff --git a/trunk/arch/mips/sgi-ip27/ip27-init.c b/trunk/arch/mips/sgi-ip27/ip27-init.c index 51d3a4f2d7e1..4a500e8cd3cc 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-init.c +++ b/trunk/arch/mips/sgi-ip27/ip27-init.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/sgi-ip27/ip27-irq.c b/trunk/arch/mips/sgi-ip27/ip27-irq.c index c1c8e40d65d6..1bb692a3b319 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-irq.c +++ b/trunk/arch/mips/sgi-ip27/ip27-irq.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index 6d0e59ffba2e..f10a7cd64f7e 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/sgi-ip27/ip27-xtalk.c b/trunk/arch/mips/sgi-ip27/ip27-xtalk.c index 5e871e75a8d9..6ae64e8dfc40 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-xtalk.c +++ b/trunk/arch/mips/sgi-ip27/ip27-xtalk.c @@ -9,7 +9,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mips/sibyte/bcm1480/irq.c b/trunk/arch/mips/sibyte/bcm1480/irq.c index ba59839a021e..690de06bde90 100644 --- a/trunk/arch/mips/sibyte/bcm1480/irq.c +++ b/trunk/arch/mips/sibyte/bcm1480/irq.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/sibyte/common/cfe_console.c b/trunk/arch/mips/sibyte/common/cfe_console.c index 1ad2da103fe9..81e3d54376e9 100644 --- a/trunk/arch/mips/sibyte/common/cfe_console.c +++ b/trunk/arch/mips/sibyte/common/cfe_console.c @@ -51,13 +51,12 @@ static int cfe_console_setup(struct console *cons, char *str) setleds("u0cn"); } else if (!strcmp(consdev, "uart1")) { setleds("u1cn"); - } else #endif #ifdef CONFIG_VGA_CONSOLE - if (!strcmp(consdev, "pcconsole0")) { - setleds("pccn"); - } else + } else if (!strcmp(consdev, "pcconsole0")) { + setleds("pccn"); #endif + } else return -ENODEV; } return 0; diff --git a/trunk/arch/mips/sni/time.c b/trunk/arch/mips/sni/time.c index 0d9ec1a5c24a..69f5f88711cc 100644 --- a/trunk/arch/mips/sni/time.c +++ b/trunk/arch/mips/sni/time.c @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/trunk/arch/mips/vr41xx/casio-e55/setup.c b/trunk/arch/mips/vr41xx/casio-e55/setup.c index 719f4a5b9844..6d9bab890587 100644 --- a/trunk/arch/mips/vr41xx/casio-e55/setup.c +++ b/trunk/arch/mips/vr41xx/casio-e55/setup.c @@ -1,7 +1,7 @@ /* * setup.c, Setup for the CASIO CASSIOPEIA E-11/15/55/65. * - * Copyright (C) 2002-2006 Yoichi Yuasa + * Copyright (C) 2002-2006 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/vr41xx/common/bcu.c b/trunk/arch/mips/vr41xx/common/bcu.c index 6346c59c9f9d..d77c330a0d59 100644 --- a/trunk/arch/mips/vr41xx/common/bcu.c +++ b/trunk/arch/mips/vr41xx/common/bcu.c @@ -2,8 +2,8 @@ * bcu.c, Bus Control Unit routines for the NEC VR4100 series. * * Copyright (C) 2002 MontaVista Software Inc. - * Author: Yoichi Yuasa - * Copyright (C) 2003-2005 Yoichi Yuasa + * Author: Yoichi Yuasa + * Copyright (C) 2003-2005 Yoichi Yuasa * * 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 @@ -21,11 +21,11 @@ */ /* * Changes: - * MontaVista Software Inc. + * MontaVista Software Inc. or * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * Yoichi Yuasa + * Yoichi Yuasa * - Added support for NEC VR4133. */ #include diff --git a/trunk/arch/mips/vr41xx/common/cmu.c b/trunk/arch/mips/vr41xx/common/cmu.c index 8ba7d04a5ec5..ad0e8e3409d9 100644 --- a/trunk/arch/mips/vr41xx/common/cmu.c +++ b/trunk/arch/mips/vr41xx/common/cmu.c @@ -2,8 +2,8 @@ * cmu.c, Clock Mask Unit routines for the NEC VR4100 series. * * Copyright (C) 2001-2002 MontaVista Software Inc. - * Author: Yoichi Yuasa - * Copuright (C) 2003-2005 Yoichi Yuasa + * Author: Yoichi Yuasa + * Copuright (C) 2003-2005 Yoichi Yuasa * * 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 @@ -21,11 +21,11 @@ */ /* * Changes: - * MontaVista Software Inc. + * MontaVista Software Inc. or * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * Yoichi Yuasa + * Yoichi Yuasa * - Added support for NEC VR4133. */ #include diff --git a/trunk/arch/mips/vr41xx/common/giu.c b/trunk/arch/mips/vr41xx/common/giu.c index 22cc6f2100a1..2b272f1496fe 100644 --- a/trunk/arch/mips/vr41xx/common/giu.c +++ b/trunk/arch/mips/vr41xx/common/giu.c @@ -1,7 +1,7 @@ /* * NEC VR4100 series GIU platform device. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/vr41xx/common/icu.c b/trunk/arch/mips/vr41xx/common/icu.c index 6d39e222b170..3f23d9fda662 100644 --- a/trunk/arch/mips/vr41xx/common/icu.c +++ b/trunk/arch/mips/vr41xx/common/icu.c @@ -2,8 +2,8 @@ * icu.c, Interrupt Control Unit routines for the NEC VR4100 series. * * Copyright (C) 2001-2002 MontaVista Software Inc. - * Author: Yoichi Yuasa - * Copyright (C) 2003-2006 Yoichi Yuasa + * Author: Yoichi Yuasa + * Copyright (C) 2003-2006 Yoichi Yuasa * * 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 @@ -21,11 +21,11 @@ */ /* * Changes: - * MontaVista Software Inc. + * MontaVista Software Inc. or * - New creation, NEC VR4122 and VR4131 are supported. * - Added support for NEC VR4111 and VR4121. * - * Yoichi Yuasa + * Yoichi Yuasa * - Coped with INTASSIGN of NEC VR4133. */ #include diff --git a/trunk/arch/mips/vr41xx/common/init.c b/trunk/arch/mips/vr41xx/common/init.c index 1386e6f081c8..c64995342ba8 100644 --- a/trunk/arch/mips/vr41xx/common/init.c +++ b/trunk/arch/mips/vr41xx/common/init.c @@ -1,7 +1,7 @@ /* * init.c, Common initialization routines for NEC VR4100 series. * - * Copyright (C) 2003-2008 Yoichi Yuasa + * Copyright (C) 2003-2008 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/vr41xx/common/irq.c b/trunk/arch/mips/vr41xx/common/irq.c index bef06872f012..9cc389109b19 100644 --- a/trunk/arch/mips/vr41xx/common/irq.c +++ b/trunk/arch/mips/vr41xx/common/irq.c @@ -1,7 +1,7 @@ /* * Interrupt handing routines for NEC VR4100 series. * - * Copyright (C) 2005-2007 Yoichi Yuasa + * Copyright (C) 2005-2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/vr41xx/common/pmu.c b/trunk/arch/mips/vr41xx/common/pmu.c index 692b4e85b7fc..028aaf75eb21 100644 --- a/trunk/arch/mips/vr41xx/common/pmu.c +++ b/trunk/arch/mips/vr41xx/common/pmu.c @@ -1,7 +1,7 @@ /* * pmu.c, Power Management Unit routines for NEC VR4100 series. * - * Copyright (C) 2003-2007 Yoichi Yuasa + * Copyright (C) 2003-2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/vr41xx/common/rtc.c b/trunk/arch/mips/vr41xx/common/rtc.c index ebc5dcf0ed8e..9f26c14edcac 100644 --- a/trunk/arch/mips/vr41xx/common/rtc.c +++ b/trunk/arch/mips/vr41xx/common/rtc.c @@ -1,7 +1,7 @@ /* * NEC VR4100 series RTC platform device. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/vr41xx/common/siu.c b/trunk/arch/mips/vr41xx/common/siu.c index 54eae56108fb..654dee6208be 100644 --- a/trunk/arch/mips/vr41xx/common/siu.c +++ b/trunk/arch/mips/vr41xx/common/siu.c @@ -1,7 +1,7 @@ /* * NEC VR4100 series SIU platform device. * - * Copyright (C) 2007-2008 Yoichi Yuasa + * Copyright (C) 2007-2008 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/vr41xx/common/type.c b/trunk/arch/mips/vr41xx/common/type.c index ff841422b638..e0c1ac5e988e 100644 --- a/trunk/arch/mips/vr41xx/common/type.c +++ b/trunk/arch/mips/vr41xx/common/type.c @@ -1,7 +1,7 @@ /* * type.c, System type for NEC VR4100 series. * - * Copyright (C) 2005 Yoichi Yuasa + * Copyright (C) 2005 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mips/vr41xx/ibm-workpad/setup.c b/trunk/arch/mips/vr41xx/ibm-workpad/setup.c index 3982f378a3e6..9eef297eca1a 100644 --- a/trunk/arch/mips/vr41xx/ibm-workpad/setup.c +++ b/trunk/arch/mips/vr41xx/ibm-workpad/setup.c @@ -1,7 +1,7 @@ /* * setup.c, Setup for the IBM WorkPad z50. * - * Copyright (C) 2002-2006 Yoichi Yuasa + * Copyright (C) 2002-2006 Yoichi Yuasa * * 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 diff --git a/trunk/arch/mn10300/include/asm/unistd.h b/trunk/arch/mn10300/include/asm/unistd.h index fad68616af32..fef5b434dadc 100644 --- a/trunk/arch/mn10300/include/asm/unistd.h +++ b/trunk/arch/mn10300/include/asm/unistd.h @@ -346,12 +346,10 @@ #define __NR_inotify_init1 333 #define __NR_preadv 334 #define __NR_pwritev 335 -#define __NR_rt_tgsigqueueinfo 336 -#define __NR_perf_counter_open 337 #ifdef __KERNEL__ -#define NR_syscalls 338 +#define NR_syscalls 326 /* * specify the deprecated syscalls we want to support on this arch diff --git a/trunk/arch/mn10300/kernel/entry.S b/trunk/arch/mn10300/kernel/entry.S index e0d2563af4f2..7408a27199f3 100644 --- a/trunk/arch/mn10300/kernel/entry.S +++ b/trunk/arch/mn10300/kernel/entry.S @@ -722,8 +722,6 @@ ENTRY(sys_call_table) .long sys_inotify_init1 .long sys_preadv .long sys_pwritev /* 335 */ - .long sys_rt_tgsigqueueinfo - .long sys_perf_counter_open nr_syscalls=(.-sys_call_table)/4 diff --git a/trunk/arch/mn10300/kernel/vmlinux.lds.S b/trunk/arch/mn10300/kernel/vmlinux.lds.S index c96ba3da95ac..bcebcefb4ad7 100644 --- a/trunk/arch/mn10300/kernel/vmlinux.lds.S +++ b/trunk/arch/mn10300/kernel/vmlinux.lds.S @@ -61,7 +61,7 @@ SECTIONS _edata = .; /* End of data section */ } - .data.init_task : { INIT_TASK_DATA(THREAD_SIZE); } + .data.init_task : { INIT_TASK(THREAD_SIZE); } /* might get freed after init */ . = ALIGN(PAGE_SIZE); diff --git a/trunk/arch/parisc/include/asm/unistd.h b/trunk/arch/parisc/include/asm/unistd.h index ef26b009dc5d..a3c341976dc2 100644 --- a/trunk/arch/parisc/include/asm/unistd.h +++ b/trunk/arch/parisc/include/asm/unistd.h @@ -807,8 +807,10 @@ #define __NR_dup3 (__NR_Linux + 312) #define __NR_pipe2 (__NR_Linux + 313) #define __NR_inotify_init1 (__NR_Linux + 314) +#define __NR_preadv (__NR_Linux + 315) +#define __NR_pwritev (__NR_Linux + 316) -#define __NR_Linux_syscalls (__NR_inotify_init1 + 1) +#define __NR_Linux_syscalls (__NR_pwritev + 1) #define __IGNORE_select /* newselect */ diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index 03b9a01bc16c..6a6296148e5d 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -413,6 +413,8 @@ ENTRY_SAME(dup3) ENTRY_SAME(pipe2) ENTRY_SAME(inotify_init1) + ENTRY_COMP(preadv) + ENTRY_COMP(pwritev) /* Nothing yet */ diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index d00131ca0835..bf6cedfa05db 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -62,6 +62,7 @@ config HAVE_LATENCYTOP_SUPPORT config TRACE_IRQFLAGS_SUPPORT bool + depends on PPC64 default y config LOCKDEP_SUPPORT diff --git a/trunk/arch/powerpc/boot/.gitignore b/trunk/arch/powerpc/boot/.gitignore index 3d80c3e9cf60..2f50acd11a60 100644 --- a/trunk/arch/powerpc/boot/.gitignore +++ b/trunk/arch/powerpc/boot/.gitignore @@ -36,13 +36,3 @@ zImage.pseries zconf.h zlib.h zutil.h -fdt.c -fdt.h -fdt_ro.c -fdt_rw.c -fdt_strerror.c -fdt_sw.c -fdt_wip.c -libfdt.h -libfdt_internal.h - diff --git a/trunk/arch/powerpc/boot/dts/amigaone.dts b/trunk/arch/powerpc/boot/dts/amigaone.dts index 49ac36b16dd7..26549fca2ed4 100644 --- a/trunk/arch/powerpc/boot/dts/amigaone.dts +++ b/trunk/arch/powerpc/boot/dts/amigaone.dts @@ -70,8 +70,8 @@ devsel-speed = <0x00000001>; min-grant = <0>; max-latency = <0>; - /* First 4k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */ - ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00001000>; + /* First 64k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */ + ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00010000>; interrupt-parent = <&i8259>; #interrupt-cells = <2>; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/mpc8569mds.dts b/trunk/arch/powerpc/boot/dts/mpc8569mds.dts index a680165292f2..a8dcb018c4a5 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8569mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8569mds.dts @@ -253,7 +253,6 @@ /* Filled in by U-Boot */ clock-frequency = <0>; status = "disabled"; - sdhci,1-bit-only; }; crypto@30000 { diff --git a/trunk/arch/powerpc/include/asm/cpm1.h b/trunk/arch/powerpc/include/asm/cpm1.h index 7685ffde8821..2ff798744c1d 100644 --- a/trunk/arch/powerpc/include/asm/cpm1.h +++ b/trunk/arch/powerpc/include/asm/cpm1.h @@ -598,6 +598,8 @@ typedef struct risc_timer_pram { #define CICR_IEN ((uint)0x00000080) /* Int. enable */ #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ +#define IMAP_ADDR (get_immrbase()) + #define CPM_PIN_INPUT 0 #define CPM_PIN_OUTPUT 1 #define CPM_PIN_PRIMARY 0 diff --git a/trunk/arch/powerpc/include/asm/dma-mapping.h b/trunk/arch/powerpc/include/asm/dma-mapping.h index b44aaabdd1a6..3d9e887c3c0c 100644 --- a/trunk/arch/powerpc/include/asm/dma-mapping.h +++ b/trunk/arch/powerpc/include/asm/dma-mapping.h @@ -309,9 +309,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_single_range_for_cpu) - dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, + dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, size, direction); } @@ -322,9 +320,7 @@ static inline void dma_sync_single_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_single_range_for_device) - dma_ops->sync_single_range_for_device(dev, dma_handle, + dma_ops->sync_single_range_for_device(dev, dma_handle, 0, size, direction); } @@ -335,9 +331,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_sg_for_cpu) - dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); + dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); } static inline void dma_sync_sg_for_device(struct device *dev, @@ -347,9 +341,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_sg_for_device) - dma_ops->sync_sg_for_device(dev, sgl, nents, direction); + dma_ops->sync_sg_for_device(dev, sgl, nents, direction); } static inline void dma_sync_single_range_for_cpu(struct device *dev, @@ -359,9 +351,7 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_single_range_for_cpu) - dma_ops->sync_single_range_for_cpu(dev, dma_handle, + dma_ops->sync_single_range_for_cpu(dev, dma_handle, offset, size, direction); } @@ -372,9 +362,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev, struct dma_mapping_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - - if (dma_ops->sync_single_range_for_device) - dma_ops->sync_single_range_for_device(dev, dma_handle, offset, + dma_ops->sync_single_range_for_device(dev, dma_handle, offset, size, direction); } #else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */ diff --git a/trunk/arch/powerpc/include/asm/highmem.h b/trunk/arch/powerpc/include/asm/highmem.h index a74c4ee6c020..684a73f4324f 100644 --- a/trunk/arch/powerpc/include/asm/highmem.h +++ b/trunk/arch/powerpc/include/asm/highmem.h @@ -22,7 +22,9 @@ #ifdef __KERNEL__ +#include #include +#include #include #include #include @@ -60,9 +62,6 @@ extern pte_t *pkmap_page_table; extern void *kmap_high(struct page *page); extern void kunmap_high(struct page *page); -extern void *kmap_atomic_prot(struct page *page, enum km_type type, - pgprot_t prot); -extern void kunmap_atomic(void *kvaddr, enum km_type type); static inline void *kmap(struct page *page) { @@ -80,11 +79,62 @@ static inline void kunmap(struct page *page) kunmap_high(page); } +/* + * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap + * gives a more generic (and caching) interface. But kmap_atomic can + * be used in IRQ contexts, so in some (very limited) cases we need + * it. + */ +static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) +{ + unsigned int idx; + unsigned long vaddr; + + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ + pagefault_disable(); + if (!PageHighMem(page)) + return page_address(page); + + debug_kmap_atomic(type); + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#ifdef CONFIG_DEBUG_HIGHMEM + BUG_ON(!pte_none(*(kmap_pte-idx))); +#endif + __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1); + local_flush_tlb_page(NULL, vaddr); + + return (void*) vaddr; +} + static inline void *kmap_atomic(struct page *page, enum km_type type) { return kmap_atomic_prot(page, type, kmap_prot); } +static inline void kunmap_atomic(void *kvaddr, enum km_type type) +{ +#ifdef CONFIG_DEBUG_HIGHMEM + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); + + if (vaddr < __fix_to_virt(FIX_KMAP_END)) { + pagefault_enable(); + return; + } + + BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); + + /* + * force other mappings to Oops if they'll try to access + * this pte without first remap it + */ + pte_clear(&init_mm, vaddr, kmap_pte-idx); + local_flush_tlb_page(NULL, vaddr); +#endif + pagefault_enable(); +} + static inline struct page *kmap_atomic_to_page(void *ptr) { unsigned long idx, vaddr = (unsigned long) ptr; @@ -98,7 +148,6 @@ static inline struct page *kmap_atomic_to_page(void *ptr) return pte_page(*pte); } - #define flush_cache_kmaps() flush_cache_all() #endif /* __KERNEL__ */ diff --git a/trunk/arch/powerpc/include/asm/hw_irq.h b/trunk/arch/powerpc/include/asm/hw_irq.h index 8b505eaaa38a..867ab8ed69b3 100644 --- a/trunk/arch/powerpc/include/asm/hw_irq.h +++ b/trunk/arch/powerpc/include/asm/hw_irq.h @@ -68,13 +68,13 @@ static inline int irqs_disabled_flags(unsigned long flags) #if defined(CONFIG_BOOKE) #define SET_MSR_EE(x) mtmsr(x) -#define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") +#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") #else #define SET_MSR_EE(x) mtmsr(x) -#define raw_local_irq_restore(flags) mtmsr(flags) +#define local_irq_restore(flags) mtmsr(flags) #endif -static inline void raw_local_irq_disable(void) +static inline void local_irq_disable(void) { #ifdef CONFIG_BOOKE __asm__ __volatile__("wrteei 0": : :"memory"); @@ -86,7 +86,7 @@ static inline void raw_local_irq_disable(void) #endif } -static inline void raw_local_irq_enable(void) +static inline void local_irq_enable(void) { #ifdef CONFIG_BOOKE __asm__ __volatile__("wrteei 1": : :"memory"); @@ -98,7 +98,7 @@ static inline void raw_local_irq_enable(void) #endif } -static inline void raw_local_irq_save_ptr(unsigned long *flags) +static inline void local_irq_save_ptr(unsigned long *flags) { unsigned long msr; msr = mfmsr(); @@ -110,12 +110,12 @@ static inline void raw_local_irq_save_ptr(unsigned long *flags) #endif } -#define raw_local_save_flags(flags) ((flags) = mfmsr()) -#define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags) -#define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0) -#define raw_irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0) +#define local_save_flags(flags) ((flags) = mfmsr()) +#define local_irq_save(flags) local_irq_save_ptr(&flags) +#define irqs_disabled() ((mfmsr() & MSR_EE) == 0) -#define hard_irq_disable() raw_local_irq_disable() +#define hard_irq_enable() local_irq_enable() +#define hard_irq_disable() local_irq_disable() static inline int irqs_disabled_flags(unsigned long flags) { diff --git a/trunk/arch/powerpc/include/asm/perf_counter.h b/trunk/arch/powerpc/include/asm/perf_counter.h index 0ea0639fcf75..8ccd4e155768 100644 --- a/trunk/arch/powerpc/include/asm/perf_counter.h +++ b/trunk/arch/powerpc/include/asm/perf_counter.h @@ -61,8 +61,6 @@ struct pt_regs; extern unsigned long perf_misc_flags(struct pt_regs *regs); extern unsigned long perf_instruction_pointer(struct pt_regs *regs); -#define PERF_COUNTER_INDEX_OFFSET 1 - /* * Only override the default definitions in include/linux/perf_counter.h * if we have hardware PMU support. diff --git a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h b/trunk/arch/powerpc/include/asm/pte-hash64-64k.h index 82b72207c51c..e05d26fa372f 100644 --- a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h +++ b/trunk/arch/powerpc/include/asm/pte-hash64-64k.h @@ -47,8 +47,7 @@ * generic accessors and iterators here */ #define __real_pte(e,p) ((real_pte_t) { \ - (e), ((e) & _PAGE_COMBO) ? \ - (pte_val(*((p) + PTRS_PER_PTE))) : 0 }) + (e), pte_val(*((p) + PTRS_PER_PTE)) }) #define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \ (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf)) #define __rpte_to_pte(r) ((r).pte) diff --git a/trunk/arch/powerpc/include/asm/rtas.h b/trunk/arch/powerpc/include/asm/rtas.h index 168fce726201..01c12339b304 100644 --- a/trunk/arch/powerpc/include/asm/rtas.h +++ b/trunk/arch/powerpc/include/asm/rtas.h @@ -58,7 +58,7 @@ struct rtas_t { unsigned long entry; /* physical address pointer */ unsigned long base; /* physical address pointer */ unsigned long size; - raw_spinlock_t lock; + spinlock_t lock; struct rtas_args args; struct device_node *dev; /* virtual address pointer */ }; @@ -245,8 +245,5 @@ static inline u32 rtas_config_addr(int busno, int devfn, int reg) (devfn << 8) | (reg & 0xff); } -extern void __cpuinit rtas_give_timebase(void); -extern void __cpuinit rtas_take_timebase(void); - #endif /* __KERNEL__ */ #endif /* _POWERPC_RTAS_H */ diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index 3cadba60a4b6..4dd38f129153 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -191,49 +191,11 @@ transfer_to_handler_cont: mflr r9 lwz r11,0(r9) /* virtual address of handler */ lwz r9,4(r9) /* where to go when done */ -#ifdef CONFIG_TRACE_IRQFLAGS - lis r12,reenable_mmu@h - ori r12,r12,reenable_mmu@l - mtspr SPRN_SRR0,r12 - mtspr SPRN_SRR1,r10 - SYNC - RFI -reenable_mmu: /* re-enable mmu so we can */ - mfmsr r10 - lwz r12,_MSR(r1) - xor r10,r10,r12 - andi. r10,r10,MSR_EE /* Did EE change? */ - beq 1f - - /* Save handler and return address into the 2 unused words - * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything - * else can be recovered from the pt_regs except r3 which for - * normal interrupts has been set to pt_regs and for syscalls - * is an argument, so we temporarily use ORIG_GPR3 to save it - */ - stw r9,8(r1) - stw r11,12(r1) - stw r3,ORIG_GPR3(r1) - bl trace_hardirqs_off - lwz r0,GPR0(r1) - lwz r3,ORIG_GPR3(r1) - lwz r4,GPR4(r1) - lwz r5,GPR5(r1) - lwz r6,GPR6(r1) - lwz r7,GPR7(r1) - lwz r8,GPR8(r1) - lwz r9,8(r1) - lwz r11,12(r1) -1: mtctr r11 - mtlr r9 - bctr /* jump to handler */ -#else /* CONFIG_TRACE_IRQFLAGS */ mtspr SPRN_SRR0,r11 mtspr SPRN_SRR1,r10 mtlr r9 SYNC RFI /* jump to handler, enable MMU */ -#endif /* CONFIG_TRACE_IRQFLAGS */ #if defined (CONFIG_6xx) || defined(CONFIG_E500) 4: rlwinm r12,r12,0,~_TLF_NAPPING @@ -289,31 +251,6 @@ _GLOBAL(DoSyscall) #ifdef SHOW_SYSCALLS bl do_show_syscall #endif /* SHOW_SYSCALLS */ -#ifdef CONFIG_TRACE_IRQFLAGS - /* Return from syscalls can (and generally will) hard enable - * interrupts. You aren't supposed to call a syscall with - * interrupts disabled in the first place. However, to ensure - * that we get it right vs. lockdep if it happens, we force - * that hard enable here with appropriate tracing if we see - * that we have been called with interrupts off - */ - mfmsr r11 - andi. r12,r11,MSR_EE - bne+ 1f - /* We came in with interrupts disabled, we enable them now */ - bl trace_hardirqs_on - mfmsr r11 - lwz r0,GPR0(r1) - lwz r3,GPR3(r1) - lwz r4,GPR4(r1) - ori r11,r11,MSR_EE - lwz r5,GPR5(r1) - lwz r6,GPR6(r1) - lwz r7,GPR7(r1) - lwz r8,GPR8(r1) - mtmsr r11 -1: -#endif /* CONFIG_TRACE_IRQFLAGS */ rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ lwz r11,TI_FLAGS(r10) andi. r11,r11,_TIF_SYSCALL_T_OR_A @@ -338,7 +275,6 @@ ret_from_syscall: rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ /* disable interrupts so current_thread_info()->flags can't change */ LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ - /* Note: We don't bother telling lockdep about it */ SYNC MTMSRD(r10) lwz r9,TI_FLAGS(r12) @@ -352,19 +288,6 @@ ret_from_syscall: oris r11,r11,0x1000 /* Set SO bit in CR */ stw r11,_CCR(r1) syscall_exit_cont: - lwz r8,_MSR(r1) -#ifdef CONFIG_TRACE_IRQFLAGS - /* If we are going to return from the syscall with interrupts - * off, we trace that here. It shouldn't happen though but we - * want to catch the bugger if it does right ? - */ - andi. r10,r8,MSR_EE - bne+ 1f - stw r3,GPR3(r1) - bl trace_hardirqs_off - lwz r3,GPR3(r1) -1: -#endif /* CONFIG_TRACE_IRQFLAGS */ #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) /* If the process has its own DBCR0 value, load it up. The internal debug mode bit tells us that dbcr0 should be loaded. */ @@ -388,6 +311,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) mtlr r4 mtcr r5 lwz r7,_NIP(r1) + lwz r8,_MSR(r1) FIX_SRR1(r8, r0) lwz r2,GPR2(r1) lwz r1,GPR1(r1) @@ -470,9 +394,7 @@ syscall_exit_work: andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) beq ret_from_except - /* Re-enable interrupts. There is no need to trace that with - * lockdep as we are supposed to have IRQs on at this point - */ + /* Re-enable interrupts */ ori r10,r10,MSR_EE SYNC MTMSRD(r10) @@ -783,7 +705,6 @@ ret_from_except: /* Hard-disable interrupts so that current_thread_info()->flags * can't change between when we test it and when we return * from the interrupt. */ - /* Note: We don't bother telling lockdep about it */ LOAD_MSR_KERNEL(r10,MSR_KERNEL) SYNC /* Some chip revs have problems here... */ MTMSRD(r10) /* disable interrupts */ @@ -823,24 +744,11 @@ resume_kernel: beq+ restore andi. r0,r3,MSR_EE /* interrupts off? */ beq restore /* don't schedule if so */ -#ifdef CONFIG_TRACE_IRQFLAGS - /* Lockdep thinks irqs are enabled, we need to call - * preempt_schedule_irq with IRQs off, so we inform lockdep - * now that we -did- turn them off already - */ - bl trace_hardirqs_off -#endif 1: bl preempt_schedule_irq rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r3,TI_FLAGS(r9) andi. r0,r3,_TIF_NEED_RESCHED bne- 1b -#ifdef CONFIG_TRACE_IRQFLAGS - /* And now, to properly rebalance the above, we tell lockdep they - * are being turned back on, which will happen when we return - */ - bl trace_hardirqs_on -#endif #else resume_kernel: #endif /* CONFIG_PREEMPT */ @@ -857,28 +765,6 @@ restore: stw r6,icache_44x_need_flush@l(r4) 1: #endif /* CONFIG_44x */ - - lwz r9,_MSR(r1) -#ifdef CONFIG_TRACE_IRQFLAGS - /* Lockdep doesn't know about the fact that IRQs are temporarily turned - * off in this assembly code while peeking at TI_FLAGS() and such. However - * we need to inform it if the exception turned interrupts off, and we - * are about to trun them back on. - * - * The problem here sadly is that we don't know whether the exceptions was - * one that turned interrupts off or not. So we always tell lockdep about - * turning them on here when we go back to wherever we came from with EE - * on, even if that may meen some redudant calls being tracked. Maybe later - * we could encode what the exception did somewhere or test the exception - * type in the pt_regs but that sounds overkill - */ - andi. r10,r9,MSR_EE - beq 1f - bl trace_hardirqs_on - lwz r9,_MSR(r1) -1: -#endif /* CONFIG_TRACE_IRQFLAGS */ - lwz r0,GPR0(r1) lwz r2,GPR2(r1) REST_4GPRS(3, r1) @@ -896,6 +782,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) stwcx. r0,0,r1 /* to clear the reservation */ #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) + lwz r9,_MSR(r1) andi. r10,r9,MSR_RI /* check if this exception occurred */ beql nonrecoverable /* at a bad place (MSR:RI = 0) */ @@ -918,6 +805,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) MTMSRD(r10) /* clear the RI bit */ .globl exc_exit_restart exc_exit_restart: + lwz r9,_MSR(r1) lwz r12,_NIP(r1) FIX_SRR1(r9,r10) mtspr SPRN_SRR0,r12 @@ -1147,18 +1035,11 @@ do_work: /* r10 contains MSR_KERNEL here */ beq do_user_signal do_resched: /* r10 contains MSR_KERNEL here */ - /* Note: We don't need to inform lockdep that we are enabling - * interrupts here. As far as it knows, they are already enabled - */ ori r10,r10,MSR_EE SYNC MTMSRD(r10) /* hard-enable interrupts */ bl schedule recheck: - /* Note: And we don't tell it we are disabling them again - * neither. Those disable/enable cycles used to peek at - * TI_FLAGS aren't advertised. - */ LOAD_MSR_KERNEL(r10,MSR_KERNEL) SYNC MTMSRD(r10) /* disable interrupts */ diff --git a/trunk/arch/powerpc/kernel/head_32.S b/trunk/arch/powerpc/kernel/head_32.S index fc2132942754..48469463f89e 100644 --- a/trunk/arch/powerpc/kernel/head_32.S +++ b/trunk/arch/powerpc/kernel/head_32.S @@ -1124,8 +1124,9 @@ mmu_off: RFI /* - * On 601, we use 3 BATs to map up to 24M of RAM at _PAGE_OFFSET - * (we keep one for debugging) and on others, we use one 256M BAT. + * Use the first pair of BAT registers to map the 1st 16MB + * of RAM to PAGE_OFFSET. From this point on we can't safely + * call OF any more. */ initial_bats: lis r11,PAGE_OFFSET@h @@ -1135,16 +1136,12 @@ initial_bats: bne 4f ori r11,r11,4 /* set up BAT registers for 601 */ li r8,0x7f /* valid, block length = 8MB */ + oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */ + oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */ mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */ mtspr SPRN_IBAT0L,r8 /* lower BAT register */ - addis r11,r11,0x800000@h - addis r8,r8,0x800000@h - mtspr SPRN_IBAT1U,r11 - mtspr SPRN_IBAT1L,r8 - addis r11,r11,0x800000@h - addis r8,r8,0x800000@h - mtspr SPRN_IBAT2U,r11 - mtspr SPRN_IBAT2L,r8 + mtspr SPRN_IBAT1U,r9 + mtspr SPRN_IBAT1L,r10 isync blr diff --git a/trunk/arch/powerpc/kernel/of_device.c b/trunk/arch/powerpc/kernel/of_device.c index a359cb08e900..fa983a59c4ce 100644 --- a/trunk/arch/powerpc/kernel/of_device.c +++ b/trunk/arch/powerpc/kernel/of_device.c @@ -76,7 +76,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.archdata.of_node = np; if (bus_id) - dev_set_name(&dev->dev, "%s", bus_id); + dev_set_name(&dev->dev, bus_id); else of_device_make_bus_id(dev); diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 892a9f2e6d76..3e7135bbe40f 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -528,7 +528,7 @@ void show_regs(struct pt_regs * regs) for (i = 0; i < 32; i++) { if ((i % REGS_PER_LINE) == 0) - printk("\nGPR%02d: ", i); + printk("\n" KERN_INFO "GPR%02d: ", i); printk(REG " ", regs->gpr[i]); if (i == LAST_VOLATILE && !FULL_REGS(regs)) break; diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index c434823b8c83..ee4c7609b649 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -38,10 +38,9 @@ #include #include #include -#include struct rtas_t rtas = { - .lock = __RAW_SPIN_LOCK_UNLOCKED + .lock = SPIN_LOCK_UNLOCKED }; EXPORT_SYMBOL(rtas); @@ -68,28 +67,6 @@ unsigned long rtas_rmo_buf; void (*rtas_flash_term_hook)(int); EXPORT_SYMBOL(rtas_flash_term_hook); -/* RTAS use home made raw locking instead of spin_lock_irqsave - * because those can be called from within really nasty contexts - * such as having the timebase stopped which would lockup with - * normal locks and spinlock debugging enabled - */ -static unsigned long lock_rtas(void) -{ - unsigned long flags; - - local_irq_save(flags); - preempt_disable(); - __raw_spin_lock_flags(&rtas.lock, flags); - return flags; -} - -static void unlock_rtas(unsigned long flags) -{ - __raw_spin_unlock(&rtas.lock); - local_irq_restore(flags); - preempt_enable(); -} - /* * call_rtas_display_status and call_rtas_display_status_delay * are designed only for very early low-level debugging, which @@ -102,7 +79,7 @@ static void call_rtas_display_status(char c) if (!rtas.base) return; - s = lock_rtas(); + spin_lock_irqsave(&rtas.lock, s); args->token = 10; args->nargs = 1; @@ -112,7 +89,7 @@ static void call_rtas_display_status(char c) enter_rtas(__pa(args)); - unlock_rtas(s); + spin_unlock_irqrestore(&rtas.lock, s); } static void call_rtas_display_status_delay(char c) @@ -434,7 +411,8 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) return -1; - s = lock_rtas(); + /* Gotta do something different here, use global lock for now... */ + spin_lock_irqsave(&rtas.lock, s); rtas_args = &rtas.args; rtas_args->token = token; @@ -461,7 +439,8 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) outputs[i] = rtas_args->rets[i+1]; ret = (nret > 0)? rtas_args->rets[0]: 0; - unlock_rtas(s); + /* Gotta do something different here, use global lock for now... */ + spin_unlock_irqrestore(&rtas.lock, s); if (buff_copy) { log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0); @@ -858,7 +837,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) buff_copy = get_errorlog_buffer(); - flags = lock_rtas(); + spin_lock_irqsave(&rtas.lock, flags); rtas.args = args; enter_rtas(__pa(&rtas.args)); @@ -869,7 +848,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) if (args.rets[0] == -1) errbuf = __fetch_rtas_last_error(buff_copy); - unlock_rtas(flags); + spin_unlock_irqrestore(&rtas.lock, flags); if (buff_copy) { if (errbuf) @@ -972,33 +951,3 @@ int __init early_init_dt_scan_rtas(unsigned long node, /* break now */ return 1; } - -static raw_spinlock_t timebase_lock; -static u64 timebase = 0; - -void __cpuinit rtas_give_timebase(void) -{ - unsigned long flags; - - local_irq_save(flags); - hard_irq_disable(); - __raw_spin_lock(&timebase_lock); - rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); - timebase = get_tb(); - __raw_spin_unlock(&timebase_lock); - - while (timebase) - barrier(); - rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); - local_irq_restore(flags); -} - -void __cpuinit rtas_take_timebase(void) -{ - while (!timebase) - barrier(); - __raw_spin_lock(&timebase_lock); - set_tb(timebase >> 32, timebase & 0xffffffff); - timebase = 0; - __raw_spin_unlock(&timebase_lock); -} diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index e1e3059cf34b..1d154248cf40 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -119,8 +119,6 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) */ notrace void __init machine_init(unsigned long dt_ptr) { - lockdep_init(); - /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index 0b47de07302d..65484b2200b3 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -68,8 +68,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map); /* SMP operations for this machine */ struct smp_ops_t *smp_ops; -/* Can't be static due to PowerMac hackery */ -volatile unsigned int cpu_callin_map[NR_CPUS]; +static volatile unsigned int cpu_callin_map[NR_CPUS]; int smt_enabled_at_boot = 1; diff --git a/trunk/arch/powerpc/kernel/udbg_16550.c b/trunk/arch/powerpc/kernel/udbg_16550.c index acb74a17bbbf..0362a891e54e 100644 --- a/trunk/arch/powerpc/kernel/udbg_16550.c +++ b/trunk/arch/powerpc/kernel/udbg_16550.c @@ -219,7 +219,7 @@ void udbg_init_pas_realmode(void) #ifdef CONFIG_PPC_EARLY_DEBUG_44x #include -static void udbg_44x_as1_flush(void) +static int udbg_44x_as1_flush(void) { if (udbg_comport) { while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) diff --git a/trunk/arch/powerpc/mm/Makefile b/trunk/arch/powerpc/mm/Makefile index 3e68363405b7..2d2192e48de7 100644 --- a/trunk/arch/powerpc/mm/Makefile +++ b/trunk/arch/powerpc/mm/Makefile @@ -30,4 +30,3 @@ obj-$(CONFIG_PPC_MM_SLICES) += slice.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o -obj-$(CONFIG_HIGHMEM) += highmem.o diff --git a/trunk/arch/powerpc/mm/highmem.c b/trunk/arch/powerpc/mm/highmem.c deleted file mode 100644 index c2186c74c85a..000000000000 --- a/trunk/arch/powerpc/mm/highmem.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * highmem.c: virtual kernel memory mappings for high memory - * - * PowerPC version, stolen from the i386 version. - * - * Used in CONFIG_HIGHMEM systems for memory pages which - * are not addressable by direct kernel virtual addresses. - * - * Copyright (C) 1999 Gerhard Wichert, Siemens AG - * Gerhard.Wichert@pdb.siemens.de - * - * - * Redesigned the x86 32-bit VM architecture to deal with - * up to 16 Terrabyte physical memory. With current x86 CPUs - * we now support up to 64 Gigabytes physical RAM. - * - * Copyright (C) 1999 Ingo Molnar - * - * Reworked for PowerPC by various contributors. Moved from - * highmem.h by Benjamin Herrenschmidt (c) 2009 IBM Corp. - */ - -#include -#include - -/* - * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap - * gives a more generic (and caching) interface. But kmap_atomic can - * be used in IRQ contexts, so in some (very limited) cases we need - * it. - */ -void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) -{ - unsigned int idx; - unsigned long vaddr; - - /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - pagefault_disable(); - if (!PageHighMem(page)) - return page_address(page); - - debug_kmap_atomic(type); - idx = type + KM_TYPE_NR*smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); -#ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(*(kmap_pte-idx))); -#endif - __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1); - local_flush_tlb_page(NULL, vaddr); - - return (void*) vaddr; -} -EXPORT_SYMBOL(kmap_atomic_prot); - -void kunmap_atomic(void *kvaddr, enum km_type type) -{ -#ifdef CONFIG_DEBUG_HIGHMEM - unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; - enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); - - if (vaddr < __fix_to_virt(FIX_KMAP_END)) { - pagefault_enable(); - return; - } - - BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); - - /* - * force other mappings to Oops if they'll try to access - * this pte without first remap it - */ - pte_clear(&init_mm, vaddr, kmap_pte-idx); - local_flush_tlb_page(NULL, vaddr); -#endif - pagefault_enable(); -} -EXPORT_SYMBOL(kunmap_atomic); diff --git a/trunk/arch/powerpc/platforms/44x/warp.c b/trunk/arch/powerpc/platforms/44x/warp.c index 0362c88f47d7..42e09a9f77e2 100644 --- a/trunk/arch/powerpc/platforms/44x/warp.c +++ b/trunk/arch/powerpc/platforms/44x/warp.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -66,6 +65,7 @@ define_machine(warp) { static u32 post_info; +/* I am not sure this is the best place for this... */ static int __init warp_post_info(void) { struct device_node *np; @@ -194,9 +194,9 @@ static int pika_setup_leds(void) return 0; } -static void pika_setup_critical_temp(struct device_node *np, - struct i2c_client *client) +static void pika_setup_critical_temp(struct i2c_client *client) { + struct device_node *np; int irq, rc; /* Do this before enabling critical temp interrupt since we @@ -208,7 +208,14 @@ static void pika_setup_critical_temp(struct device_node *np, i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */ i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */ + np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); + if (np == NULL) { + printk(KERN_ERR __FILE__ ": Unable to find ad7414\n"); + return; + } + irq = irq_of_parse_and_map(np, 0); + of_node_put(np); if (irq == NO_IRQ) { printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n"); return; @@ -237,24 +244,32 @@ static inline void pika_dtm_check_fan(void __iomem *fpga) static int pika_dtm_thread(void __iomem *fpga) { - struct device_node *np; + struct i2c_adapter *adap; struct i2c_client *client; - np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); - if (np == NULL) - return -ENOENT; + /* We loop in case either driver was compiled as a module and + * has not been insmoded yet. + */ + while (!(adap = i2c_get_adapter(0))) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + } - client = of_find_i2c_device_by_node(np); - if (client == NULL) { - of_node_put(np); - return -ENOENT; + while (1) { + list_for_each_entry(client, &adap->clients, list) + if (client->addr == 0x4a) + goto found_it; + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); } - pika_setup_critical_temp(np, client); +found_it: + pika_setup_critical_temp(client); - of_node_put(np); + i2c_put_adapter(adap); - printk(KERN_INFO "Warp DTM thread running.\n"); + printk(KERN_INFO "PIKA DTM thread running.\n"); while (!kthread_should_stop()) { int val; @@ -276,6 +291,7 @@ static int pika_dtm_thread(void __iomem *fpga) return 0; } + static int __init pika_dtm_start(void) { struct task_struct *dtm_thread; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 60ed9c067b1d..77f90b356356 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -285,7 +285,6 @@ static struct of_device_id mpc85xx_ids[] = { { .type = "qe", }, { .compatible = "fsl,qe", }, { .compatible = "gianfar", }, - { .compatible = "fsl,rapidio-delta", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/smp.c b/trunk/arch/powerpc/platforms/85xx/smp.c index 62c592ede641..cc0b0db8a6f3 100644 --- a/trunk/arch/powerpc/platforms/85xx/smp.c +++ b/trunk/arch/powerpc/platforms/85xx/smp.c @@ -52,19 +52,20 @@ smp_85xx_kick_cpu(int nr) pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); + local_irq_save(flags); + np = of_get_cpu_node(nr, NULL); cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); if (cpu_rel_addr == NULL) { printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr); + local_irq_restore(flags); return; } /* Map the spin table */ bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); - local_irq_save(flags); - out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); @@ -72,10 +73,10 @@ smp_85xx_kick_cpu(int nr) while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) mdelay(1); - local_irq_restore(flags); - iounmap(bptr_vaddr); + local_irq_restore(flags); + pr_debug("waited %d msecs for CPU #%d.\n", n, nr); } diff --git a/trunk/arch/powerpc/platforms/85xx/socrates.c b/trunk/arch/powerpc/platforms/85xx/socrates.c index 747d8fb3ab82..d0e8443b12c6 100644 --- a/trunk/arch/powerpc/platforms/85xx/socrates.c +++ b/trunk/arch/powerpc/platforms/85xx/socrates.c @@ -102,11 +102,10 @@ static struct of_device_id __initdata socrates_of_bus_ids[] = { {}, }; -static int __init socrates_publish_devices(void) +static void __init socrates_init(void) { - return of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); + of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); } -machine_device_initcall(socrates, socrates_publish_devices); /* * Called very early, device-tree isn't unflattened @@ -125,6 +124,7 @@ define_machine(socrates) { .name = "Socrates", .probe = socrates_probe, .setup_arch = socrates_setup_arch, + .init = socrates_init, .init_IRQ = socrates_pic_init, .get_irq = mpic_get_irq, .restart = fsl_rstcr_restart, diff --git a/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c index 1b426050a2f9..ee01532786e4 100644 --- a/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c @@ -32,6 +32,7 @@ #include #include +#include /* A few bit definitions needed for fixups on some boards */ #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ diff --git a/trunk/arch/powerpc/platforms/cell/smp.c b/trunk/arch/powerpc/platforms/cell/smp.c index bc97fada48c6..9046803c8276 100644 --- a/trunk/arch/powerpc/platforms/cell/smp.c +++ b/trunk/arch/powerpc/platforms/cell/smp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -139,6 +140,31 @@ static void __devinit smp_cell_setup_cpu(int cpu) mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); } +static DEFINE_SPINLOCK(timebase_lock); +static unsigned long timebase = 0; + +static void __devinit cell_give_timebase(void) +{ + spin_lock(&timebase_lock); + rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); + timebase = get_tb(); + spin_unlock(&timebase_lock); + + while (timebase) + barrier(); + rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); +} + +static void __devinit cell_take_timebase(void) +{ + while (!timebase) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase >> 32, timebase & 0xffffffff); + timebase = 0; + spin_unlock(&timebase_lock); +} + static void __devinit smp_cell_kick_cpu(int nr) { BUG_ON(nr < 0 || nr >= NR_CPUS); @@ -198,8 +224,8 @@ void __init smp_init_cell(void) /* Non-lpar has additional take/give timebase */ if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { - smp_ops->give_timebase = rtas_give_timebase; - smp_ops->take_timebase = rtas_take_timebase; + smp_ops->give_timebase = cell_give_timebase; + smp_ops->take_timebase = cell_take_timebase; } DBG(" <- smp_init_cell()\n"); diff --git a/trunk/arch/powerpc/platforms/chrp/smp.c b/trunk/arch/powerpc/platforms/chrp/smp.c index 02cafecc90e3..10a4a4d063b6 100644 --- a/trunk/arch/powerpc/platforms/chrp/smp.c +++ b/trunk/arch/powerpc/platforms/chrp/smp.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -41,12 +42,40 @@ static void __devinit smp_chrp_setup_cpu(int cpu_nr) mpic_setup_this_cpu(); } +static DEFINE_SPINLOCK(timebase_lock); +static unsigned int timebase_upper = 0, timebase_lower = 0; + +void __devinit smp_chrp_give_timebase(void) +{ + spin_lock(&timebase_lock); + rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); + timebase_upper = get_tbu(); + timebase_lower = get_tbl(); + spin_unlock(&timebase_lock); + + while (timebase_upper || timebase_lower) + barrier(); + rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); +} + +void __devinit smp_chrp_take_timebase(void) +{ + while (!(timebase_upper || timebase_lower)) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase_upper, timebase_lower); + timebase_upper = 0; + timebase_lower = 0; + spin_unlock(&timebase_lock); + printk("CPU %i taken timebase\n", smp_processor_id()); +} + /* CHRP with openpic */ struct smp_ops_t chrp_smp_ops = { .message_pass = smp_mpic_message_pass, .probe = smp_mpic_probe, .kick_cpu = smp_chrp_kick_cpu, .setup_cpu = smp_chrp_setup_cpu, - .give_timebase = rtas_give_timebase, - .take_timebase = rtas_take_timebase, + .give_timebase = smp_chrp_give_timebase, + .take_timebase = smp_chrp_take_timebase, }; diff --git a/trunk/arch/powerpc/platforms/pasemi/setup.c b/trunk/arch/powerpc/platforms/pasemi/setup.c index a4619347aa7e..153051eb6d93 100644 --- a/trunk/arch/powerpc/platforms/pasemi/setup.c +++ b/trunk/arch/powerpc/platforms/pasemi/setup.c @@ -71,25 +71,20 @@ static void pas_restart(char *cmd) } #ifdef CONFIG_SMP -static raw_spinlock_t timebase_lock; +static DEFINE_SPINLOCK(timebase_lock); static unsigned long timebase; static void __devinit pas_give_timebase(void) { - unsigned long flags; - - local_irq_save(flags); - hard_irq_disable(); - __raw_spin_lock(&timebase_lock); + spin_lock(&timebase_lock); mtspr(SPRN_TBCTL, TBCTL_FREEZE); isync(); timebase = get_tb(); - __raw_spin_unlock(&timebase_lock); + spin_unlock(&timebase_lock); while (timebase) barrier(); mtspr(SPRN_TBCTL, TBCTL_RESTART); - local_irq_restore(flags); } static void __devinit pas_take_timebase(void) @@ -97,10 +92,10 @@ static void __devinit pas_take_timebase(void) while (!timebase) smp_rmb(); - __raw_spin_lock(&timebase_lock); + spin_lock(&timebase_lock); set_tb(timebase >> 32, timebase & 0xffffffff); timebase = 0; - __raw_spin_unlock(&timebase_lock); + spin_unlock(&timebase_lock); } struct smp_ops_t pas_smp_ops = { diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index c20522656367..86f69a4eb49b 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -103,6 +103,11 @@ unsigned long smu_cmdbuf_abs; EXPORT_SYMBOL(smu_cmdbuf_abs); #endif +#ifdef CONFIG_SMP +extern struct smp_ops_t psurge_smp_ops; +extern struct smp_ops_t core99_smp_ops; +#endif /* CONFIG_SMP */ + static void pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; @@ -336,6 +341,34 @@ static void __init pmac_setup_arch(void) ROOT_DEV = DEFAULT_ROOT_DEVICE; #endif +#ifdef CONFIG_SMP + /* Check for Core99 */ + ic = of_find_node_by_name(NULL, "uni-n"); + if (!ic) + ic = of_find_node_by_name(NULL, "u3"); + if (!ic) + ic = of_find_node_by_name(NULL, "u4"); + if (ic) { + of_node_put(ic); + smp_ops = &core99_smp_ops; + } +#ifdef CONFIG_PPC32 + else { + /* + * We have to set bits in cpu_possible_map here since the + * secondary CPU(s) aren't in the device tree, and + * setup_per_cpu_areas only allocates per-cpu data for + * CPUs in the cpu_possible_map. + */ + int cpu; + + for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu) + cpu_set(cpu, cpu_possible_map); + smp_ops = &psurge_smp_ops; + } +#endif +#endif /* CONFIG_SMP */ + #ifdef CONFIG_ADB if (strstr(cmd_line, "adb_sync")) { extern int __adb_probe_sync; @@ -479,14 +512,6 @@ static void __init pmac_init_early(void) #ifdef CONFIG_PPC64 iommu_init_early_dart(); #endif - - /* SMP Init has to be done early as we need to patch up - * cpu_possible_map before interrupt stacks are allocated - * or kaboom... - */ -#ifdef CONFIG_SMP - pmac_setup_smp(); -#endif } static int __init pmac_declare_of_platform_devices(void) diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index 6d4da7b46b41..cf1dbe758890 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -64,12 +64,11 @@ extern void __secondary_start_pmac_0(void); extern int pmac_pfunc_base_install(void); -static void (*pmac_tb_freeze)(int freeze); -static u64 timebase; -static int tb_req; - #ifdef CONFIG_PPC32 +/* Sync flag for HW tb sync */ +static volatile int sec_tb_reset = 0; + /* * Powersurge (old powermac SMP) support. */ @@ -295,9 +294,6 @@ static int __init smp_psurge_probe(void) psurge_quad_init(); /* All released cards using this HW design have 4 CPUs */ ncpus = 4; - /* No sure how timebase sync works on those, let's use SW */ - smp_ops->give_timebase = smp_generic_give_timebase; - smp_ops->take_timebase = smp_generic_take_timebase; } else { iounmap(quad_base); if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) { @@ -312,15 +308,18 @@ static int __init smp_psurge_probe(void) psurge_start = ioremap(PSURGE_START, 4); psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); - /* This is necessary because OF doesn't know about the + /* + * This is necessary because OF doesn't know about the * secondary cpu(s), and thus there aren't nodes in the * device tree for them, and smp_setup_cpu_maps hasn't - * set their bits in cpu_present_map. + * set their bits in cpu_possible_map and cpu_present_map. */ if (ncpus > NR_CPUS) ncpus = NR_CPUS; - for (i = 1; i < ncpus ; ++i) + for (i = 1; i < ncpus ; ++i) { cpu_set(i, cpu_present_map); + set_hard_smp_processor_id(i, i); + } if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); @@ -330,14 +329,8 @@ static int __init smp_psurge_probe(void) static void __init smp_psurge_kick_cpu(int nr) { unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; - unsigned long a, flags; - int i, j; - - /* Defining this here is evil ... but I prefer hiding that - * crap to avoid giving people ideas that they can do the - * same. - */ - extern volatile unsigned int cpu_callin_map[NR_CPUS]; + unsigned long a; + int i; /* may need to flush here if secondary bats aren't setup */ for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) @@ -346,52 +339,47 @@ static void __init smp_psurge_kick_cpu(int nr) if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353); - /* This is going to freeze the timeebase, we disable interrupts */ - local_irq_save(flags); - out_be32(psurge_start, start); mb(); psurge_set_ipi(nr); - /* * We can't use udelay here because the timebase is now frozen. */ for (i = 0; i < 2000; ++i) - asm volatile("nop" : : : "memory"); + barrier(); psurge_clr_ipi(nr); - /* - * Also, because the timebase is frozen, we must not return to the - * caller which will try to do udelay's etc... Instead, we wait -here- - * for the CPU to callin. - */ - for (i = 0; i < 100000 && !cpu_callin_map[nr]; ++i) { - for (j = 1; j < 10000; j++) - asm volatile("nop" : : : "memory"); - asm volatile("sync" : : : "memory"); - } - if (!cpu_callin_map[nr]) - goto stuck; - - /* And we do the TB sync here too for standard dual CPU cards */ - if (psurge_type == PSURGE_DUAL) { - while(!tb_req) - barrier(); - tb_req = 0; - mb(); - timebase = get_tb(); - mb(); - while (timebase) - barrier(); + if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); +} + +/* + * With the dual-cpu powersurge board, the decrementers and timebases + * of both cpus are frozen after the secondary cpu is started up, + * until we give the secondary cpu another interrupt. This routine + * uses this to get the timebases synchronized. + * -- paulus. + */ +static void __init psurge_dual_sync_tb(int cpu_nr) +{ + int t; + + set_dec(tb_ticks_per_jiffy); + /* XXX fixme */ + set_tb(0, 0); + + if (cpu_nr > 0) { mb(); + sec_tb_reset = 1; + return; } - stuck: - /* now interrupt the secondary, restarting both TBs */ - if (psurge_type == PSURGE_DUAL) - psurge_set_ipi(1); - if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); + /* wait for the secondary to have reset its TB before proceeding */ + for (t = 10000000; t > 0 && !sec_tb_reset; --t) + ; + + /* now interrupt the secondary, starting both TBs */ + psurge_set_ipi(1); } static struct irqaction psurge_irqaction = { @@ -402,35 +390,36 @@ static struct irqaction psurge_irqaction = { static void __init smp_psurge_setup_cpu(int cpu_nr) { - if (cpu_nr != 0) - return; - /* reset the entry point so if we get another intr we won't - * try to startup again */ - out_be32(psurge_start, 0x100); - if (setup_irq(30, &psurge_irqaction)) - printk(KERN_ERR "Couldn't get primary IPI interrupt"); + if (cpu_nr == 0) { + /* If we failed to start the second CPU, we should still + * send it an IPI to start the timebase & DEC or we might + * have them stuck. + */ + if (num_online_cpus() < 2) { + if (psurge_type == PSURGE_DUAL) + psurge_set_ipi(1); + return; + } + /* reset the entry point so if we get another intr we won't + * try to startup again */ + out_be32(psurge_start, 0x100); + if (setup_irq(30, &psurge_irqaction)) + printk(KERN_ERR "Couldn't get primary IPI interrupt"); + } + + if (psurge_type == PSURGE_DUAL) + psurge_dual_sync_tb(cpu_nr); } void __init smp_psurge_take_timebase(void) { - if (psurge_type != PSURGE_DUAL) - return; - - tb_req = 1; - mb(); - while (!timebase) - barrier(); - mb(); - set_tb(timebase >> 32, timebase & 0xffffffff); - timebase = 0; - mb(); - set_dec(tb_ticks_per_jiffy/2); + /* Dummy implementation */ } void __init smp_psurge_give_timebase(void) { - /* Nothing to do here */ + /* Dummy implementation */ } /* PowerSurge-style Macs */ @@ -448,6 +437,9 @@ struct smp_ops_t psurge_smp_ops = { * Core 99 and later support */ +static void (*pmac_tb_freeze)(int freeze); +static u64 timebase; +static int tb_req; static void smp_core99_give_timebase(void) { @@ -486,6 +478,7 @@ static void __devinit smp_core99_take_timebase(void) set_tb(timebase >> 32, timebase & 0xffffffff); timebase = 0; mb(); + set_dec(tb_ticks_per_jiffy/2); local_irq_restore(flags); } @@ -927,34 +920,3 @@ struct smp_ops_t core99_smp_ops = { # endif #endif }; - -void __init pmac_setup_smp(void) -{ - struct device_node *np; - - /* Check for Core99 */ - np = of_find_node_by_name(NULL, "uni-n"); - if (!np) - np = of_find_node_by_name(NULL, "u3"); - if (!np) - np = of_find_node_by_name(NULL, "u4"); - if (np) { - of_node_put(np); - smp_ops = &core99_smp_ops; - } -#ifdef CONFIG_PPC32 - else { - /* We have to set bits in cpu_possible_map here since the - * secondary CPU(s) aren't in the device tree. Various - * things won't be initialized for CPUs not in the possible - * map, so we really need to fix it up here. - */ - int cpu; - - for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu) - cpu_set(cpu, cpu_possible_map); - smp_ops = &psurge_smp_ops; - } -#endif /* CONFIG_PPC32 */ -} - diff --git a/trunk/arch/powerpc/platforms/pseries/smp.c b/trunk/arch/powerpc/platforms/pseries/smp.c index 1f8f6cfb94f7..1a231c389ba0 100644 --- a/trunk/arch/powerpc/platforms/pseries/smp.c +++ b/trunk/arch/powerpc/platforms/pseries/smp.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +118,31 @@ static void __devinit smp_xics_setup_cpu(int cpu) } #endif /* CONFIG_XICS */ +static DEFINE_SPINLOCK(timebase_lock); +static unsigned long timebase = 0; + +static void __devinit pSeries_give_timebase(void) +{ + spin_lock(&timebase_lock); + rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); + timebase = get_tb(); + spin_unlock(&timebase_lock); + + while (timebase) + barrier(); + rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); +} + +static void __devinit pSeries_take_timebase(void) +{ + while (!timebase) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase >> 32, timebase & 0xffffffff); + timebase = 0; + spin_unlock(&timebase_lock); +} + static void __devinit smp_pSeries_kick_cpu(int nr) { BUG_ON(nr < 0 || nr >= NR_CPUS); @@ -183,8 +209,8 @@ static void __init smp_init_pseries(void) /* Non-lpar has additional take/give timebase */ if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { - smp_ops->give_timebase = rtas_give_timebase; - smp_ops->take_timebase = rtas_take_timebase; + smp_ops->give_timebase = pSeries_give_timebase; + smp_ops->take_timebase = pSeries_take_timebase; } pr_debug(" <- smp_init_pSeries()\n"); diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index d46de1f0f3ee..9c3af5045495 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -279,29 +279,28 @@ static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr, } #ifdef CONFIG_PPC_DCR -static void _mpic_map_dcr(struct mpic *mpic, struct device_node *node, - struct mpic_reg_bank *rb, +static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, unsigned int offset, unsigned int size) { const u32 *dbasep; - dbasep = of_get_property(node, "dcr-reg", NULL); + dbasep = of_get_property(mpic->irqhost->of_node, "dcr-reg", NULL); - rb->dhost = dcr_map(node, *dbasep + offset, size); + rb->dhost = dcr_map(mpic->irqhost->of_node, *dbasep + offset, size); BUG_ON(!DCR_MAP_OK(rb->dhost)); } -static inline void mpic_map(struct mpic *mpic, struct device_node *node, - phys_addr_t phys_addr, struct mpic_reg_bank *rb, - unsigned int offset, unsigned int size) +static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr, + struct mpic_reg_bank *rb, unsigned int offset, + unsigned int size) { if (mpic->flags & MPIC_USES_DCR) - _mpic_map_dcr(mpic, node, rb, offset, size); + _mpic_map_dcr(mpic, rb, offset, size); else _mpic_map_mmio(mpic, phys_addr, rb, offset, size); } #else /* CONFIG_PPC_DCR */ -#define mpic_map(m,n,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) +#define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) #endif /* !CONFIG_PPC_DCR */ @@ -1053,10 +1052,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, int intvec_top; u64 paddr = phys_addr; - mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL); + mpic = alloc_bootmem(sizeof(struct mpic)); if (mpic == NULL) return NULL; - + + memset(mpic, 0, sizeof(struct mpic)); mpic->name = name; mpic->hc_irq = mpic_irq_chip; @@ -1152,8 +1152,8 @@ struct mpic * __init mpic_alloc(struct device_node *node, } /* Map the global registers */ - mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); - mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); + mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); + mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); /* Reset */ if (flags & MPIC_WANTS_RESET) { @@ -1194,7 +1194,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { - mpic_map(mpic, node, paddr, &mpic->cpuregs[i], + mpic_map(mpic, paddr, &mpic->cpuregs[i], MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), 0x1000); } @@ -1202,7 +1202,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Initialize main ISU if none provided */ if (mpic->isu_size == 0) { mpic->isu_size = mpic->num_sources; - mpic_map(mpic, node, paddr, &mpic->isus[0], + mpic_map(mpic, paddr, &mpic->isus[0], MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); } mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); @@ -1256,10 +1256,8 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, BUG_ON(isu_num >= MPIC_MAX_ISU); - mpic_map(mpic, mpic->irqhost->of_node, - paddr, &mpic->isus[isu_num], 0, + mpic_map(mpic, paddr, &mpic->isus[isu_num], 0, MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); - if ((isu_first + mpic->isu_size) > mpic->num_sources) mpic->num_sources = isu_first + mpic->isu_size; } diff --git a/trunk/arch/powerpc/sysdev/qe_lib/qe.c b/trunk/arch/powerpc/sysdev/qe_lib/qe.c index 237e3654f48c..b28b0e512d67 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/qe.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/qe.c @@ -112,7 +112,6 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) { unsigned long flags; u8 mcn_shift = 0, dev_shift = 0; - u32 ret; spin_lock_irqsave(&qe_lock, flags); if (cmd == QE_RESET) { @@ -140,13 +139,11 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) } /* wait for the QE_CR_FLG to clear */ - ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0, - 100, 0); - /* On timeout (e.g. failure), the expression will be false (ret == 0), - otherwise it will be true (ret == 1). */ + while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) + cpu_relax(); spin_unlock_irqrestore(&qe_lock, flags); - return ret == 1; + return 0; } EXPORT_SYMBOL(qe_issue_cmd); diff --git a/trunk/arch/s390/include/asm/kvm_host.h b/trunk/arch/s390/include/asm/kvm_host.h index 1cd02f6073a0..a27d0d5a6f86 100644 --- a/trunk/arch/s390/include/asm/kvm_host.h +++ b/trunk/arch/s390/include/asm/kvm_host.h @@ -99,9 +99,7 @@ struct kvm_s390_sie_block { __u8 reservedd0[48]; /* 0x00d0 */ __u64 gcr[16]; /* 0x0100 */ __u64 gbea; /* 0x0180 */ - __u8 reserved188[24]; /* 0x0188 */ - __u32 fac; /* 0x01a0 */ - __u8 reserved1a4[92]; /* 0x01a4 */ + __u8 reserved188[120]; /* 0x0188 */ } __attribute__((packed)); struct kvm_vcpu_stat { diff --git a/trunk/arch/s390/kvm/kvm-s390.c b/trunk/arch/s390/kvm/kvm-s390.c index 90d9d1ba258b..c18b21d6991c 100644 --- a/trunk/arch/s390/kvm/kvm-s390.c +++ b/trunk/arch/s390/kvm/kvm-s390.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "kvm-s390.h" #include "gaccess.h" @@ -70,7 +69,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { NULL } }; -static unsigned long long *facilities; /* Section: not file related */ void kvm_arch_hardware_enable(void *garbage) @@ -290,7 +288,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin; vcpu->arch.sie_block->ecb = 2; vcpu->arch.sie_block->eca = 0xC1002001U; - vcpu->arch.sie_block->fac = (int) (long) facilities; hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, (unsigned long) vcpu); @@ -742,29 +739,11 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) static int __init kvm_s390_init(void) { - int ret; - ret = kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); - if (ret) - return ret; - - /* - * guests can ask for up to 255+1 double words, we need a full page - * to hold the maximum amount of facilites. On the other hand, we - * only set facilities that are known to work in KVM. - */ - facilities = (unsigned long long *) get_zeroed_page(GFP_DMA); - if (!facilities) { - kvm_exit(); - return -ENOMEM; - } - stfle(facilities, 1); - facilities[0] &= 0xff00fff3f0700000ULL; - return 0; + return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); } static void __exit kvm_s390_exit(void) { - free_page((unsigned long) facilities); kvm_exit(); } diff --git a/trunk/arch/s390/kvm/priv.c b/trunk/arch/s390/kvm/priv.c index d426aac8095d..93ecd06e1a74 100644 --- a/trunk/arch/s390/kvm/priv.c +++ b/trunk/arch/s390/kvm/priv.c @@ -158,7 +158,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) vcpu->stat.instruction_stfl++; /* only pass the facility bits, which we can handle */ - facility_list &= 0xff00fff3; + facility_list &= 0xfe00fff3; rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), &facility_list, sizeof(facility_list)); diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index e2bdd7b94fd9..ac1c620d1c7d 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -15,7 +15,7 @@ config SUPERH select HAVE_IOREMAP_PROT if MMU select HAVE_ARCH_TRACEHOOK select HAVE_DMA_API_DEBUG - select HAVE_PERF_COUNTERS + select HAVE_PERF_COUNTER select RTC_LIB select GENERIC_ATOMIC64 help @@ -71,9 +71,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ config GENERIC_IRQ_PROBE def_bool y -config IRQ_PER_CPU - def_bool y - config GENERIC_GPIO def_bool n @@ -154,9 +151,6 @@ config ARCH_NO_VIRT_TO_BUS config ARCH_HAS_DEFAULT_IDLE def_bool y -config ARCH_HAS_CPU_IDLE_WAIT - def_bool y - config IO_TRAPPED bool @@ -417,8 +411,6 @@ config CPU_SUBTYPE_SH7786 select CPU_HAS_PTEAEX select ARCH_SPARSEMEM_ENABLE select SYS_SUPPORTS_NUMA - select SYS_SUPPORTS_SMP - select GENERIC_CLOCKEVENTS_BROADCAST if SMP config CPU_SUBTYPE_SHX3 bool "Support SH-X3 processor" @@ -656,7 +648,7 @@ config NR_CPUS int "Maximum number of CPUs (2-32)" range 2 32 depends on SMP - default "4" if CPU_SUBTYPE_SHX3 + default "4" if CPU_SHX3 default "2" help This allows you to specify the maximum number of CPUs which this diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug index 39224b57c6ef..8ece0b5bd028 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -61,6 +61,10 @@ config EARLY_PRINTK select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using the kernel command line option to toggle back and forth. +config DEBUG_BOOTMEM + depends on DEBUG_KERNEL + bool "Debug BOOTMEM initialization" + config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL && SUPERH32 diff --git a/trunk/arch/sh/boards/mach-se/7206/io.c b/trunk/arch/sh/boards/mach-se/7206/io.c index 180455642a43..9c3a33210d61 100644 --- a/trunk/arch/sh/boards/mach-se/7206/io.c +++ b/trunk/arch/sh/boards/mach-se/7206/io.c @@ -50,7 +50,7 @@ unsigned char se7206_inb_p(unsigned long port) unsigned short se7206_inw(unsigned long port) { - return *port2adr(port); + return *port2adr(port);; } void se7206_outb(unsigned char value, unsigned long port) diff --git a/trunk/arch/sh/boards/mach-se/7724/setup.c b/trunk/arch/sh/boards/mach-se/7724/setup.c index c050a8d76dfd..9cd04bd558b8 100644 --- a/trunk/arch/sh/boards/mach-se/7724/setup.c +++ b/trunk/arch/sh/boards/mach-se/7724/setup.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include #include @@ -274,34 +272,6 @@ static struct platform_device keysc_device = { }, }; -/* SH Eth */ -static struct resource sh_eth_resources[] = { - [0] = { - .start = SH_ETH_ADDR, - .end = SH_ETH_ADDR + 0x1FC, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 91, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -struct sh_eth_plat_data sh_eth_plat = { - .phy = 0x1f, /* SMSC LAN8187 */ - .edmac_endian = EDMAC_LITTLE_ENDIAN, -}; - -static struct platform_device sh_eth_device = { - .name = "sh-eth", - .id = 0, - .dev = { - .platform_data = &sh_eth_plat, - }, - .num_resources = ARRAY_SIZE(sh_eth_resources), - .resource = sh_eth_resources, -}; - static struct platform_device *ms7724se_devices[] __initdata = { &heartbeat_device, &smc91x_eth_device, @@ -310,57 +280,8 @@ static struct platform_device *ms7724se_devices[] __initdata = { &ceu0_device, &ceu1_device, &keysc_device, - &sh_eth_device, }; -#define EEPROM_OP 0xBA206000 -#define EEPROM_ADR 0xBA206004 -#define EEPROM_DATA 0xBA20600C -#define EEPROM_STAT 0xBA206010 -#define EEPROM_STRT 0xBA206014 -static int __init sh_eth_is_eeprom_ready(void) -{ - int t = 10000; - - while (t--) { - if (!ctrl_inw(EEPROM_STAT)) - return 1; - cpu_relax(); - } - - printk(KERN_ERR "ms7724se can not access to eeprom\n"); - return 0; -} - -static void __init sh_eth_init(void) -{ - int i; - u16 mac[3]; - - /* check EEPROM status */ - if (!sh_eth_is_eeprom_ready()) - return; - - /* read MAC addr from EEPROM */ - for (i = 0 ; i < 3 ; i++) { - ctrl_outw(0x0, EEPROM_OP); /* read */ - ctrl_outw(i*2, EEPROM_ADR); - ctrl_outw(0x1, EEPROM_STRT); - if (!sh_eth_is_eeprom_ready()) - return; - - mac[i] = ctrl_inw(EEPROM_DATA); - mac[i] = ((mac[i] & 0xFF) << 8) | (mac[i] >> 8); /* swap */ - } - - /* reset sh-eth */ - ctrl_outl(0x1, SH_ETH_ADDR + 0x0); - - /* set MAC addr */ - ctrl_outl(((mac[0] << 16) | (mac[1])), SH_ETH_MAHR); - ctrl_outl((mac[2]), SH_ETH_MALR); -} - #define SW4140 0xBA201000 #define FPGA_OUT 0xBA200400 #define PORT_HIZA 0xA4050158 @@ -381,8 +302,7 @@ static int __init devices_setup(void) ctrl_outw(ctrl_inw(FPGA_OUT) & ~((1 << 1) | /* LAN */ (1 << 6) | /* VIDEO DAC */ - (1 << 12) | /* USB0 */ - (1 << 14)), /* RMII */ + (1 << 12)), /* USB0 */ FPGA_OUT); /* enable IRQ 0,1,2 */ @@ -454,7 +374,7 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_VIO0_CLK, NULL); gpio_request(GPIO_FN_VIO0_FLD, NULL); gpio_request(GPIO_FN_VIO0_HD, NULL); - platform_resource_setup_memory(&ceu0_device, "ceu0", 4 << 20); + platform_resource_setup_memory(&ceu0_device, "ceu", 4 << 20); /* enable CEU1 */ gpio_request(GPIO_FN_VIO1_D7, NULL); @@ -469,7 +389,7 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_VIO1_HD, NULL); gpio_request(GPIO_FN_VIO1_VD, NULL); gpio_request(GPIO_FN_VIO1_CLK, NULL); - platform_resource_setup_memory(&ceu1_device, "ceu1", 4 << 20); + platform_resource_setup_memory(&ceu1_device, "ceu", 4 << 20); /* KEYSC */ gpio_request(GPIO_FN_KEYOUT5_IN5, NULL); @@ -484,28 +404,6 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_KEYOUT1, NULL); gpio_request(GPIO_FN_KEYOUT0, NULL); - /* - * enable SH-Eth - * - * please remove J33 pin from your board !! - * - * ms7724 board should not use GPIO_FN_LNKSTA pin - * So, This time PTX5 is set to input pin - */ - gpio_request(GPIO_FN_RMII_RXD0, NULL); - gpio_request(GPIO_FN_RMII_RXD1, NULL); - gpio_request(GPIO_FN_RMII_TXD0, NULL); - gpio_request(GPIO_FN_RMII_TXD1, NULL); - gpio_request(GPIO_FN_RMII_REF_CLK, NULL); - gpio_request(GPIO_FN_RMII_TX_EN, NULL); - gpio_request(GPIO_FN_RMII_RX_ER, NULL); - gpio_request(GPIO_FN_RMII_CRS_DV, NULL); - gpio_request(GPIO_FN_MDIO, NULL); - gpio_request(GPIO_FN_MDC, NULL); - gpio_request(GPIO_PTX5, NULL); - gpio_direction_input(GPIO_PTX5); - sh_eth_init(); - if (sw & SW41_B) { /* SVGA */ lcdc_info.ch[0].lcd_cfg.xres = 800; @@ -539,7 +437,7 @@ static int __init devices_setup(void) } return platform_add_devices(ms7724se_devices, - ARRAY_SIZE(ms7724se_devices)); + ARRAY_SIZE(ms7724se_devices)); } device_initcall(devices_setup); diff --git a/trunk/arch/sh/configs/migor_defconfig b/trunk/arch/sh/configs/migor_defconfig index b18cfd39cac6..da627d22c009 100644 --- a/trunk/arch/sh/configs/migor_defconfig +++ b/trunk/arch/sh/configs/migor_defconfig @@ -309,7 +309,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 earlyprintk=serial ip=on root=/dev/nfs ip=dhcp" +CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=serial ip=on root=/dev/nfs ip=dhcp" # # Bus options @@ -858,35 +858,7 @@ CONFIG_VIDEO_SH_MOBILE_CEU=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -CONFIG_FB_SYS_FILLRECT=y -CONFIG_FB_SYS_COPYAREA=y -CONFIG_FB_SYS_IMAGEBLIT=y -# CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=y -CONFIG_FB_DEFERRED_IO=y -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_SH_MOBILE_LCDC=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -898,27 +870,6 @@ CONFIG_FB_SH_MOBILE_LCDC=y # Console display driver support # CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FONTS=y -# CONFIG_FONT_8x8 is not set -# CONFIG_FONT_8x16 is not set -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -CONFIG_FONT_MINI_4x6=y -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -CONFIG_LOGO_SUPERH_VGA16=y -# CONFIG_LOGO_SUPERH_CLUT224 is not set # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y diff --git a/trunk/arch/sh/configs/se7724_defconfig b/trunk/arch/sh/configs/se7724_defconfig index 3ee783a0a075..3840270283e4 100644 --- a/trunk/arch/sh/configs/se7724_defconfig +++ b/trunk/arch/sh/configs/se7724_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.30 -# Mon Jun 29 16:28:43 2009 +# Thu Jun 18 16:09:05 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -14,7 +14,6 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_IRQ_PER_CPU=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -29,9 +28,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y -CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y # # General setup @@ -91,12 +88,10 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y -CONFIG_HAVE_PERF_COUNTERS=y # # Performance Counters # -# CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y # CONFIG_STRIP_ASM_SYMS is not set CONFIG_COMPAT_BRK=y @@ -112,10 +107,6 @@ CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y - -# -# GCOV-based kernel profiling -# # CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y @@ -128,7 +119,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y -CONFIG_LBDAF=y +# CONFIG_LBD is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -593,6 +584,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_BNX2_ISCSI is not set # CONFIG_LIBFC is not set # CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set @@ -632,7 +624,7 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_AX88796 is not set # CONFIG_STNIC is not set -CONFIG_SH_ETH=y +# CONFIG_SH_ETH is not set CONFIG_SMC91X=y # CONFIG_ENC28J60 is not set # CONFIG_ETHOC is not set @@ -809,11 +801,6 @@ CONFIG_SPI_BITBANG=y # # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set - -# -# PPS support -# -# CONFIG_PPS is not set CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_GPIO_SYSFS is not set @@ -864,8 +851,6 @@ CONFIG_SSB_POSSIBLE=y # 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_EZX_PCAP is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -1211,7 +1196,6 @@ CONFIG_RTC_DRV_PCF8563=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1276,7 +1260,6 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set CONFIG_FILE_LOCKING=y diff --git a/trunk/arch/sh/include/asm/dma-mapping.h b/trunk/arch/sh/include/asm/dma-mapping.h index 69d56dd4c968..ea9d4f41c9d2 100644 --- a/trunk/arch/sh/include/asm/dma-mapping.h +++ b/trunk/arch/sh/include/asm/dma-mapping.h @@ -97,7 +97,7 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, dma_unmap_single(dev, dma_address, size, dir); } -static inline void __dma_sync_single(struct device *dev, dma_addr_t dma_handle, +static inline void dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) @@ -119,7 +119,7 @@ static inline void dma_sync_single_range(struct device *dev, dma_cache_sync(dev, phys_to_virt(dma_handle) + offset, size, dir); } -static inline void __dma_sync_sg(struct device *dev, struct scatterlist *sg, +static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction dir) { int i; @@ -137,7 +137,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { - __dma_sync_single(dev, dma_handle, size, dir); + dma_sync_single(dev, dma_handle, size, dir); debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir); } @@ -146,7 +146,7 @@ static inline void dma_sync_single_for_device(struct device *dev, size_t size, enum dma_data_direction dir) { - __dma_sync_single(dev, dma_handle, size, dir); + dma_sync_single(dev, dma_handle, size, dir); debug_dma_sync_single_for_device(dev, dma_handle, size, dir); } @@ -177,7 +177,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction dir) { - __dma_sync_sg(dev, sg, nelems, dir); + dma_sync_sg(dev, sg, nelems, dir); debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir); } @@ -185,7 +185,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction dir) { - __dma_sync_sg(dev, sg, nelems, dir); + dma_sync_sg(dev, sg, nelems, dir); debug_dma_sync_sg_for_device(dev, sg, nelems, dir); } diff --git a/trunk/arch/sh/include/asm/perf_counter.h b/trunk/arch/sh/include/asm/perf_counter.h index 61c2b40c802c..a8153c2aa6fa 100644 --- a/trunk/arch/sh/include/asm/perf_counter.h +++ b/trunk/arch/sh/include/asm/perf_counter.h @@ -2,6 +2,6 @@ #define __ASM_SH_PERF_COUNTER_H /* SH only supports software counters through this interface. */ -static inline void set_perf_counter_pending(void) {} +#define set_perf_counter_pending() do { } while (0) #endif /* __ASM_SH_PERF_COUNTER_H */ diff --git a/trunk/arch/sh/include/asm/syscall_32.h b/trunk/arch/sh/include/asm/syscall_32.h index 6f83f2cc45c1..5bc34681d994 100644 --- a/trunk/arch/sh/include/asm/syscall_32.h +++ b/trunk/arch/sh/include/asm/syscall_32.h @@ -3,7 +3,6 @@ #include #include -#include #include /* The system call number is given by the user in R3 */ diff --git a/trunk/arch/sh/include/asm/system.h b/trunk/arch/sh/include/asm/system.h index ab79e1f4fbe0..a88895e6dcb0 100644 --- a/trunk/arch/sh/include/asm/system.h +++ b/trunk/arch/sh/include/asm/system.h @@ -154,7 +154,6 @@ extern struct dentry *sh_debugfs_root; void per_cpu_trap_init(void); void default_idle(void); -void cpu_idle_wait(void); asmlinkage void break_point_trap(void); diff --git a/trunk/arch/sh/include/mach-se/mach/se7724.h b/trunk/arch/sh/include/mach-se/mach/se7724.h index 29514a39d0f5..74164b60d0db 100644 --- a/trunk/arch/sh/include/mach-se/mach/se7724.h +++ b/trunk/arch/sh/include/mach-se/mach/se7724.h @@ -20,11 +20,6 @@ */ #include -/* SH Eth */ -#define SH_ETH_ADDR (0xA4600000) -#define SH_ETH_MAHR (SH_ETH_ADDR + 0x1C0) -#define SH_ETH_MALR (SH_ETH_ADDR + 0x1C8) - #define PA_LED (0xba203000) /* 8bit LED */ #define IRQ_MODE (0xba200010) #define IRQ0_SR (0xba200014) diff --git a/trunk/arch/sh/kernel/cpu/sh4a/Makefile b/trunk/arch/sh/kernel/cpu/sh4a/Makefile index ebdd391d5f42..96ea09ca8cc1 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh4a/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o # SMP setup -smp-$(CONFIG_CPU_SHX3) := smp-shx3.o +smp-$(CONFIG_CPU_SUBTYPE_SHX3) := smp-shx3.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SUBTYPE_SH7763) := clock-sh7763.o @@ -38,6 +38,6 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7724) := pinmux-sh7724.o pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o -obj-y += $(clock-y) -obj-$(CONFIG_SMP) += $(smp-y) +obj-y += $(clock-y) +obj-$(CONFIG_SMP) += $(smp-y) obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y) diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index b70049470a0b..93e0d2c017e8 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -595,8 +595,9 @@ enum { HSPI, GPIO0, GPIO1, Thermal, - INTICI0, INTICI1, INTICI2, INTICI3, - INTICI4, INTICI5, INTICI6, INTICI7, + INTC0, INTC1, INTC2, INTC3, INTC4, INTC5, INTC6, INTC7, + + /* interrupt groups */ }; static struct intc_vect vectors[] __initdata = { @@ -637,12 +638,10 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(HSPI, 0xe80), INTC_VECT(GPIO0, 0xea0), INTC_VECT(GPIO1, 0xec0), INTC_VECT(Thermal, 0xee0), - INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20), - INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60), - INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0), - INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0), }; +/* FIXME: Main CPU support only now */ +#if 1 /* Main CPU */ #define CnINTMSK0 0xfe410030 #define CnINTMSK1 0xfe410040 #define CnINTMSKCLR0 0xfe410050 @@ -655,6 +654,21 @@ static struct intc_vect vectors[] __initdata = { #define CnINT2MSKCR1 0xfe410a34 #define CnINT2MSKCR2 0xfe410a38 #define CnINT2MSKCR3 0xfe410a3c +#else /* Sub CPU */ +#define CnINTMSK0 0xfe410034 +#define CnINTMSK1 0xfe410044 +#define CnINTMSKCLR0 0xfe410054 +#define CnINTMSKCLR1 0xfe410064 +#define CnINT2MSKR0 0xfe410b20 +#define CnINT2MSKR1 0xfe410b24 +#define CnINT2MSKR2 0xfe410b28 +#define CnINT2MSKR3 0xfe410b2c +#define CnINT2MSKCR0 0xfe410b30 +#define CnINT2MSKCR1 0xfe410b34 +#define CnINT2MSKCR2 0xfe410b38 +#define CnINT2MSKCR3 0xfe410b3c +#endif + #define INTMSK2 0xfe410068 #define INTMSKCLR2 0xfe41006c @@ -739,9 +753,6 @@ static struct intc_prio_reg prio_registers[] __initdata = { GPIO1, Thermal } }, { 0xfe41085c, 0, 32, 8, /* INT2PRI23 */ { 0, 0, 0, 0 } }, { 0xfe410860, 0, 32, 8, /* INT2PRI24 */ { 0, 0, 0, 0 } }, - { 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */ - { INTICI7, INTICI6, INTICI5, INTICI4, - INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 2) }, }; static DECLARE_INTC_DESC(intc_desc, "sh7786", vectors, NULL, diff --git a/trunk/arch/sh/kernel/idle.c b/trunk/arch/sh/kernel/idle.c index 27ff2dc093c7..f35ed0348850 100644 --- a/trunk/arch/sh/kernel/idle.c +++ b/trunk/arch/sh/kernel/idle.c @@ -1,7 +1,7 @@ /* * The idle loop for all SuperH platforms. * - * Copyright (C) 2002 - 2009 Paul Mundt + * Copyright (C) 2002 - 2008 Paul Mundt * * 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 @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -80,23 +79,3 @@ void cpu_idle(void) check_pgt_cache(); } } - -static void do_nothing(void *unused) -{ -} - -/* - * cpu_idle_wait - Used to ensure that all the CPUs discard old value of - * pm_idle and update to new pm_idle value. Required while changing pm_idle - * handler on SMP systems. - * - * Caller must have changed pm_idle to the new value before the call. Old - * pm_idle value will not be used by any CPU after the return of this function. - */ -void cpu_idle_wait(void) -{ - smp_mb(); - /* kick all the CPUs so that they exit out of pm_idle */ - smp_call_function(do_nothing, NULL, 1); -} -EXPORT_SYMBOL_GPL(cpu_idle_wait); diff --git a/trunk/arch/sh/mm/fault_32.c b/trunk/arch/sh/mm/fault_32.c index 71925946f1e1..cc8ddbdf3d7a 100644 --- a/trunk/arch/sh/mm/fault_32.c +++ b/trunk/arch/sh/mm/fault_32.c @@ -15,28 +15,12 @@ #include #include #include -#include +#include #include #include #include #include -static inline int notify_page_fault(struct pt_regs *regs, int trap) -{ - int ret = 0; - -#ifdef CONFIG_KPROBES - if (!user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, trap)) - ret = 1; - preempt_enable(); - } -#endif - - return ret; -} - /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -103,16 +87,13 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, return; } - mm = tsk->mm; - - if (unlikely(notify_page_fault(regs, lookup_exception_vector()))) - return; - /* Only enable interrupts if they were on before the fault */ - if ((regs->sr & SR_IMASK) != SR_IMASK) + if ((regs->sr & SR_IMASK) != SR_IMASK) { + trace_hardirqs_on(); local_irq_enable(); + } - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); + mm = tsk->mm; /* * If we're in an interrupt or have no user @@ -160,15 +141,10 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto do_sigbus; BUG(); } - if (fault & VM_FAULT_MAJOR) { + if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, - regs, address); - } else { + else tsk->min_flt++; - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, - regs, address); - } up_read(&mm->mmap_sem); return; @@ -269,6 +245,22 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto no_context; } +static inline int notify_page_fault(struct pt_regs *regs, int trap) +{ + int ret = 0; + +#ifdef CONFIG_KPROBES + if (!user_mode(regs)) { + preempt_disable(); + if (kprobe_running() && kprobe_fault_handler(regs, trap)) + ret = 1; + preempt_enable(); + } +#endif + + return ret; +} + /* * Called with interrupts disabled. */ @@ -281,7 +273,12 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, pmd_t *pmd; pte_t *pte; pte_t entry; - int ret = 1; + int ret = 0; + + if (notify_page_fault(regs, lookup_exception_vector())) + goto out; + + ret = 1; /* * We don't take page faults for P1, P2, and parts of P4, these diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index fe532aeaa16d..ee8e6bbe882c 100644 --- a/trunk/arch/sh/mm/init.c +++ b/trunk/arch/sh/mm/init.c @@ -70,7 +70,7 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) } set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); - local_flush_tlb_one(get_asid(), addr); + flush_tlb_one(get_asid(), addr); } /* @@ -177,8 +177,10 @@ void __init paging_init(void) free_area_init_nodes(max_zone_pfns); +#ifdef CONFIG_SUPERH32 /* Set up the uncached fixmap */ set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start)); +#endif } static struct kcore_list kcore_mem, kcore_vmalloc; diff --git a/trunk/arch/sh/mm/tlbflush_64.c b/trunk/arch/sh/mm/tlbflush_64.c index 3ce40ea34824..fcbb6e135cef 100644 --- a/trunk/arch/sh/mm/tlbflush_64.c +++ b/trunk/arch/sh/mm/tlbflush_64.c @@ -3,7 +3,7 @@ * * Copyright (C) 2000, 2001 Paolo Alberelli * Copyright (C) 2003 Richard Curnow (/proc/tlb, bug fixes) - * Copyright (C) 2003 - 2009 Paul Mundt + * Copyright (C) 2003 Paul Mundt * * 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 @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -116,8 +115,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, /* Not an IO address, so reenable interrupts */ local_irq_enable(); - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); - /* * If we're in an interrupt or have no user * context, we must not take the fault.. @@ -198,16 +195,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, goto do_sigbus; BUG(); } - - if (fault & VM_FAULT_MAJOR) { + if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, - regs, address); - } else { + else tsk->min_flt++; - perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, - regs, address); - } /* If we get here, the page fault has been handled. Do the TLB refill now from the newly-setup PTE, to avoid having to fault again right diff --git a/trunk/arch/sparc/boot/Makefile b/trunk/arch/sparc/boot/Makefile index 1ff0fd924756..96041a8d39e8 100644 --- a/trunk/arch/sparc/boot/Makefile +++ b/trunk/arch/sparc/boot/Makefile @@ -15,7 +15,7 @@ quiet_cmd_elftoaout = ELFTOAOUT $@ ifeq ($(CONFIG_SPARC32),y) quiet_cmd_piggy = PIGGY $@ - cmd_piggy = $(obj)/piggyback_32 $@ System.map $(ROOT_IMG) + cmd_piggy = $(obj)/piggyback_32 $@ $(obj)/System.map $(ROOT_IMG) quiet_cmd_btfix = BTFIX $@ cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ quiet_cmd_sysmap = SYSMAP $(obj)/System.map @@ -58,7 +58,7 @@ $(obj)/image: $(obj)/btfix.o FORCE $(obj)/zImage: $(obj)/image $(call if_changed,strip) -$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_32 System.map $(ROOT_IMG) FORCE +$(obj)/tftpboot.img: $(obj)/piggyback $(obj)/System.map $(obj)/image FORCE $(call if_changed,elftoaout) $(call if_changed,piggy) @@ -79,7 +79,7 @@ $(obj)/image: vmlinux FORCE $(call if_changed,strip) @echo ' kernel: $@ is ready' -$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE +$(obj)/tftpboot.img: vmlinux $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE $(call if_changed,elftoaout) $(call if_changed,piggy) @echo ' kernel: $@ is ready' diff --git a/trunk/arch/sparc/boot/piggyback_32.c b/trunk/arch/sparc/boot/piggyback_32.c index e8dc9adfcd61..c9f500c1a8b2 100644 --- a/trunk/arch/sparc/boot/piggyback_32.c +++ b/trunk/arch/sparc/boot/piggyback_32.c @@ -70,7 +70,7 @@ void die(char *str) int main(int argc,char **argv) { static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 }; - char buffer[1024], *q, *r; + unsigned char buffer[1024], *q, *r; unsigned int i, j, k, start, end, offset; FILE *map; struct stat s; @@ -84,7 +84,7 @@ int main(int argc,char **argv) while (fgets (buffer, 1024, map)) { if (!strcmp (buffer + 8, " T start\n") || !strcmp (buffer + 16, " T start\n")) start = strtoul (buffer, NULL, 16); - else if (!strcmp (buffer + 8, " A _end\n") || !strcmp (buffer + 16, " A _end\n")) + else if (!strcmp (buffer + 8, " A end\n") || !strcmp (buffer + 16, " A end\n")) end = strtoul (buffer, NULL, 16); } fclose (map); diff --git a/trunk/arch/sparc/boot/piggyback_64.c b/trunk/arch/sparc/boot/piggyback_64.c index c63fd1b6bdd4..de364bfed0bb 100644 --- a/trunk/arch/sparc/boot/piggyback_64.c +++ b/trunk/arch/sparc/boot/piggyback_64.c @@ -46,7 +46,6 @@ int main(int argc,char **argv) struct stat s; int image, tail; - start = end = 0; if (stat (argv[3], &s) < 0) die (argv[3]); map = fopen (argv[2], "r"); if (!map) die(argv[2]); diff --git a/trunk/arch/sparc/kernel/irq_64.c b/trunk/arch/sparc/kernel/irq_64.c index f0ee79055409..bd075054942b 100644 --- a/trunk/arch/sparc/kernel/irq_64.c +++ b/trunk/arch/sparc/kernel/irq_64.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -913,19 +914,25 @@ void __cpuinit notrace sun4v_register_mondo_queues(int this_cpu) tb->nonresum_qmask); } -/* Each queue region must be a power of 2 multiple of 64 bytes in - * size. The base real address must be aligned to the size of the - * region. Thus, an 8KB queue must be 8KB aligned, for example. - */ -static void __init alloc_one_queue(unsigned long *pa_ptr, unsigned long qmask) +static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) +{ + unsigned long size = PAGE_ALIGN(qmask + 1); + void *p = __alloc_bootmem(size, size, 0); + if (!p) { + prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); + prom_halt(); + } + + *pa_ptr = __pa(p); +} + +static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) { unsigned long size = PAGE_ALIGN(qmask + 1); - unsigned long order = get_order(size); - unsigned long p; + void *p = __alloc_bootmem(size, size, 0); - p = __get_free_pages(GFP_KERNEL, order); if (!p) { - prom_printf("SUN4V: Error, cannot allocate queue.\n"); + prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); prom_halt(); } @@ -935,11 +942,11 @@ static void __init alloc_one_queue(unsigned long *pa_ptr, unsigned long qmask) static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb) { #ifdef CONFIG_SMP - unsigned long page; + void *page; BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); - page = get_zeroed_page(GFP_KERNEL); + page = alloc_bootmem_pages(PAGE_SIZE); if (!page) { prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); prom_halt(); @@ -958,13 +965,13 @@ static void __init sun4v_init_mondo_queues(void) for_each_possible_cpu(cpu) { struct trap_per_cpu *tb = &trap_block[cpu]; - alloc_one_queue(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask); - alloc_one_queue(&tb->dev_mondo_pa, tb->dev_mondo_qmask); - alloc_one_queue(&tb->resum_mondo_pa, tb->resum_qmask); - alloc_one_queue(&tb->resum_kernel_buf_pa, tb->resum_qmask); - alloc_one_queue(&tb->nonresum_mondo_pa, tb->nonresum_qmask); - alloc_one_queue(&tb->nonresum_kernel_buf_pa, - tb->nonresum_qmask); + alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask); + alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask); + alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask); + alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask); + alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask); + alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, + tb->nonresum_qmask); } } @@ -992,7 +999,7 @@ void __init init_IRQ(void) kill_prom_timer(); size = sizeof(struct ino_bucket) * NUM_IVECS; - ivector_table = kzalloc(size, GFP_KERNEL); + ivector_table = alloc_bootmem(size); if (!ivector_table) { prom_printf("Fatal error, cannot allocate ivector_table\n"); prom_halt(); diff --git a/trunk/arch/um/drivers/slip_kern.c b/trunk/arch/um/drivers/slip_kern.c index dd2aadc14af0..5ec17563142e 100644 --- a/trunk/arch/um/drivers/slip_kern.c +++ b/trunk/arch/um/drivers/slip_kern.c @@ -30,6 +30,7 @@ static void slip_init(struct net_device *dev, void *data) slip_proto_init(&spri->slip); + dev->init = NULL; dev->hard_header_len = 0; dev->header_ops = NULL; dev->addr_len = 0; diff --git a/trunk/arch/um/drivers/slirp_kern.c b/trunk/arch/um/drivers/slirp_kern.c index e376284f0fb7..f15a6e7654f3 100644 --- a/trunk/arch/um/drivers/slirp_kern.c +++ b/trunk/arch/um/drivers/slirp_kern.c @@ -32,6 +32,7 @@ void slirp_init(struct net_device *dev, void *data) slip_proto_init(&spri->slip); + dev->init = NULL; dev->hard_header_len = 0; dev->header_ops = NULL; dev->addr_len = 0; diff --git a/trunk/arch/um/include/asm/dma-mapping.h b/trunk/arch/um/include/asm/dma-mapping.h index 378de4bbf49f..90fc708b320e 100644 --- a/trunk/arch/um/include/asm/dma-mapping.h +++ b/trunk/arch/um/include/asm/dma-mapping.h @@ -79,14 +79,14 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, } static inline void -dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, +dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { BUG(); } static inline void -dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, +dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction) { BUG(); diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index c07f72205909..d1430ef6b4f9 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1913,14 +1913,25 @@ config DMAR_DEFAULT_ON recommended you say N here while the DMAR code remains experimental. +config DMAR_GFX_WA + def_bool y + prompt "Support for Graphics workaround" + depends on DMAR + ---help--- + Current Graphics drivers tend to use physical address + for DMA and avoid using DMA APIs. Setting this config + option permits the IOMMU driver to set a unity map for + all the OS-visible memory. Hence the driver can continue + to use physical addresses for DMA. + config DMAR_FLOPPY_WA def_bool y depends on DMAR ---help--- - Floppy disk drivers are known to bypass DMA API calls + Floppy disk drivers are know to bypass DMA API calls thereby failing to work when IOMMU is enabled. This workaround will setup a 1:1 mapping for the first - 16MiB to make floppy (an ISA device) work. + 16M to make floppy (an ISA device) work. config INTR_REMAP bool "Support for Interrupt Remapping (EXPERIMENTAL)" diff --git a/trunk/arch/x86/include/asm/acpi.h b/trunk/arch/x86/include/asm/acpi.h index 20d1465a2ab0..4518dc500903 100644 --- a/trunk/arch/x86/include/asm/acpi.h +++ b/trunk/arch/x86/include/asm/acpi.h @@ -144,7 +144,6 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate) #else /* !CONFIG_ACPI */ -#define acpi_disabled 1 #define acpi_lapic 0 #define acpi_ioapic 0 static inline void acpi_noirq_set(void) { } diff --git a/trunk/arch/x86/include/asm/boot.h b/trunk/arch/x86/include/asm/boot.h index 7a1065958ba9..418e632d4a80 100644 --- a/trunk/arch/x86/include/asm/boot.h +++ b/trunk/arch/x86/include/asm/boot.h @@ -8,7 +8,7 @@ #ifdef __KERNEL__ -#include +#include /* Physical address where kernel should be loaded. */ #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ @@ -16,10 +16,10 @@ & ~(CONFIG_PHYSICAL_ALIGN - 1)) /* Minimum kernel alignment, as a power of two */ -#ifdef CONFIG_X86_64 +#ifdef CONFIG_x86_64 #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT #else -#define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT + THREAD_ORDER) +#define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT+1) #endif #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2) diff --git a/trunk/arch/x86/include/asm/pci.h b/trunk/arch/x86/include/asm/pci.h index 1ff685ca221c..927958d13c19 100644 --- a/trunk/arch/x86/include/asm/pci.h +++ b/trunk/arch/x86/include/asm/pci.h @@ -91,7 +91,7 @@ extern void pci_iommu_alloc(void); #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) -#if defined(CONFIG_X86_64) || defined(CONFIG_DMAR) || defined(CONFIG_DMA_API_DEBUG) +#if defined(CONFIG_X86_64) || defined(CONFIG_DMA_API_DEBUG) #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ dma_addr_t ADDR_NAME; diff --git a/trunk/arch/x86/include/asm/pci_x86.h b/trunk/arch/x86/include/asm/pci_x86.h index b399988eee3a..cb739cc0a080 100644 --- a/trunk/arch/x86/include/asm/pci_x86.h +++ b/trunk/arch/x86/include/asm/pci_x86.h @@ -25,7 +25,7 @@ #define PCI_BIOS_IRQ_SCAN 0x2000 #define PCI_ASSIGN_ALL_BUSSES 0x4000 #define PCI_CAN_SKIP_ISA_ALIGN 0x8000 -#define PCI_USE__CRS 0x10000 +#define PCI_NO_ROOT_CRS 0x10000 #define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000 #define PCI_HAS_IO_ECS 0x40000 #define PCI_NOASSIGN_ROMS 0x80000 @@ -121,9 +121,6 @@ extern int __init pcibios_init(void); extern int __init pci_mmcfg_arch_init(void); extern void __init pci_mmcfg_arch_free(void); -extern struct acpi_mcfg_allocation *pci_mmcfg_config; -extern int pci_mmcfg_config_num; - /* * AMD Fam10h CPUs are buggy, and cannot access MMIO config space * on their northbrige except through the * %eax register. As such, you MUST diff --git a/trunk/arch/x86/include/asm/percpu.h b/trunk/arch/x86/include/asm/percpu.h index 103f1ddb0d85..02ecb30982a3 100644 --- a/trunk/arch/x86/include/asm/percpu.h +++ b/trunk/arch/x86/include/asm/percpu.h @@ -42,7 +42,6 @@ #else /* ...!ASSEMBLY */ -#include #include #ifdef CONFIG_SMP @@ -156,15 +155,6 @@ do { \ /* We can use this directly for local CPU (faster). */ DECLARE_PER_CPU(unsigned long, this_cpu_off); -#ifdef CONFIG_NEED_MULTIPLE_NODES -void *pcpu_lpage_remapped(void *kaddr); -#else -static inline void *pcpu_lpage_remapped(void *kaddr) -{ - return NULL; -} -#endif - #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_SMP diff --git a/trunk/arch/x86/include/asm/perf_counter.h b/trunk/arch/x86/include/asm/perf_counter.h index fa64e401589d..5fb33e160ea0 100644 --- a/trunk/arch/x86/include/asm/perf_counter.h +++ b/trunk/arch/x86/include/asm/perf_counter.h @@ -87,9 +87,6 @@ union cpuid10_edx { #ifdef CONFIG_PERF_COUNTERS extern void init_hw_perf_counters(void); extern void perf_counters_lapic_init(void); - -#define PERF_COUNTER_INDEX_OFFSET 0 - #else static inline void init_hw_perf_counters(void) { } static inline void perf_counters_lapic_init(void) { } diff --git a/trunk/arch/x86/include/asm/proto.h b/trunk/arch/x86/include/asm/proto.h index 621f56d73121..49fb3ecf3bb3 100644 --- a/trunk/arch/x86/include/asm/proto.h +++ b/trunk/arch/x86/include/asm/proto.h @@ -22,14 +22,7 @@ extern int reboot_force; long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); -/* - * This looks more complex than it should be. But we need to - * get the type for the ~ right in round_down (it needs to be - * as wide as the result!), and we want to evaluate the macro - * arguments just once each. - */ -#define __round_mask(x,y) ((__typeof__(x))((y)-1)) -#define round_up(x,y) ((((x)-1) | __round_mask(x,y))+1) -#define round_down(x,y) ((x) & ~__round_mask(x,y)) +#define round_up(x, y) (((x) + (y) - 1) & ~((y) - 1)) +#define round_down(x, y) ((x) & ~((y) - 1)) #endif /* _ASM_X86_PROTO_H */ diff --git a/trunk/arch/x86/kernel/acpi/boot.c b/trunk/arch/x86/kernel/acpi/boot.c index 6b8ca3a0285d..631086159c53 100644 --- a/trunk/arch/x86/kernel/acpi/boot.c +++ b/trunk/arch/x86/kernel/acpi/boot.c @@ -44,7 +44,11 @@ static int __initdata acpi_force = 0; u32 acpi_rsdt_forced; -int acpi_disabled; +#ifdef CONFIG_ACPI +int acpi_disabled = 0; +#else +int acpi_disabled = 1; +#endif EXPORT_SYMBOL(acpi_disabled); #ifdef CONFIG_X86_64 @@ -118,6 +122,72 @@ void __init __acpi_unmap_table(char *map, unsigned long size) early_iounmap(map, size); } +#ifdef CONFIG_PCI_MMCONFIG + +static int acpi_mcfg_64bit_base_addr __initdata = FALSE; + +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +struct acpi_mcfg_allocation *pci_mmcfg_config; +int pci_mmcfg_config_num; + +static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg) +{ + if (!strcmp(mcfg->header.oem_id, "SGI")) + acpi_mcfg_64bit_base_addr = TRUE; + + return 0; +} + +int __init acpi_parse_mcfg(struct acpi_table_header *header) +{ + struct acpi_table_mcfg *mcfg; + unsigned long i; + int config_size; + + if (!header) + return -EINVAL; + + mcfg = (struct acpi_table_mcfg *)header; + + /* how many config structures do we have */ + pci_mmcfg_config_num = 0; + i = header->length - sizeof(struct acpi_table_mcfg); + while (i >= sizeof(struct acpi_mcfg_allocation)) { + ++pci_mmcfg_config_num; + i -= sizeof(struct acpi_mcfg_allocation); + }; + if (pci_mmcfg_config_num == 0) { + printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); + return -ENODEV; + } + + config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); + pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); + if (!pci_mmcfg_config) { + printk(KERN_WARNING PREFIX + "No memory for MCFG config tables\n"); + return -ENOMEM; + } + + memcpy(pci_mmcfg_config, &mcfg[1], config_size); + + acpi_mcfg_oem_check(mcfg); + + for (i = 0; i < pci_mmcfg_config_num; ++i) { + if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) && + !acpi_mcfg_64bit_base_addr) { + printk(KERN_ERR PREFIX + "MMCONFIG not in low 4GB of memory\n"); + kfree(pci_mmcfg_config); + pci_mmcfg_config_num = 0; + return -ENODEV; + } + } + + return 0; +} +#endif /* CONFIG_PCI_MMCONFIG */ + #ifdef CONFIG_X86_LOCAL_APIC static int __init acpi_parse_madt(struct acpi_table_header *table) { @@ -1447,6 +1517,14 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), }, }, + { + .callback = force_acpi_ht, + .ident = "ASUS P4B266", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "P4B266"), + }, + }, { .callback = force_acpi_ht, .ident = "ASUS P2B-DS", diff --git a/trunk/arch/x86/kernel/acpi/cstate.c b/trunk/arch/x86/kernel/acpi/cstate.c index 8c44c232efcb..bbbe4bbb6f34 100644 --- a/trunk/arch/x86/kernel/acpi/cstate.c +++ b/trunk/arch/x86/kernel/acpi/cstate.c @@ -34,22 +34,12 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, flags->bm_check = 1; else if (c->x86_vendor == X86_VENDOR_INTEL) { /* - * Today all MP CPUs that support C3 share cache. - * And caches should not be flushed by software while - * entering C3 type state. + * Today all CPUs that support C3 share cache. + * TBD: This needs to look at cache shared map, once + * multi-core detection patch makes to the base. */ flags->bm_check = 1; } - - /* - * On all recent Intel platforms, ARB_DISABLE is a nop. - * So, set bm_control to zero to indicate that ARB_DISABLE - * is not required while entering C3 type state on - * P4, Core and beyond CPUs - */ - if (c->x86_vendor == X86_VENDOR_INTEL && - (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 14))) - flags->bm_control = 0; } EXPORT_SYMBOL(acpi_processor_power_init_bm_check); diff --git a/trunk/arch/x86/kernel/acpi/processor.c b/trunk/arch/x86/kernel/acpi/processor.c index d296f4a195c9..7c074eec39fb 100644 --- a/trunk/arch/x86/kernel/acpi/processor.c +++ b/trunk/arch/x86/kernel/acpi/processor.c @@ -72,7 +72,6 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) return; } - /* Initialize _PDC data based on the CPU vendor */ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) { @@ -86,15 +85,3 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) } EXPORT_SYMBOL(arch_acpi_processor_init_pdc); - -void arch_acpi_processor_cleanup_pdc(struct acpi_processor *pr) -{ - if (pr->pdc) { - kfree(pr->pdc->pointer->buffer.pointer); - kfree(pr->pdc->pointer); - kfree(pr->pdc); - pr->pdc = NULL; - } -} - -EXPORT_SYMBOL(arch_acpi_processor_cleanup_pdc); diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c index 4d0216fcb36c..b7a79207295e 100644 --- a/trunk/arch/x86/kernel/apic/io_apic.c +++ b/trunk/arch/x86/kernel/apic/io_apic.c @@ -1414,9 +1414,6 @@ int setup_ioapic_entry(int apic_id, int irq, irte.vector = vector; irte.dest_id = IRTE_DEST(destination); - /* Set source-id of interrupt request */ - set_ioapic_sid(&irte, apic_id); - modify_irte(irq, &irte); ir_entry->index2 = (index >> 15) & 0x1; @@ -3293,9 +3290,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms irte.vector = cfg->vector; irte.dest_id = IRTE_DEST(dest); - /* Set source-id of interrupt request */ - set_msi_sid(&irte, pdev); - modify_irte(irq, &irte); msg->address_hi = MSI_ADDR_BASE_HI; diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 28e5f5956042..e5b27d8f1b47 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -258,15 +258,13 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_HT unsigned bits; - int cpu = smp_processor_id(); bits = c->x86_coreid_bits; + /* Low order bits define the core id (index of core in socket) */ c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); /* Convert the initial APIC ID into the socket ID */ c->phys_proc_id = c->initial_apicid >> bits; - /* use socket ID also for last level cache */ - per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; #endif } diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index f1961c07af9a..6b26d4deada0 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -848,6 +848,9 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) numa_add_cpu(smp_processor_id()); #endif + + /* Cap the iomem address space to what is addressable on all CPUs */ + iomem_resource.end &= (1ULL << c->x86_phys_bits) - 1; } #ifdef CONFIG_X86_64 diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce.c b/trunk/arch/x86/kernel/cpu/mcheck/mce.c index af425b83202b..284d1de968bc 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce.c @@ -1117,7 +1117,7 @@ static void mcheck_timer(unsigned long data) *n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ)); t->expires = jiffies + *n; - add_timer_on(t, smp_processor_id()); + add_timer(t); } static void mce_do_trigger(struct work_struct *work) @@ -1321,7 +1321,7 @@ static void mce_init_timer(void) return; setup_timer(t, mcheck_timer, smp_processor_id()); t->expires = round_jiffies(jiffies + *n); - add_timer_on(t, smp_processor_id()); + add_timer(t); } /* diff --git a/trunk/arch/x86/kernel/cpu/perf_counter.c b/trunk/arch/x86/kernel/cpu/perf_counter.c index d4cf4ce19aac..76dfef23f789 100644 --- a/trunk/arch/x86/kernel/cpu/perf_counter.c +++ b/trunk/arch/x86/kernel/cpu/perf_counter.c @@ -401,7 +401,7 @@ static const u64 amd_hw_cache_event_ids [ C(RESULT_MISS) ] = 0x0041, /* Data Cache Misses */ }, [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */ + [ C(RESULT_ACCESS) ] = 0x0042, /* Data Cache Refills from L2 */ [ C(RESULT_MISS) ] = 0, }, [ C(OP_PREFETCH) ] = { @@ -912,8 +912,6 @@ x86_perf_counter_set_period(struct perf_counter *counter, err = checking_wrmsrl(hwc->counter_base + idx, (u64)(-left) & x86_pmu.counter_mask); - perf_counter_update_userpage(counter); - return ret; } @@ -971,6 +969,13 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) if (!x86_pmu.num_counters_fixed) return -1; + /* + * Quirk, IA32_FIXED_CTRs do not work on current Atom processors: + */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && + boot_cpu_data.x86_model == 28) + return -1; + event = hwc->config & ARCH_PERFMON_EVENT_MASK; if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS))) @@ -1036,8 +1041,6 @@ static int x86_pmu_enable(struct perf_counter *counter) x86_perf_counter_set_period(counter, hwc, idx); x86_pmu.enable(hwc, idx); - perf_counter_update_userpage(counter); - return 0; } @@ -1130,8 +1133,6 @@ static void x86_pmu_disable(struct perf_counter *counter) x86_perf_counter_update(counter, hwc, idx); cpuc->counters[idx] = NULL; clear_bit(idx, cpuc->used_mask); - - perf_counter_update_userpage(counter); } /* @@ -1427,6 +1428,8 @@ static int intel_pmu_init(void) */ x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); + /* * Install the hw-cache-events table: */ @@ -1496,22 +1499,21 @@ void __init init_hw_perf_counters(void) pr_cont("%s PMU driver.\n", x86_pmu.name); if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { + x86_pmu.num_counters = X86_PMC_MAX_GENERIC; WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", x86_pmu.num_counters, X86_PMC_MAX_GENERIC); - x86_pmu.num_counters = X86_PMC_MAX_GENERIC; } perf_counter_mask = (1 << x86_pmu.num_counters) - 1; perf_max_counters = x86_pmu.num_counters; if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { + x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED); - x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; } perf_counter_mask |= ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; - x86_pmu.intel_ctrl = perf_counter_mask; perf_counters_lapic_init(); register_die_notifier(&perf_counter_nmi_notifier); diff --git a/trunk/arch/x86/kernel/dumpstack.c b/trunk/arch/x86/kernel/dumpstack.c index c8405718a4c3..95ea5fa7d444 100644 --- a/trunk/arch/x86/kernel/dumpstack.c +++ b/trunk/arch/x86/kernel/dumpstack.c @@ -22,7 +22,6 @@ #include "dumpstack.h" int panic_on_unrecovered_nmi; -int panic_on_io_nmi; unsigned int code_bytes = 64; int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; static int die_counter; diff --git a/trunk/arch/x86/kernel/e820.c b/trunk/arch/x86/kernel/e820.c index c4ca89d9aaf4..7271fa33d791 100644 --- a/trunk/arch/x86/kernel/e820.c +++ b/trunk/arch/x86/kernel/e820.c @@ -1383,8 +1383,6 @@ static unsigned long ram_alignment(resource_size_t pos) return 32*1024*1024; } -#define MAX_RESOURCE_SIZE ((resource_size_t)-1) - void __init e820_reserve_resources_late(void) { int i; @@ -1402,19 +1400,17 @@ void __init e820_reserve_resources_late(void) * avoid stolen RAM: */ for (i = 0; i < e820.nr_map; i++) { - struct e820entry *entry = &e820.map[i]; - u64 start, end; + struct e820entry *entry = &e820_saved.map[i]; + resource_size_t start, end; if (entry->type != E820_RAM) continue; start = entry->addr + entry->size; - end = round_up(start, ram_alignment(start)) - 1; - if (end > MAX_RESOURCE_SIZE) - end = MAX_RESOURCE_SIZE; - if (start >= end) + end = round_up(start, ram_alignment(start)); + if (start == end) continue; - reserve_region_with_split(&iomem_resource, start, end, - "RAM buffer"); + reserve_region_with_split(&iomem_resource, start, + end - 1, "RAM buffer"); } } diff --git a/trunk/arch/x86/kernel/pci-dma.c b/trunk/arch/x86/kernel/pci-dma.c index 1a041bcf506b..47630479b067 100644 --- a/trunk/arch/x86/kernel/pci-dma.c +++ b/trunk/arch/x86/kernel/pci-dma.c @@ -211,11 +211,11 @@ static __init int iommu_setup(char *p) #ifdef CONFIG_SWIOTLB if (!strncmp(p, "soft", 4)) swiotlb = 1; -#endif if (!strncmp(p, "pt", 2)) { iommu_pass_through = 1; return 1; } +#endif gart_parse_options(p); diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index de2cab132844..be5ae80f897f 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -289,20 +289,6 @@ void * __init extend_brk(size_t size, size_t align) return ret; } -#ifdef CONFIG_X86_64 -static void __init init_gbpages(void) -{ - if (direct_gbpages && cpu_has_gbpages) - printk(KERN_INFO "Using GB pages for direct mapping\n"); - else - direct_gbpages = 0; -} -#else -static inline void init_gbpages(void) -{ -} -#endif - static void __init reserve_brk(void) { if (_brk_end > _brk_start) @@ -885,8 +871,6 @@ void __init setup_arch(char **cmdline_p) reserve_brk(); - init_gbpages(); - /* max_pfn_mapped is updated here */ max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<= pcpul_size) + if (off >= pcpur_size) return NULL; - return virt_to_page(pcpul_map[cpu].ptr + off); + return virt_to_page(pcpur_ptrs[cpu] + off); } -static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) +static ssize_t __init setup_pcpu_remap(size_t static_size) { - size_t map_size, dyn_size; + static struct vm_struct vm; + size_t ptrs_size, dyn_size; unsigned int cpu; - int i, j; ssize_t ret; - if (!chosen) { - size_t vm_size = VMALLOC_END - VMALLOC_START; - size_t tot_size = num_possible_cpus() * PMD_SIZE; - - /* on non-NUMA, embedding is better */ - if (!pcpu_need_numa()) - return -EINVAL; - - /* don't consume more than 20% of vmalloc area */ - if (tot_size > vm_size / 5) { - pr_info("PERCPU: too large chunk size %zuMB for " - "large page remap\n", tot_size >> 20); - return -EINVAL; - } - } - - /* need PSE */ - if (!cpu_has_pse) { - pr_warning("PERCPU: lpage allocator requires PSE\n"); + /* + * If large page isn't supported, there's no benefit in doing + * this. Also, on non-NUMA, embedding is better. + * + * NOTE: disabled for now. + */ + if (true || !cpu_has_pse || !pcpu_need_numa()) return -EINVAL; - } /* * Currently supports only single page. Supporting multiple * pages won't be too difficult if it ever becomes necessary. */ - pcpul_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE + + pcpur_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE); - if (pcpul_size > PMD_SIZE) { + if (pcpur_size > PMD_SIZE) { pr_warning("PERCPU: static data is larger than large page, " "can't use large page\n"); return -EINVAL; } - dyn_size = pcpul_size - static_size - PERCPU_FIRST_CHUNK_RESERVE; + dyn_size = pcpur_size - static_size - PERCPU_FIRST_CHUNK_RESERVE; /* allocate pointer array and alloc large pages */ - map_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpul_map[0])); - pcpul_map = alloc_bootmem(map_size); + ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0])); + pcpur_ptrs = alloc_bootmem(ptrs_size); for_each_possible_cpu(cpu) { - pcpul_map[cpu].cpu = cpu; - pcpul_map[cpu].ptr = pcpu_alloc_bootmem(cpu, PMD_SIZE, - PMD_SIZE); - if (!pcpul_map[cpu].ptr) { - pr_warning("PERCPU: failed to allocate large page " - "for cpu%u\n", cpu); + pcpur_ptrs[cpu] = pcpu_alloc_bootmem(cpu, PMD_SIZE, PMD_SIZE); + if (!pcpur_ptrs[cpu]) goto enomem; - } /* - * Only use pcpul_size bytes and give back the rest. + * Only use pcpur_size bytes and give back the rest. * * Ingo: The 2MB up-rounding bootmem is needed to make * sure the partial 2MB page is still fully RAM - it's * not well-specified to have a PAT-incompatible area * (unmapped RAM, device memory, etc.) in that hole. */ - free_bootmem(__pa(pcpul_map[cpu].ptr + pcpul_size), - PMD_SIZE - pcpul_size); + free_bootmem(__pa(pcpur_ptrs[cpu] + pcpur_size), + PMD_SIZE - pcpur_size); - memcpy(pcpul_map[cpu].ptr, __per_cpu_load, static_size); + memcpy(pcpur_ptrs[cpu], __per_cpu_load, static_size); } /* allocate address and map */ - pcpul_vm.flags = VM_ALLOC; - pcpul_vm.size = num_possible_cpus() * PMD_SIZE; - vm_area_register_early(&pcpul_vm, PMD_SIZE); + vm.flags = VM_ALLOC; + vm.size = num_possible_cpus() * PMD_SIZE; + vm_area_register_early(&vm, PMD_SIZE); for_each_possible_cpu(cpu) { - pmd_t *pmd, pmd_v; + pmd_t *pmd; - pmd = populate_extra_pmd((unsigned long)pcpul_vm.addr + - cpu * PMD_SIZE); - pmd_v = pfn_pmd(page_to_pfn(virt_to_page(pcpul_map[cpu].ptr)), - PAGE_KERNEL_LARGE); - set_pmd(pmd, pmd_v); + pmd = populate_extra_pmd((unsigned long)vm.addr + + cpu * PMD_SIZE); + set_pmd(pmd, pfn_pmd(page_to_pfn(virt_to_page(pcpur_ptrs[cpu])), + PAGE_KERNEL_LARGE)); } /* we're ready, commit */ pr_info("PERCPU: Remapped at %p with large pages, static data " - "%zu bytes\n", pcpul_vm.addr, static_size); + "%zu bytes\n", vm.addr, static_size); - ret = pcpu_setup_first_chunk(pcpul_get_page, static_size, + ret = pcpu_setup_first_chunk(pcpur_get_page, static_size, PERCPU_FIRST_CHUNK_RESERVE, dyn_size, - PMD_SIZE, pcpul_vm.addr, NULL); - - /* sort pcpul_map array for pcpu_lpage_remapped() */ - for (i = 0; i < num_possible_cpus() - 1; i++) - for (j = i + 1; j < num_possible_cpus(); j++) - if (pcpul_map[i].ptr > pcpul_map[j].ptr) { - struct pcpul_ent tmp = pcpul_map[i]; - pcpul_map[i] = pcpul_map[j]; - pcpul_map[j] = tmp; - } - - return ret; + PMD_SIZE, vm.addr, NULL); + goto out_free_ar; enomem: for_each_possible_cpu(cpu) - if (pcpul_map[cpu].ptr) - free_bootmem(__pa(pcpul_map[cpu].ptr), pcpul_size); - free_bootmem(__pa(pcpul_map), map_size); - return -ENOMEM; -} - -/** - * pcpu_lpage_remapped - determine whether a kaddr is in pcpul recycled area - * @kaddr: the kernel address in question - * - * Determine whether @kaddr falls in the pcpul recycled area. This is - * used by pageattr to detect VM aliases and break up the pcpu PMD - * mapping such that the same physical page is not mapped under - * different attributes. - * - * The recycled area is always at the tail of a partially used PMD - * page. - * - * RETURNS: - * Address of corresponding remapped pcpu address if match is found; - * otherwise, NULL. - */ -void *pcpu_lpage_remapped(void *kaddr) -{ - void *pmd_addr = (void *)((unsigned long)kaddr & PMD_MASK); - unsigned long offset = (unsigned long)kaddr & ~PMD_MASK; - int left = 0, right = num_possible_cpus() - 1; - int pos; - - /* pcpul in use at all? */ - if (!pcpul_map) - return NULL; - - /* okay, perform binary search */ - while (left <= right) { - pos = (left + right) / 2; - - if (pcpul_map[pos].ptr < pmd_addr) - left = pos + 1; - else if (pcpul_map[pos].ptr > pmd_addr) - right = pos - 1; - else { - /* it shouldn't be in the area for the first chunk */ - WARN_ON(offset < pcpul_size); - - return pcpul_vm.addr + - pcpul_map[pos].cpu * PMD_SIZE + offset; - } - } - - return NULL; + if (pcpur_ptrs[cpu]) + free_bootmem(__pa(pcpur_ptrs[cpu]), PMD_SIZE); + ret = -ENOMEM; +out_free_ar: + free_bootmem(__pa(pcpur_ptrs), ptrs_size); + return ret; } #else -static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) +static ssize_t __init setup_pcpu_remap(size_t static_size) { return -EINVAL; } @@ -329,7 +249,7 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) * mapping so that it can use PMD mapping without additional TLB * pressure. */ -static ssize_t __init setup_pcpu_embed(size_t static_size, bool chosen) +static ssize_t __init setup_pcpu_embed(size_t static_size) { size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; @@ -338,7 +258,7 @@ static ssize_t __init setup_pcpu_embed(size_t static_size, bool chosen) * this. Also, embedding allocation doesn't play well with * NUMA. */ - if (!chosen && (!cpu_has_pse || pcpu_need_numa())) + if (!cpu_has_pse || pcpu_need_numa()) return -EINVAL; return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE, @@ -388,11 +308,8 @@ static ssize_t __init setup_pcpu_4k(size_t static_size) void *ptr; ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE); - if (!ptr) { - pr_warning("PERCPU: failed to allocate " - "4k page for cpu%u\n", cpu); + if (!ptr) goto enomem; - } memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); pcpu4k_pages[j++] = virt_to_page(ptr); @@ -416,16 +333,6 @@ static ssize_t __init setup_pcpu_4k(size_t static_size) return ret; } -/* for explicit first chunk allocator selection */ -static char pcpu_chosen_alloc[16] __initdata; - -static int __init percpu_alloc_setup(char *str) -{ - strncpy(pcpu_chosen_alloc, str, sizeof(pcpu_chosen_alloc) - 1); - return 0; -} -early_param("percpu_alloc", percpu_alloc_setup); - static inline void setup_percpu_segment(int cpu) { #ifdef CONFIG_X86_32 @@ -439,6 +346,11 @@ static inline void setup_percpu_segment(int cpu) #endif } +/* + * Great future plan: + * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. + * Always point %gs to its beginning + */ void __init setup_per_cpu_areas(void) { size_t static_size = __per_cpu_end - __per_cpu_start; @@ -455,26 +367,9 @@ void __init setup_per_cpu_areas(void) * of large page mappings. Please read comments on top of * each allocator for details. */ - ret = -EINVAL; - if (strlen(pcpu_chosen_alloc)) { - if (strcmp(pcpu_chosen_alloc, "4k")) { - if (!strcmp(pcpu_chosen_alloc, "lpage")) - ret = setup_pcpu_lpage(static_size, true); - else if (!strcmp(pcpu_chosen_alloc, "embed")) - ret = setup_pcpu_embed(static_size, true); - else - pr_warning("PERCPU: unknown allocator %s " - "specified\n", pcpu_chosen_alloc); - if (ret < 0) - pr_warning("PERCPU: %s allocator failed (%zd), " - "falling back to 4k\n", - pcpu_chosen_alloc, ret); - } - } else { - ret = setup_pcpu_lpage(static_size, false); - if (ret < 0) - ret = setup_pcpu_embed(static_size, false); - } + ret = setup_pcpu_remap(static_size); + if (ret < 0) + ret = setup_pcpu_embed(static_size); if (ret < 0) ret = setup_pcpu_4k(static_size); if (ret < 0) diff --git a/trunk/arch/x86/kernel/tlb_uv.c b/trunk/arch/x86/kernel/tlb_uv.c index 8ccabb8a2f6a..124d40c575df 100644 --- a/trunk/arch/x86/kernel/tlb_uv.c +++ b/trunk/arch/x86/kernel/tlb_uv.c @@ -711,6 +711,7 @@ uv_activation_descriptor_init(int node, int pnode) unsigned long pa; unsigned long m; unsigned long n; + unsigned long mmr_image; struct bau_desc *adp; struct bau_desc *ad2; @@ -726,8 +727,12 @@ uv_activation_descriptor_init(int node, int pnode) n = pa >> uv_nshift; m = pa & uv_mmask; - uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, - (n << UV_DESC_BASE_PNODE_SHIFT | m)); + mmr_image = uv_read_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE); + if (mmr_image) { + uv_write_global_mmr64(pnode, (unsigned long) + UVH_LB_BAU_SB_DESCRIPTOR_BASE, + (n << UV_DESC_BASE_PNODE_SHIFT | m)); + } /* * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c index 5204332f475d..a0f48f5671c0 100644 --- a/trunk/arch/x86/kernel/traps.c +++ b/trunk/arch/x86/kernel/traps.c @@ -346,9 +346,6 @@ io_check_error(unsigned char reason, struct pt_regs *regs) printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); show_registers(regs); - if (panic_on_io_nmi) - panic("NMI IOCK error: Not continuing"); - /* Re-enable the IOCK line, wait for a few seconds */ reason = (reason & 0xf) | 8; outb(reason, 0x61); diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 7030b5f911bf..5c3d6e81a7dc 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -2157,7 +2157,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) else /* 32 bits PSE 4MB page */ context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; + context->rsvd_bits_mask[1][0] = ~0ull; break; case PT32E_ROOT_LEVEL: context->rsvd_bits_mask[0][2] = @@ -2170,7 +2170,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) context->rsvd_bits_mask[1][1] = exb_bit_rsvd | rsvd_bits(maxphyaddr, 62) | rsvd_bits(13, 20); /* large page */ - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; + context->rsvd_bits_mask[1][0] = ~0ull; break; case PT64_ROOT_LEVEL: context->rsvd_bits_mask[0][3] = exb_bit_rsvd | @@ -2186,7 +2186,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) context->rsvd_bits_mask[1][1] = exb_bit_rsvd | rsvd_bits(maxphyaddr, 51) | rsvd_bits(13, 20); /* large page */ - context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; + context->rsvd_bits_mask[1][0] = ~0ull; break; } } diff --git a/trunk/arch/x86/kvm/paging_tmpl.h b/trunk/arch/x86/kvm/paging_tmpl.h index 67785f635399..258e4591e1ca 100644 --- a/trunk/arch/x86/kvm/paging_tmpl.h +++ b/trunk/arch/x86/kvm/paging_tmpl.h @@ -281,7 +281,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, { unsigned access = gw->pt_access; struct kvm_mmu_page *shadow_page; - u64 spte, *sptep = NULL; + u64 spte, *sptep; int direct; gfn_t table_gfn; int r; diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 356a0ce85c68..e770bf349ec4 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -3012,12 +3012,6 @@ static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 1; } -static int handle_vmx_insn(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - kvm_queue_exception(vcpu, UD_VECTOR); - return 1; -} - static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); @@ -3204,15 +3198,6 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, [EXIT_REASON_HLT] = handle_halt, [EXIT_REASON_INVLPG] = handle_invlpg, [EXIT_REASON_VMCALL] = handle_vmcall, - [EXIT_REASON_VMCLEAR] = handle_vmx_insn, - [EXIT_REASON_VMLAUNCH] = handle_vmx_insn, - [EXIT_REASON_VMPTRLD] = handle_vmx_insn, - [EXIT_REASON_VMPTRST] = handle_vmx_insn, - [EXIT_REASON_VMREAD] = handle_vmx_insn, - [EXIT_REASON_VMRESUME] = handle_vmx_insn, - [EXIT_REASON_VMWRITE] = handle_vmx_insn, - [EXIT_REASON_VMOFF] = handle_vmx_insn, - [EXIT_REASON_VMON] = handle_vmx_insn, [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, [EXIT_REASON_APIC_ACCESS] = handle_apic_access, [EXIT_REASON_WBINVD] = handle_wbinvd, diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index fe5474aec41a..249540f98513 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -898,7 +898,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_VM_HSAVE_PA: case MSR_P6_EVNTSEL0: case MSR_P6_EVNTSEL1: - case MSR_K7_EVNTSEL0: data = 0; break; case MSR_MTRRcap: diff --git a/trunk/arch/x86/kvm/x86_emulate.c b/trunk/arch/x86/kvm/x86_emulate.c index 616de4628d60..c1b6c232e02b 100644 --- a/trunk/arch/x86/kvm/x86_emulate.c +++ b/trunk/arch/x86/kvm/x86_emulate.c @@ -1361,7 +1361,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, return 0; } -static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) +void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) { u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask); /* diff --git a/trunk/arch/x86/lib/delay.c b/trunk/arch/x86/lib/delay.c index ff485d361182..f4568605d7d5 100644 --- a/trunk/arch/x86/lib/delay.c +++ b/trunk/arch/x86/lib/delay.c @@ -55,10 +55,8 @@ static void delay_tsc(unsigned long loops) preempt_disable(); cpu = smp_processor_id(); - rdtsc_barrier(); rdtscl(bclock); for (;;) { - rdtsc_barrier(); rdtscl(now); if ((now - bclock) >= loops) break; @@ -80,7 +78,6 @@ static void delay_tsc(unsigned long loops) if (unlikely(cpu != smp_processor_id())) { loops -= (now - bclock); cpu = smp_processor_id(); - rdtsc_barrier(); rdtscl(bclock); } } diff --git a/trunk/arch/x86/mm/init.c b/trunk/arch/x86/mm/init.c index 47ce9a2ce5e7..f53b57e4086f 100644 --- a/trunk/arch/x86/mm/init.c +++ b/trunk/arch/x86/mm/init.c @@ -177,6 +177,20 @@ static int __meminit save_mr(struct map_range *mr, int nr_range, return nr_range; } +#ifdef CONFIG_X86_64 +static void __init init_gbpages(void) +{ + if (direct_gbpages && cpu_has_gbpages) + printk(KERN_INFO "Using GB pages for direct mapping\n"); + else + direct_gbpages = 0; +} +#else +static inline void init_gbpages(void) +{ +} +#endif + /* * Setup the direct mapping of the physical memory at PAGE_OFFSET. * This runs before bootmem is initialized and gets pages directly from @@ -196,6 +210,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); + if (!after_bootmem) + init_gbpages(); + #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK) /* * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages. diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index b177652251a4..c4378f4fd4a5 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -598,8 +598,6 @@ void __init paging_init(void) sparse_memory_present_with_active_regions(MAX_NUMNODES); sparse_init(); - /* clear the default setting with node 0 */ - nodes_clear(node_states[N_NORMAL_MEMORY]); free_area_init_nodes(max_zone_pfns); } diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index 1b734d7a8966..3cfe9ced8a4c 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -682,9 +681,8 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias); static int cpa_process_alias(struct cpa_data *cpa) { struct cpa_data alias_cpa; - unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT); - unsigned long vaddr, remapped; - int ret; + int ret = 0; + unsigned long temp_cpa_vaddr, vaddr; if (cpa->pfn >= max_pfn_mapped) return 0; @@ -708,55 +706,42 @@ static int cpa_process_alias(struct cpa_data *cpa) PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { alias_cpa = *cpa; - alias_cpa.vaddr = &laddr; + temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); + alias_cpa.vaddr = &temp_cpa_vaddr; alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); + ret = __change_page_attr_set_clr(&alias_cpa, 0); - if (ret) - return ret; } #ifdef CONFIG_X86_64 + if (ret) + return ret; /* - * If the primary call didn't touch the high mapping already - * and the physical address is inside the kernel map, we need + * No need to redo, when the primary call touched the high + * mapping already: + */ + if (within(vaddr, (unsigned long) _text, _brk_end)) + return 0; + + /* + * If the physical address is inside the kernel map, we need * to touch the high mapped kernel as well: */ - if (!within(vaddr, (unsigned long)_text, _brk_end) && - within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) { - unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + - __START_KERNEL_map - phys_base; - alias_cpa = *cpa; - alias_cpa.vaddr = &temp_cpa_vaddr; - alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); + if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) + return 0; - /* - * The high mapping range is imprecise, so ignore the - * return value. - */ - __change_page_attr_set_clr(&alias_cpa, 0); - } -#endif + alias_cpa = *cpa; + temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base; + alias_cpa.vaddr = &temp_cpa_vaddr; + alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); /* - * If the PMD page was partially used for per-cpu remapping, - * the recycled area needs to be split and modified. Because - * the area is always proper subset of a PMD page - * cpa->numpages is guaranteed to be 1 for these areas, so - * there's no need to loop over and check for further remaps. + * The high mapping range is imprecise, so ignore the return value. */ - remapped = (unsigned long)pcpu_lpage_remapped((void *)laddr); - if (remapped) { - WARN_ON(cpa->numpages > 1); - alias_cpa = *cpa; - alias_cpa.vaddr = &remapped; - alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); - ret = __change_page_attr_set_clr(&alias_cpa, 0); - if (ret) - return ret; - } - - return 0; + __change_page_attr_set_clr(&alias_cpa, 0); +#endif + return ret; } static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) diff --git a/trunk/arch/x86/pci/acpi.c b/trunk/arch/x86/pci/acpi.c index b26626dc517c..16c3fda85bba 100644 --- a/trunk/arch/x86/pci/acpi.c +++ b/trunk/arch/x86/pci/acpi.c @@ -238,7 +238,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do #endif } - if (bus && (pci_probe & PCI_USE__CRS)) + if (bus && !(pci_probe & PCI_NO_ROOT_CRS)) get_current_resources(device, busnum, domain, bus); return bus; } diff --git a/trunk/arch/x86/pci/amd_bus.c b/trunk/arch/x86/pci/amd_bus.c index f893d6a6e803..2255f880678b 100644 --- a/trunk/arch/x86/pci/amd_bus.c +++ b/trunk/arch/x86/pci/amd_bus.c @@ -101,7 +101,7 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b) struct pci_root_info *info; /* don't go for it if _CRS is used */ - if (pci_probe & PCI_USE__CRS) + if (!(pci_probe & PCI_NO_ROOT_CRS)) return; /* if only one root bus, don't need to anything */ diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 2202b6257b82..4740119e4bb7 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -515,8 +515,8 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "assign-busses")) { pci_probe |= PCI_ASSIGN_ALL_BUSSES; return NULL; - } else if (!strcmp(str, "use_crs")) { - pci_probe |= PCI_USE__CRS; + } else if (!strcmp(str, "nocrs")) { + pci_probe |= PCI_NO_ROOT_CRS; return NULL; } else if (!strcmp(str, "earlydump")) { pci_early_dump_regs = 1; diff --git a/trunk/arch/x86/pci/mmconfig-shared.c b/trunk/arch/x86/pci/mmconfig-shared.c index 712443ec6d43..8766b0e216c5 100644 --- a/trunk/arch/x86/pci/mmconfig-shared.c +++ b/trunk/arch/x86/pci/mmconfig-shared.c @@ -523,69 +523,6 @@ static void __init pci_mmcfg_reject_broken(int early) static int __initdata known_bridge; -static int acpi_mcfg_64bit_base_addr __initdata = FALSE; - -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -struct acpi_mcfg_allocation *pci_mmcfg_config; -int pci_mmcfg_config_num; - -static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg) -{ - if (!strcmp(mcfg->header.oem_id, "SGI")) - acpi_mcfg_64bit_base_addr = TRUE; - - return 0; -} - -static int __init pci_parse_mcfg(struct acpi_table_header *header) -{ - struct acpi_table_mcfg *mcfg; - unsigned long i; - int config_size; - - if (!header) - return -EINVAL; - - mcfg = (struct acpi_table_mcfg *)header; - - /* how many config structures do we have */ - pci_mmcfg_config_num = 0; - i = header->length - sizeof(struct acpi_table_mcfg); - while (i >= sizeof(struct acpi_mcfg_allocation)) { - ++pci_mmcfg_config_num; - i -= sizeof(struct acpi_mcfg_allocation); - }; - if (pci_mmcfg_config_num == 0) { - printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); - return -ENODEV; - } - - config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); - pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); - if (!pci_mmcfg_config) { - printk(KERN_WARNING PREFIX - "No memory for MCFG config tables\n"); - return -ENOMEM; - } - - memcpy(pci_mmcfg_config, &mcfg[1], config_size); - - acpi_mcfg_oem_check(mcfg); - - for (i = 0; i < pci_mmcfg_config_num; ++i) { - if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) && - !acpi_mcfg_64bit_base_addr) { - printk(KERN_ERR PREFIX - "MMCONFIG not in low 4GB of memory\n"); - kfree(pci_mmcfg_config); - pci_mmcfg_config_num = 0; - return -ENODEV; - } - } - - return 0; -} - static void __init __pci_mmcfg_init(int early) { /* MMCONFIG disabled */ @@ -606,7 +543,7 @@ static void __init __pci_mmcfg_init(int early) } if (!known_bridge) - acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg); + acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); pci_mmcfg_reject_broken(early); diff --git a/trunk/arch/x86/power/cpu.c b/trunk/arch/x86/power/cpu.c index b3d20b9cac63..d277ef1eea51 100644 --- a/trunk/arch/x86/power/cpu.c +++ b/trunk/arch/x86/power/cpu.c @@ -244,7 +244,7 @@ static void __restore_processor_state(struct saved_context *ctxt) do_fpu_end(); mtrr_ap_init(); -#ifdef CONFIG_X86_OLD_MCE +#ifdef CONFIG_X86_32 mcheck_init(&boot_cpu_data); #endif } diff --git a/trunk/block/Makefile b/trunk/block/Makefile index 6c54ed0ff755..e9fa4dd690f2 100644 --- a/trunk/block/Makefile +++ b/trunk/block/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \ blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \ blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \ - ioctl.o genhd.o scsi_ioctl.o + ioctl.o genhd.o scsi_ioctl.o cmd-filter.o obj-$(CONFIG_BLK_DEV_BSG) += bsg.o obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 4b45435c6eaf..b06cf5c2a829 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -595,6 +595,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) q->sg_reserved_size = INT_MAX; + blk_set_cmd_filter_defaults(&q->cmd_filter); + /* * all done */ @@ -1170,11 +1172,6 @@ static int __make_request(struct request_queue *q, struct bio *bio) const int unplug = bio_unplug(bio); int rw_flags; - if (bio_barrier(bio) && bio_has_data(bio) && - (q->next_ordered == QUEUE_ORDERED_NONE)) { - bio_endio(bio, -EOPNOTSUPP); - return 0; - } /* * low level driver can indicate that it wants pages above a * certain limit bounced to low memory (ie for highmem, or even @@ -1475,6 +1472,11 @@ static inline void __generic_make_request(struct bio *bio) err = -EOPNOTSUPP; goto end_io; } + if (bio_barrier(bio) && bio_has_data(bio) && + (q->next_ordered == QUEUE_ORDERED_NONE)) { + err = -EOPNOTSUPP; + goto end_io; + } ret = q->make_request_fn(q, bio); } while (ret); @@ -2363,7 +2365,7 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src, __bio_clone(bio, bio_src); if (bio_integrity(bio_src) && - bio_integrity_clone(bio, bio_src, gfp_mask, bs)) + bio_integrity_clone(bio, bio_src, gfp_mask)) goto free_and_out; if (bio_ctr && bio_ctr(bio, bio_src, data)) diff --git a/trunk/block/blk-merge.c b/trunk/block/blk-merge.c index e1999679a4d5..39ce64432ba6 100644 --- a/trunk/block/blk-merge.c +++ b/trunk/block/blk-merge.c @@ -350,12 +350,6 @@ static int attempt_merge(struct request_queue *q, struct request *req, if (blk_integrity_rq(req) != blk_integrity_rq(next)) return 0; - /* don't merge requests of different failfast settings */ - if (blk_failfast_dev(req) != blk_failfast_dev(next) || - blk_failfast_transport(req) != blk_failfast_transport(next) || - blk_failfast_driver(req) != blk_failfast_driver(next)) - return 0; - /* * If we are allowed to merge, then append bio list * from next to rq and release next. merge_requests_fn diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index 5f184bb3ff9e..54106f052f70 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -186,7 +186,7 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, return -EFAULT; if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) { - if (blk_verify_command(rq->cmd, has_write_perm)) + if (blk_verify_command(&q->cmd_filter, rq->cmd, has_write_perm)) return -EPERM; } else if (!capable(CAP_SYS_RAWIO)) return -EPERM; @@ -315,6 +315,7 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, blk_put_request(rq); if (next_rq) { blk_rq_unmap_user(next_rq->bio); + next_rq->bio = NULL; blk_put_request(next_rq); } return ERR_PTR(ret); @@ -448,6 +449,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, hdr->dout_resid = rq->resid_len; hdr->din_resid = rq->next_rq->resid_len; blk_rq_unmap_user(bidi_bio); + rq->next_rq->bio = NULL; blk_put_request(rq->next_rq); } else if (rq_data_dir(rq) == READ) hdr->din_resid = rq->resid_len; @@ -466,6 +468,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, blk_rq_unmap_user(bio); if (rq->cmd != rq->__cmd) kfree(rq->cmd); + rq->bio = NULL; blk_put_request(rq); return ret; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 87276eb83f7f..833ec18eaa63 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -70,51 +70,6 @@ struct cfq_rb_root { }; #define CFQ_RB_ROOT (struct cfq_rb_root) { RB_ROOT, NULL, } -/* - * Per process-grouping structure - */ -struct cfq_queue { - /* reference count */ - atomic_t ref; - /* various state flags, see below */ - unsigned int flags; - /* parent cfq_data */ - struct cfq_data *cfqd; - /* service_tree member */ - struct rb_node rb_node; - /* service_tree key */ - unsigned long rb_key; - /* prio tree member */ - struct rb_node p_node; - /* prio tree root we belong to, if any */ - struct rb_root *p_root; - /* sorted list of pending requests */ - struct rb_root sort_list; - /* if fifo isn't expired, next request to serve */ - struct request *next_rq; - /* requests queued in sort_list */ - int queued[2]; - /* currently allocated requests */ - int allocated[2]; - /* fifo list of requests in sort_list */ - struct list_head fifo; - - unsigned long slice_end; - long slice_resid; - unsigned int slice_dispatch; - - /* pending metadata requests */ - int meta_pending; - /* number of requests that are on the dispatch list or inside driver */ - int dispatched; - - /* io prio of this group */ - unsigned short ioprio, org_ioprio; - unsigned short ioprio_class, org_ioprio_class; - - pid_t pid; -}; - /* * Per block device queue structure */ @@ -180,11 +135,51 @@ struct cfq_data { unsigned int cfq_slice_idle; struct list_head cic_list; +}; - /* - * Fallback dummy cfqq for extreme OOM conditions - */ - struct cfq_queue oom_cfqq; +/* + * Per process-grouping structure + */ +struct cfq_queue { + /* reference count */ + atomic_t ref; + /* various state flags, see below */ + unsigned int flags; + /* parent cfq_data */ + struct cfq_data *cfqd; + /* service_tree member */ + struct rb_node rb_node; + /* service_tree key */ + unsigned long rb_key; + /* prio tree member */ + struct rb_node p_node; + /* prio tree root we belong to, if any */ + struct rb_root *p_root; + /* sorted list of pending requests */ + struct rb_root sort_list; + /* if fifo isn't expired, next request to serve */ + struct request *next_rq; + /* requests queued in sort_list */ + int queued[2]; + /* currently allocated requests */ + int allocated[2]; + /* fifo list of requests in sort_list */ + struct list_head fifo; + + unsigned long slice_end; + long slice_resid; + unsigned int slice_dispatch; + + /* pending metadata requests */ + int meta_pending; + /* number of requests that are on the dispatch list or inside driver */ + int dispatched; + + /* io prio of this group */ + unsigned short ioprio, org_ioprio; + unsigned short ioprio_class, org_ioprio_class; + + pid_t pid; }; enum cfqq_state_flags { @@ -1646,26 +1641,6 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc) ioc->ioprio_changed = 0; } -static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq, - pid_t pid, int is_sync) -{ - RB_CLEAR_NODE(&cfqq->rb_node); - RB_CLEAR_NODE(&cfqq->p_node); - INIT_LIST_HEAD(&cfqq->fifo); - - atomic_set(&cfqq->ref, 0); - cfqq->cfqd = cfqd; - - cfq_mark_cfqq_prio_changed(cfqq); - - if (is_sync) { - if (!cfq_class_idle(cfqq)) - cfq_mark_cfqq_idle_window(cfqq); - cfq_mark_cfqq_sync(cfqq); - } - cfqq->pid = pid; -} - static struct cfq_queue * cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc, gfp_t gfp_mask) @@ -1678,40 +1653,56 @@ cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, /* cic always exists here */ cfqq = cic_to_cfqq(cic, is_sync); - /* - * Always try a new alloc if we fell back to the OOM cfqq - * originally, since it should just be a temporary situation. - */ - if (!cfqq || cfqq == &cfqd->oom_cfqq) { - cfqq = NULL; + if (!cfqq) { if (new_cfqq) { cfqq = new_cfqq; new_cfqq = NULL; } else if (gfp_mask & __GFP_WAIT) { + /* + * Inform the allocator of the fact that we will + * just repeat this allocation if it fails, to allow + * the allocator to do whatever it needs to attempt to + * free memory. + */ spin_unlock_irq(cfqd->queue->queue_lock); new_cfqq = kmem_cache_alloc_node(cfq_pool, - gfp_mask | __GFP_ZERO, + gfp_mask | __GFP_NOFAIL | __GFP_ZERO, cfqd->queue->node); spin_lock_irq(cfqd->queue->queue_lock); - if (new_cfqq) - goto retry; + goto retry; } else { cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask | __GFP_ZERO, cfqd->queue->node); + if (!cfqq) + goto out; } - if (cfqq) { - cfq_init_cfqq(cfqd, cfqq, current->pid, is_sync); - cfq_init_prio_data(cfqq, ioc); - cfq_log_cfqq(cfqd, cfqq, "alloced"); - } else - cfqq = &cfqd->oom_cfqq; + RB_CLEAR_NODE(&cfqq->rb_node); + RB_CLEAR_NODE(&cfqq->p_node); + INIT_LIST_HEAD(&cfqq->fifo); + + atomic_set(&cfqq->ref, 0); + cfqq->cfqd = cfqd; + + cfq_mark_cfqq_prio_changed(cfqq); + + cfq_init_prio_data(cfqq, ioc); + + if (is_sync) { + if (!cfq_class_idle(cfqq)) + cfq_mark_cfqq_idle_window(cfqq); + cfq_mark_cfqq_sync(cfqq); + } + cfqq->pid = current->pid; + cfq_log_cfqq(cfqd, cfqq, "alloced"); } if (new_cfqq) kmem_cache_free(cfq_pool, new_cfqq); +out: + WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq); return cfqq; } @@ -1744,8 +1735,11 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc, cfqq = *async_cfqq; } - if (!cfqq) + if (!cfqq) { cfqq = cfq_find_alloc_queue(cfqd, is_sync, ioc, gfp_mask); + if (!cfqq) + return NULL; + } /* * pin the queue now that it's allocated, scheduler exit will prune it @@ -2313,6 +2307,10 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask) cfqq = cic_to_cfqq(cic, is_sync); if (!cfqq) { cfqq = cfq_get_queue(cfqd, is_sync, cic->ioc, gfp_mask); + + if (!cfqq) + goto queue_fail; + cic_set_cfqq(cic, cfqq, is_sync); } @@ -2467,14 +2465,6 @@ static void *cfq_init_queue(struct request_queue *q) for (i = 0; i < CFQ_PRIO_LISTS; i++) cfqd->prio_trees[i] = RB_ROOT; - /* - * Our fallback cfqq if cfq_find_alloc_queue() runs into OOM issues. - * Grab a permanent reference to it, so that the normal code flow - * will not attempt to free it. - */ - cfq_init_cfqq(cfqd, &cfqd->oom_cfqq, 1, 0); - atomic_inc(&cfqd->oom_cfqq.ref); - INIT_LIST_HEAD(&cfqd->cic_list); cfqd->queue = q; diff --git a/trunk/block/cmd-filter.c b/trunk/block/cmd-filter.c new file mode 100644 index 000000000000..572bbc2f900d --- /dev/null +++ b/trunk/block/cmd-filter.c @@ -0,0 +1,233 @@ +/* + * Copyright 2004 Peter M. Jones + * + * 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 Licens + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +int blk_verify_command(struct blk_cmd_filter *filter, + unsigned char *cmd, fmode_t has_write_perm) +{ + /* root can do any command. */ + if (capable(CAP_SYS_RAWIO)) + return 0; + + /* if there's no filter set, assume we're filtering everything out */ + if (!filter) + return -EPERM; + + /* Anybody who can open the device can do a read-safe command */ + if (test_bit(cmd[0], filter->read_ok)) + return 0; + + /* Write-safe commands require a writable open */ + if (test_bit(cmd[0], filter->write_ok) && has_write_perm) + return 0; + + return -EPERM; +} +EXPORT_SYMBOL(blk_verify_command); + +#if 0 +/* and now, the sysfs stuff */ +static ssize_t rcf_cmds_show(struct blk_cmd_filter *filter, char *page, + int rw) +{ + char *npage = page; + unsigned long *okbits; + int i; + + if (rw == READ) + okbits = filter->read_ok; + else + okbits = filter->write_ok; + + for (i = 0; i < BLK_SCSI_MAX_CMDS; i++) { + if (test_bit(i, okbits)) { + npage += sprintf(npage, "0x%02x", i); + if (i < BLK_SCSI_MAX_CMDS - 1) + sprintf(npage++, " "); + } + } + + if (npage != page) + npage += sprintf(npage, "\n"); + + return npage - page; +} + +static ssize_t rcf_readcmds_show(struct blk_cmd_filter *filter, char *page) +{ + return rcf_cmds_show(filter, page, READ); +} + +static ssize_t rcf_writecmds_show(struct blk_cmd_filter *filter, + char *page) +{ + return rcf_cmds_show(filter, page, WRITE); +} + +static ssize_t rcf_cmds_store(struct blk_cmd_filter *filter, + const char *page, size_t count, int rw) +{ + unsigned long okbits[BLK_SCSI_CMD_PER_LONG], *target_okbits; + int cmd, set; + char *p, *status; + + if (rw == READ) { + memcpy(&okbits, filter->read_ok, sizeof(okbits)); + target_okbits = filter->read_ok; + } else { + memcpy(&okbits, filter->write_ok, sizeof(okbits)); + target_okbits = filter->write_ok; + } + + while ((p = strsep((char **)&page, " ")) != NULL) { + set = 1; + + if (p[0] == '+') { + p++; + } else if (p[0] == '-') { + set = 0; + p++; + } + + cmd = simple_strtol(p, &status, 16); + + /* either of these cases means invalid input, so do nothing. */ + if ((status == p) || cmd >= BLK_SCSI_MAX_CMDS) + return -EINVAL; + + if (set) + __set_bit(cmd, okbits); + else + __clear_bit(cmd, okbits); + } + + memcpy(target_okbits, okbits, sizeof(okbits)); + return count; +} + +static ssize_t rcf_readcmds_store(struct blk_cmd_filter *filter, + const char *page, size_t count) +{ + return rcf_cmds_store(filter, page, count, READ); +} + +static ssize_t rcf_writecmds_store(struct blk_cmd_filter *filter, + const char *page, size_t count) +{ + return rcf_cmds_store(filter, page, count, WRITE); +} + +struct rcf_sysfs_entry { + struct attribute attr; + ssize_t (*show)(struct blk_cmd_filter *, char *); + ssize_t (*store)(struct blk_cmd_filter *, const char *, size_t); +}; + +static struct rcf_sysfs_entry rcf_readcmds_entry = { + .attr = { .name = "read_table", .mode = S_IRUGO | S_IWUSR }, + .show = rcf_readcmds_show, + .store = rcf_readcmds_store, +}; + +static struct rcf_sysfs_entry rcf_writecmds_entry = { + .attr = {.name = "write_table", .mode = S_IRUGO | S_IWUSR }, + .show = rcf_writecmds_show, + .store = rcf_writecmds_store, +}; + +static struct attribute *default_attrs[] = { + &rcf_readcmds_entry.attr, + &rcf_writecmds_entry.attr, + NULL, +}; + +#define to_rcf(atr) container_of((atr), struct rcf_sysfs_entry, attr) + +static ssize_t +rcf_attr_show(struct kobject *kobj, struct attribute *attr, char *page) +{ + struct rcf_sysfs_entry *entry = to_rcf(attr); + struct blk_cmd_filter *filter; + + filter = container_of(kobj, struct blk_cmd_filter, kobj); + if (entry->show) + return entry->show(filter, page); + + return 0; +} + +static ssize_t +rcf_attr_store(struct kobject *kobj, struct attribute *attr, + const char *page, size_t length) +{ + struct rcf_sysfs_entry *entry = to_rcf(attr); + struct blk_cmd_filter *filter; + + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + + if (!entry->store) + return -EINVAL; + + filter = container_of(kobj, struct blk_cmd_filter, kobj); + return entry->store(filter, page, length); +} + +static struct sysfs_ops rcf_sysfs_ops = { + .show = rcf_attr_show, + .store = rcf_attr_store, +}; + +static struct kobj_type rcf_ktype = { + .sysfs_ops = &rcf_sysfs_ops, + .default_attrs = default_attrs, +}; + +int blk_register_filter(struct gendisk *disk) +{ + int ret; + struct blk_cmd_filter *filter = &disk->queue->cmd_filter; + + ret = kobject_init_and_add(&filter->kobj, &rcf_ktype, + &disk_to_dev(disk)->kobj, + "%s", "cmd_filter"); + if (ret < 0) + return ret; + + return 0; +} +EXPORT_SYMBOL(blk_register_filter); + +void blk_unregister_filter(struct gendisk *disk) +{ + struct blk_cmd_filter *filter = &disk->queue->cmd_filter; + + kobject_put(&filter->kobj); +} +EXPORT_SYMBOL(blk_unregister_filter); +#endif diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 6f2375339a99..ca861927ba41 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -100,14 +100,6 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio) if (bio_integrity(bio) != blk_integrity_rq(rq)) return 0; - /* - * Don't merge if failfast settings don't match - */ - if (bio_failfast_dev(bio) != blk_failfast_dev(rq) || - bio_failfast_transport(bio) != blk_failfast_transport(rq) || - bio_failfast_driver(bio) != blk_failfast_driver(rq)) - return 0; - if (!elv_iosched_allow_merge(rq, bio)) return 0; diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index f0e0ce0a607d..5f8e798ede4e 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -32,11 +32,6 @@ #include #include -struct blk_cmd_filter { - unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; - unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; -} blk_default_cmd_filter; - /* Command group 3 is reserved and should never be used. */ const unsigned char scsi_command_size_tbl[8] = { @@ -110,7 +105,7 @@ static int sg_emulated_host(struct request_queue *q, int __user *p) return put_user(1, p); } -static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) +void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) { /* Basic read-only commands */ __set_bit(TEST_UNIT_READY, filter->read_ok); @@ -192,37 +187,14 @@ static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) __set_bit(GPCMD_SET_STREAMING, filter->write_ok); __set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok); } - -int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm) -{ - struct blk_cmd_filter *filter = &blk_default_cmd_filter; - - /* root can do any command. */ - if (capable(CAP_SYS_RAWIO)) - return 0; - - /* if there's no filter set, assume we're filtering everything out */ - if (!filter) - return -EPERM; - - /* Anybody who can open the device can do a read-safe command */ - if (test_bit(cmd[0], filter->read_ok)) - return 0; - - /* Write-safe commands require a writable open */ - if (test_bit(cmd[0], filter->write_ok) && has_write_perm) - return 0; - - return -EPERM; -} -EXPORT_SYMBOL(blk_verify_command); +EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults); static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, struct sg_io_hdr *hdr, fmode_t mode) { if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) return -EFAULT; - if (blk_verify_command(rq->cmd, mode & FMODE_WRITE)) + if (blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE)) return -EPERM; /* @@ -455,7 +427,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) goto error; - err = blk_verify_command(rq->cmd, mode & FMODE_WRITE); + err = blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE); if (err) goto error; @@ -673,10 +645,5 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod blk_put_queue(q); return err; } -EXPORT_SYMBOL(scsi_cmd_ioctl); -int __init blk_scsi_ioctl_init(void) -{ - blk_set_cmd_filter_defaults(&blk_default_cmd_filter); - return 0; -} +EXPORT_SYMBOL(scsi_cmd_ioctl); diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index 0df8fcb687d6..88e42abf5d88 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -61,7 +61,6 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); static int acpi_ac_add(struct acpi_device *device); static int acpi_ac_remove(struct acpi_device *device, int type); static int acpi_ac_resume(struct acpi_device *device); -static void acpi_ac_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id ac_device_ids[] = { {"ACPI0003", 0}, @@ -73,12 +72,10 @@ static struct acpi_driver acpi_ac_driver = { .name = "ac", .class = ACPI_AC_CLASS, .ids = ac_device_ids, - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = acpi_ac_add, .remove = acpi_ac_remove, .resume = acpi_ac_resume, - .notify = acpi_ac_notify, }, }; @@ -223,14 +220,16 @@ static int acpi_ac_remove_fs(struct acpi_device *device) Driver Model -------------------------------------------------------------------------- */ -static void acpi_ac_notify(struct acpi_device *device, u32 event) +static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_ac *ac = acpi_driver_data(device); + struct acpi_ac *ac = data; + struct acpi_device *device = NULL; if (!ac) return; + device = ac->device; switch (event) { default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -254,6 +253,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) static int acpi_ac_add(struct acpi_device *device) { int result = 0; + acpi_status status = AE_OK; struct acpi_ac *ac = NULL; @@ -286,6 +286,13 @@ static int acpi_ac_add(struct acpi_device *device) ac->charger.get_property = get_ac_property; power_supply_register(&ac->device->dev, &ac->charger); #endif + status = acpi_install_notify_handler(device->handle, + ACPI_ALL_NOTIFY, acpi_ac_notify, + ac); + if (ACPI_FAILURE(status)) { + result = -ENODEV; + goto end; + } printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), @@ -321,6 +328,7 @@ static int acpi_ac_resume(struct acpi_device *device) static int acpi_ac_remove(struct acpi_device *device, int type) { + acpi_status status = AE_OK; struct acpi_ac *ac = NULL; @@ -329,6 +337,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type) ac = acpi_driver_data(device); + status = acpi_remove_notify_handler(device->handle, + ACPI_ALL_NOTIFY, acpi_ac_notify); #ifdef CONFIG_ACPI_SYSFS_POWER if (ac->charger.dev) power_supply_unregister(&ac->charger); diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 58b4517ce712..b0de6312919a 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -796,12 +796,13 @@ static void acpi_battery_remove_fs(struct acpi_device *device) Driver Interface -------------------------------------------------------------------------- */ -static void acpi_battery_notify(struct acpi_device *device, u32 event) +static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_battery *battery = acpi_driver_data(device); - + struct acpi_battery *battery = data; + struct acpi_device *device; if (!battery) return; + device = battery->device; acpi_battery_update(battery); acpi_bus_generate_proc_event(device, event, acpi_battery_present(battery)); @@ -818,6 +819,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) static int acpi_battery_add(struct acpi_device *device) { int result = 0; + acpi_status status = 0; struct acpi_battery *battery = NULL; if (!device) return -EINVAL; @@ -832,12 +834,22 @@ static int acpi_battery_add(struct acpi_device *device) acpi_battery_update(battery); #ifdef CONFIG_ACPI_PROCFS_POWER result = acpi_battery_add_fs(device); + if (result) + goto end; #endif - if (!result) { - printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", - ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), - device->status.battery_present ? "present" : "absent"); - } else { + status = acpi_install_notify_handler(device->handle, + ACPI_ALL_NOTIFY, + acpi_battery_notify, battery); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); + result = -ENODEV; + goto end; + } + printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", + ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), + device->status.battery_present ? "present" : "absent"); + end: + if (result) { #ifdef CONFIG_ACPI_PROCFS_POWER acpi_battery_remove_fs(device); #endif @@ -848,11 +860,15 @@ static int acpi_battery_add(struct acpi_device *device) static int acpi_battery_remove(struct acpi_device *device, int type) { + acpi_status status = 0; struct acpi_battery *battery = NULL; if (!device || !acpi_driver_data(device)) return -EINVAL; battery = acpi_driver_data(device); + status = acpi_remove_notify_handler(device->handle, + ACPI_ALL_NOTIFY, + acpi_battery_notify); #ifdef CONFIG_ACPI_PROCFS_POWER acpi_battery_remove_fs(device); #endif @@ -880,12 +896,10 @@ static struct acpi_driver acpi_battery_driver = { .name = "battery", .class = ACPI_BATTERY_CLASS, .ids = battery_device_ids, - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = acpi_battery_add, .resume = acpi_battery_resume, .remove = acpi_battery_remove, - .notify = acpi_battery_notify, }, }; diff --git a/trunk/drivers/acpi/blacklist.c b/trunk/drivers/acpi/blacklist.c index f6baa77deefb..09c69806c1fc 100644 --- a/trunk/drivers/acpi/blacklist.c +++ b/trunk/drivers/acpi/blacklist.c @@ -192,22 +192,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), }, }, - { - .callback = dmi_disable_osi_vista, - .ident = "Sony VGN-NS10J_S", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), - }, - }, - { - .callback = dmi_disable_osi_vista, - .ident = "Sony VGN-SR290J", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), - }, - }, /* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index 2876fc70c3a9..ae862f1798dc 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -450,16 +450,18 @@ int acpi_bus_receive_event(struct acpi_bus_event *event) Notification Handling -------------------------------------------------------------------------- */ -static void acpi_bus_check_device(acpi_handle handle) +static int +acpi_bus_check_device(struct acpi_device *device, int *status_changed) { - struct acpi_device *device; - acpi_status status; + acpi_status status = 0; struct acpi_device_status old_status; - if (acpi_bus_get_device(handle, &device)) - return; + if (!device) - return; + return -EINVAL; + + if (status_changed) + *status_changed = 0; old_status = device->status; @@ -469,15 +471,22 @@ static void acpi_bus_check_device(acpi_handle handle) */ if (device->parent && !device->parent->status.present) { device->status = device->parent->status; - return; + if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) { + if (status_changed) + *status_changed = 1; + } + return 0; } status = acpi_bus_get_status(device); if (ACPI_FAILURE(status)) - return; + return -ENODEV; if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) - return; + return 0; + + if (status_changed) + *status_changed = 1; /* * Device Insertion/Removal @@ -489,17 +498,33 @@ static void acpi_bus_check_device(acpi_handle handle) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); /* TBD: Handle device removal */ } + + return 0; } -static void acpi_bus_check_scope(acpi_handle handle) +static int acpi_bus_check_scope(struct acpi_device *device) { + int result = 0; + int status_changed = 0; + + + if (!device) + return -EINVAL; + /* Status Change? */ - acpi_bus_check_device(handle); + result = acpi_bus_check_device(device, &status_changed); + if (result) + return result; + + if (!status_changed) + return 0; /* * TBD: Enumerate child devices within this device's scope and * run acpi_bus_check_device()'s on them. */ + + return 0; } static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list); @@ -522,19 +547,22 @@ EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier); */ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) { + int result = 0; struct acpi_device *device = NULL; - struct acpi_driver *driver; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", - type, handle)); blocking_notifier_call_chain(&acpi_bus_notify_list, type, (void *)handle); + if (acpi_bus_get_device(handle, &device)) + return; + switch (type) { case ACPI_NOTIFY_BUS_CHECK: - acpi_bus_check_scope(handle); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Received BUS CHECK notification for device [%s]\n", + device->pnp.bus_id)); + result = acpi_bus_check_scope(device); /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). @@ -542,7 +570,10 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; case ACPI_NOTIFY_DEVICE_CHECK: - acpi_bus_check_device(handle); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Received DEVICE CHECK notification for device [%s]\n", + device->pnp.bus_id)); + result = acpi_bus_check_device(device, NULL); /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). @@ -550,26 +581,44 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; case ACPI_NOTIFY_DEVICE_WAKE: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Received DEVICE WAKE notification for device [%s]\n", + device->pnp.bus_id)); /* TBD */ break; case ACPI_NOTIFY_EJECT_REQUEST: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Received EJECT REQUEST notification for device [%s]\n", + device->pnp.bus_id)); /* TBD */ break; case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Received DEVICE CHECK LIGHT notification for device [%s]\n", + device->pnp.bus_id)); /* TBD: Exactly what does 'light' mean? */ break; case ACPI_NOTIFY_FREQUENCY_MISMATCH: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Received FREQUENCY MISMATCH notification for device [%s]\n", + device->pnp.bus_id)); /* TBD */ break; case ACPI_NOTIFY_BUS_MODE_MISMATCH: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Received BUS MODE MISMATCH notification for device [%s]\n", + device->pnp.bus_id)); /* TBD */ break; case ACPI_NOTIFY_POWER_FAULT: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Received POWER FAULT notification for device [%s]\n", + device->pnp.bus_id)); /* TBD */ break; @@ -580,13 +629,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; } - acpi_bus_get_device(handle, &device); - if (device) { - driver = device->driver; - if (driver && driver->ops.notify && - (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) - driver->ops.notify(device, type); - } + return; } /* -------------------------------------------------------------------------- diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index a8a5c29958c8..8bd2c2a6884d 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -140,6 +140,46 @@ struct device *acpi_get_physical_device(acpi_handle handle) EXPORT_SYMBOL(acpi_get_physical_device); +/* ToDo: When a PCI bridge is found, return the PCI device behind the bridge + * This should work in general, but did not on a Lenovo T61 for the + * graphics card. But this must be fixed when the PCI device is + * bound and the kernel device struct is attached to the acpi device + * Note: A success call will increase reference count by one + * Do call put_device(dev) on the returned device then + */ +struct device *acpi_get_physical_pci_device(acpi_handle handle) +{ + struct device *dev; + long long device_id; + acpi_status status; + + status = + acpi_evaluate_integer(handle, "_ADR", NULL, &device_id); + + if (ACPI_FAILURE(status)) + return NULL; + + /* We need to attempt to determine whether the _ADR refers to a + PCI device or not. There's no terribly good way to do this, + so the best we can hope for is to assume that there'll never + be a device in the host bridge */ + if (device_id >= 0x10000) { + /* It looks like a PCI device. Does it exist? */ + dev = acpi_get_physical_device(handle); + } else { + /* It doesn't look like a PCI device. Does its parent + exist? */ + acpi_handle phandle; + if (acpi_get_parent(handle, &phandle)) + return NULL; + dev = acpi_get_physical_device(phandle); + } + if (!dev) + return NULL; + return dev; +} +EXPORT_SYMBOL(acpi_get_physical_pci_device); + static int acpi_bind_one(struct device *dev, acpi_handle handle) { struct acpi_device *acpi_dev; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 71670719d61a..d916bea729f1 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -79,7 +79,6 @@ static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; static struct workqueue_struct *kacpi_notify_wq; -static struct workqueue_struct *kacpi_hotplug_wq; struct acpi_res_list { resource_size_t start; @@ -193,10 +192,8 @@ acpi_status acpi_os_initialize1(void) { kacpid_wq = create_singlethread_workqueue("kacpid"); kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); - kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); BUG_ON(!kacpid_wq); BUG_ON(!kacpi_notify_wq); - BUG_ON(!kacpi_hotplug_wq); return AE_OK; } @@ -209,7 +206,6 @@ acpi_status acpi_os_terminate(void) destroy_workqueue(kacpid_wq); destroy_workqueue(kacpi_notify_wq); - destroy_workqueue(kacpi_hotplug_wq); return AE_OK; } @@ -720,7 +716,6 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, acpi_status status = AE_OK; struct acpi_os_dpc *dpc; struct workqueue_struct *queue; - work_func_t func; int ret; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", @@ -745,17 +740,15 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, dpc->function = function; dpc->context = context; - /* - * We can't run hotplug code in keventd_wq/kacpid_wq/kacpid_notify_wq - * because the hotplug code may call driver .remove() functions, - * which invoke flush_scheduled_work/acpi_os_wait_events_complete - * to flush these workqueues. - */ - queue = hp ? kacpi_hotplug_wq : - (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); - func = hp ? acpi_os_execute_hp_deferred : acpi_os_execute_deferred; - INIT_WORK(&dpc->work, func); - ret = queue_work(queue, &dpc->work); + if (!hp) { + INIT_WORK(&dpc->work, acpi_os_execute_deferred); + queue = (type == OSL_NOTIFY_HANDLER) ? + kacpi_notify_wq : kacpid_wq; + ret = queue_work(queue, &dpc->work); + } else { + INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred); + ret = schedule_work(&dpc->work); + } if (!ret) { printk(KERN_ERR PREFIX diff --git a/trunk/drivers/acpi/pci_bind.c b/trunk/drivers/acpi/pci_bind.c index a5a77b78a723..bc46de3d967f 100644 --- a/trunk/drivers/acpi/pci_bind.c +++ b/trunk/drivers/acpi/pci_bind.c @@ -24,7 +24,12 @@ */ #include +#include +#include #include +#include +#include +#include #include #include #include @@ -33,76 +38,310 @@ #define _COMPONENT ACPI_PCI_COMPONENT ACPI_MODULE_NAME("pci_bind"); -static int acpi_pci_unbind(struct acpi_device *device) -{ +struct acpi_pci_data { + struct acpi_pci_id id; + struct pci_bus *bus; struct pci_dev *dev; +}; + +static int acpi_pci_unbind(struct acpi_device *device); + +static void acpi_pci_data_handler(acpi_handle handle, u32 function, + void *context) +{ + + /* TBD: Anything we need to do here? */ + + return; +} + +/** + * acpi_get_pci_id + * ------------------ + * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) + * to resolve PCI information for ACPI-PCI devices defined in the namespace. + * This typically occurs when resolving PCI operation region information. + */ +acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_device *device = NULL; + struct acpi_pci_data *data = NULL; + + + if (!id) + return AE_BAD_PARAMETER; + + result = acpi_bus_get_device(handle, &device); + if (result) { + printk(KERN_ERR PREFIX + "Invalid ACPI Bus context for device %s\n", + acpi_device_bid(device)); + return AE_NOT_EXIST; + } + + status = acpi_get_data(handle, acpi_pci_data_handler, (void **)&data); + if (ACPI_FAILURE(status) || !data) { + ACPI_EXCEPTION((AE_INFO, status, + "Invalid ACPI-PCI context for device %s", + acpi_device_bid(device))); + return status; + } - dev = acpi_get_pci_dev(device->handle); - if (!dev || !dev->subordinate) - goto out; + *id = data->id; - acpi_pci_irq_del_prt(dev->subordinate); + /* + id->segment = data->id.segment; + id->bus = data->id.bus; + id->device = data->id.device; + id->function = data->id.function; + */ - device->ops.bind = NULL; - device->ops.unbind = NULL; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Device %s has PCI address %04x:%02x:%02x.%d\n", + acpi_device_bid(device), id->segment, id->bus, + id->device, id->function)); -out: - pci_dev_put(dev); - return 0; + return AE_OK; } -static int acpi_pci_bind(struct acpi_device *device) +EXPORT_SYMBOL(acpi_get_pci_id); + +int acpi_pci_bind(struct acpi_device *device) { + int result = 0; acpi_status status; + struct acpi_pci_data *data; + struct acpi_pci_data *pdata; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_handle handle; - struct pci_bus *bus; - struct pci_dev *dev; - dev = acpi_get_pci_dev(device->handle); - if (!dev) - return 0; + if (!device || !device->parent) + return -EINVAL; + + data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); + if (ACPI_FAILURE(status)) { + kfree(data); + return -ENODEV; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", + (char *)buffer.pointer)); + + /* + * Segment & Bus + * ------------- + * These are obtained via the parent device's ACPI-PCI context. + */ + status = acpi_get_data(device->parent->handle, acpi_pci_data_handler, + (void **)&pdata); + if (ACPI_FAILURE(status) || !pdata || !pdata->bus) { + ACPI_EXCEPTION((AE_INFO, status, + "Invalid ACPI-PCI context for parent device %s", + acpi_device_bid(device->parent))); + result = -ENODEV; + goto end; + } + data->id.segment = pdata->id.segment; + data->id.bus = pdata->bus->number; + + /* + * Device & Function + * ----------------- + * These are simply obtained from the device's _ADR method. Note + * that a value of zero is valid. + */ + data->id.device = device->pnp.bus_address >> 16; + data->id.function = device->pnp.bus_address & 0xFFFF; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n", + data->id.segment, data->id.bus, data->id.device, + data->id.function)); + + /* + * TBD: Support slot devices (e.g. function=0xFFFF). + */ + + /* + * Locate PCI Device + * ----------------- + * Locate matching device in PCI namespace. If it doesn't exist + * this typically means that the device isn't currently inserted + * (e.g. docking station, port replicator, etc.). + */ + data->dev = pci_get_slot(pdata->bus, + PCI_DEVFN(data->id.device, data->id.function)); + if (!data->dev) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Device %04x:%02x:%02x.%d not present in PCI namespace\n", + data->id.segment, data->id.bus, + data->id.device, data->id.function)); + result = -ENODEV; + goto end; + } + if (!data->dev->bus) { + printk(KERN_ERR PREFIX + "Device %04x:%02x:%02x.%d has invalid 'bus' field\n", + data->id.segment, data->id.bus, + data->id.device, data->id.function); + result = -ENODEV; + goto end; + } /* - * Install the 'bind' function to facilitate callbacks for - * children of the P2P bridge. + * PCI Bridge? + * ----------- + * If so, set the 'bus' field and install the 'bind' function to + * facilitate callbacks for all of its children. */ - if (dev->subordinate) { + if (data->dev->subordinate) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %04x:%02x:%02x.%d is a PCI bridge\n", - pci_domain_nr(dev->bus), dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn))); + data->id.segment, data->id.bus, + data->id.device, data->id.function)); + data->bus = data->dev->subordinate; device->ops.bind = acpi_pci_bind; device->ops.unbind = acpi_pci_unbind; } /* - * Evaluate and parse _PRT, if exists. This code allows parsing of - * _PRT objects within the scope of non-bridge devices. Note that - * _PRTs within the scope of a PCI bridge assume the bridge's - * subordinate bus number. + * Attach ACPI-PCI Context + * ----------------------- + * Thus binding the ACPI and PCI devices. + */ + status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Unable to attach ACPI-PCI context to device %s", + acpi_device_bid(device))); + result = -ENODEV; + goto end; + } + + /* + * PCI Routing Table + * ----------------- + * Evaluate and parse _PRT, if exists. This code is independent of + * PCI bridges (above) to allow parsing of _PRT objects within the + * scope of non-bridge devices. Note that _PRTs within the scope of + * a PCI bridge assume the bridge's subordinate bus number. * * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? */ status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); + if (ACPI_SUCCESS(status)) { + if (data->bus) /* PCI-PCI bridge */ + acpi_pci_irq_add_prt(device->handle, data->id.segment, + data->bus->number); + else /* non-bridge PCI device */ + acpi_pci_irq_add_prt(device->handle, data->id.segment, + data->id.bus); + } + + end: + kfree(buffer.pointer); + if (result) { + pci_dev_put(data->dev); + kfree(data); + } + return result; +} + +static int acpi_pci_unbind(struct acpi_device *device) +{ + int result = 0; + acpi_status status; + struct acpi_pci_data *data; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + + if (!device || !device->parent) + return -EINVAL; + + status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); if (ACPI_FAILURE(status)) - goto out; + return -ENODEV; - if (dev->subordinate) - bus = dev->subordinate; - else - bus = dev->bus; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n", + (char *) buffer.pointer)); + kfree(buffer.pointer); - acpi_pci_irq_add_prt(device->handle, bus); + status = + acpi_get_data(device->handle, acpi_pci_data_handler, + (void **)&data); + if (ACPI_FAILURE(status)) { + result = -ENODEV; + goto end; + } -out: - pci_dev_put(dev); - return 0; + status = acpi_detach_data(device->handle, acpi_pci_data_handler); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Unable to detach data from device %s", + acpi_device_bid(device))); + result = -ENODEV; + goto end; + } + if (data->dev->subordinate) { + acpi_pci_irq_del_prt(data->id.segment, data->bus->number); + } + pci_dev_put(data->dev); + kfree(data); + + end: + return result; } -int acpi_pci_bind_root(struct acpi_device *device) +int +acpi_pci_bind_root(struct acpi_device *device, + struct acpi_pci_id *id, struct pci_bus *bus) { + int result = 0; + acpi_status status; + struct acpi_pci_data *data = NULL; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + if (!device || !id || !bus) { + return -EINVAL; + } + + data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->id = *id; + data->bus = bus; device->ops.bind = acpi_pci_bind; device->ops.unbind = acpi_pci_unbind; - return 0; + status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); + if (ACPI_FAILURE(status)) { + kfree (data); + return -ENODEV; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to " + "%04x:%02x\n", (char *)buffer.pointer, + id->segment, id->bus)); + + status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Unable to attach ACPI-PCI context to device %s", + (char *)buffer.pointer)); + result = -ENODEV; + goto end; + } + + end: + kfree(buffer.pointer); + if (result != 0) + kfree(data); + + return result; } diff --git a/trunk/drivers/acpi/pci_irq.c b/trunk/drivers/acpi/pci_irq.c index b794eb88ab90..2faa9e2ac893 100644 --- a/trunk/drivers/acpi/pci_irq.c +++ b/trunk/drivers/acpi/pci_irq.c @@ -182,7 +182,7 @@ static void do_prt_fixups(struct acpi_prt_entry *entry, } } -static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus, +static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, struct acpi_pci_routing_table *prt) { struct acpi_prt_entry *entry; @@ -196,8 +196,8 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus, * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert * it here. */ - entry->id.segment = pci_domain_nr(bus); - entry->id.bus = bus->number; + entry->id.segment = segment; + entry->id.bus = bus; entry->id.device = (prt->address >> 16) & 0xFFFF; entry->pin = prt->pin + 1; @@ -242,7 +242,7 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus, return 0; } -int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus) +int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) { acpi_status status; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -271,7 +271,7 @@ int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus) entry = buffer.pointer; while (entry && (entry->length > 0)) { - acpi_pci_irq_add_entry(handle, bus, entry); + acpi_pci_irq_add_entry(handle, segment, bus, entry); entry = (struct acpi_pci_routing_table *) ((unsigned long)entry + entry->length); } @@ -280,17 +280,16 @@ int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus) return 0; } -void acpi_pci_irq_del_prt(struct pci_bus *bus) +void acpi_pci_irq_del_prt(int segment, int bus) { struct acpi_prt_entry *entry, *tmp; printk(KERN_DEBUG "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", - pci_domain_nr(bus), bus->number); + segment, bus); spin_lock(&acpi_prt_lock); list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { - if (pci_domain_nr(bus) == entry->id.segment - && bus->number == entry->id.bus) { + if (segment == entry->id.segment && bus == entry->id.bus) { list_del(&entry->list); kfree(entry); } diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 55b5b90c2a44..196f97d00956 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -63,10 +63,9 @@ static struct acpi_driver acpi_pci_root_driver = { struct acpi_pci_root { struct list_head node; - struct acpi_device *device; + struct acpi_device * device; + struct acpi_pci_id id; struct pci_bus *bus; - u16 segment; - u8 bus_nr; u32 osc_support_set; /* _OSC state of support bits */ u32 osc_control_set; /* _OSC state of control bits */ @@ -83,7 +82,7 @@ static DEFINE_MUTEX(osc_lock); int acpi_pci_register_driver(struct acpi_pci_driver *driver) { int n = 0; - struct acpi_pci_root *root; + struct list_head *entry; struct acpi_pci_driver **pptr = &sub_driver; while (*pptr) @@ -93,7 +92,9 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver) if (!driver->add) return 0; - list_for_each_entry(root, &acpi_pci_roots, node) { + list_for_each(entry, &acpi_pci_roots) { + struct acpi_pci_root *root; + root = list_entry(entry, struct acpi_pci_root, node); driver->add(root->device->handle); n++; } @@ -105,7 +106,7 @@ EXPORT_SYMBOL(acpi_pci_register_driver); void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) { - struct acpi_pci_root *root; + struct list_head *entry; struct acpi_pci_driver **pptr = &sub_driver; while (*pptr) { @@ -119,48 +120,28 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) if (!driver->remove) return; - list_for_each_entry(root, &acpi_pci_roots, node) + list_for_each(entry, &acpi_pci_roots) { + struct acpi_pci_root *root; + root = list_entry(entry, struct acpi_pci_root, node); driver->remove(root->device->handle); + } } EXPORT_SYMBOL(acpi_pci_unregister_driver); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) { - struct acpi_pci_root *root; + struct acpi_pci_root *tmp; - list_for_each_entry(root, &acpi_pci_roots, node) - if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus)) - return root->device->handle; + list_for_each_entry(tmp, &acpi_pci_roots, node) { + if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) + return tmp->device->handle; + } return NULL; } EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); -/** - * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge - * @handle - the ACPI CA node in question. - * - * Note: we could make this API take a struct acpi_device * instead, but - * for now, it's more convenient to operate on an acpi_handle. - */ -int acpi_is_root_bridge(acpi_handle handle) -{ - int ret; - struct acpi_device *device; - - ret = acpi_bus_get_device(handle, &device); - if (ret) - return 0; - - ret = acpi_match_device_ids(device, root_device_ids); - if (ret) - return 0; - else - return 1; -} -EXPORT_SYMBOL_GPL(acpi_is_root_bridge); - static acpi_status get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { @@ -180,22 +161,19 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) return AE_OK; } -static acpi_status try_get_root_bridge_busnr(acpi_handle handle, - unsigned long long *bus) +static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) { acpi_status status; - int busnum; - busnum = -1; + *busnum = -1; status = acpi_walk_resources(handle, METHOD_NAME__CRS, - get_root_bridge_busnr_callback, &busnum); + get_root_bridge_busnr_callback, busnum); if (ACPI_FAILURE(status)) return status; /* Check if we really get a bus number from _CRS */ - if (busnum == -1) + if (*busnum == -1) return AE_ERROR; - *bus = busnum; return AE_OK; } @@ -320,7 +298,6 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) { struct acpi_pci_root *root; - list_for_each_entry(root, &acpi_pci_roots, node) { if (root->device->handle == handle) return root; @@ -328,87 +305,6 @@ static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) return NULL; } -struct acpi_handle_node { - struct list_head node; - acpi_handle handle; -}; - -/** - * acpi_get_pci_dev - convert ACPI CA handle to struct pci_dev - * @handle: the handle in question - * - * Given an ACPI CA handle, the desired PCI device is located in the - * list of PCI devices. - * - * If the device is found, its reference count is increased and this - * function returns a pointer to its data structure. The caller must - * decrement the reference count by calling pci_dev_put(). - * If no device is found, %NULL is returned. - */ -struct pci_dev *acpi_get_pci_dev(acpi_handle handle) -{ - int dev, fn; - unsigned long long adr; - acpi_status status; - acpi_handle phandle; - struct pci_bus *pbus; - struct pci_dev *pdev = NULL; - struct acpi_handle_node *node, *tmp; - struct acpi_pci_root *root; - LIST_HEAD(device_list); - - /* - * Walk up the ACPI CA namespace until we reach a PCI root bridge. - */ - phandle = handle; - while (!acpi_is_root_bridge(phandle)) { - node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL); - if (!node) - goto out; - - INIT_LIST_HEAD(&node->node); - node->handle = phandle; - list_add(&node->node, &device_list); - - status = acpi_get_parent(phandle, &phandle); - if (ACPI_FAILURE(status)) - goto out; - } - - root = acpi_pci_find_root(phandle); - if (!root) - goto out; - - pbus = root->bus; - - /* - * Now, walk back down the PCI device tree until we return to our - * original handle. Assumes that everything between the PCI root - * bridge and the device we're looking for must be a P2P bridge. - */ - list_for_each_entry(node, &device_list, node) { - acpi_handle hnd = node->handle; - status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr); - if (ACPI_FAILURE(status)) - goto out; - dev = (adr >> 16) & 0xffff; - fn = adr & 0xffff; - - pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); - if (!pdev || hnd == handle) - break; - - pbus = pdev->subordinate; - pci_dev_put(pdev); - } -out: - list_for_each_entry_safe(node, tmp, &device_list, node) - kfree(node); - - return pdev; -} -EXPORT_SYMBOL_GPL(acpi_get_pci_dev); - /** * acpi_pci_osc_control_set - commit requested control to Firmware * @handle: acpi_handle for the target ACPI object @@ -467,46 +363,31 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set); static int __devinit acpi_pci_root_add(struct acpi_device *device) { - unsigned long long segment, bus; - acpi_status status; - int result; - struct acpi_pci_root *root; - acpi_handle handle; + int result = 0; + struct acpi_pci_root *root = NULL; + struct acpi_pci_root *tmp; + acpi_status status = AE_OK; + unsigned long long value = 0; + acpi_handle handle = NULL; struct acpi_device *child; u32 flags, base_flags; - segment = 0; - status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, - &segment); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); - return -ENODEV; - } - /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ - bus = 0; - status = try_get_root_bridge_busnr(device->handle, &bus); - if (ACPI_FAILURE(status)) { - status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - printk(KERN_ERR PREFIX - "no bus number in _CRS and can't evaluate _BBN\n"); - return -ENODEV; - } - } + if (!device) + return -EINVAL; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) return -ENOMEM; - INIT_LIST_HEAD(&root->node); + root->device = device; - root->segment = segment & 0xFFFF; - root->bus_nr = bus & 0xFF; strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); device->driver_data = root; + device->ops.bind = acpi_pci_bind; + /* * All supported architectures that use ACPI have support for * PCI domains, so we indicate this in _OSC support capabilities. @@ -514,6 +395,79 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; acpi_pci_osc_support(root, flags); + /* + * Segment + * ------- + * Obtained via _SEG, if exists, otherwise assumed to be zero (0). + */ + status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, + &value); + switch (status) { + case AE_OK: + root->id.segment = (u16) value; + break; + case AE_NOT_FOUND: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Assuming segment 0 (no _SEG)\n")); + root->id.segment = 0; + break; + default: + ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SEG")); + result = -ENODEV; + goto end; + } + + /* + * Bus + * --- + * Obtained via _BBN, if exists, otherwise assumed to be zero (0). + */ + status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, + &value); + switch (status) { + case AE_OK: + root->id.bus = (u16) value; + break; + case AE_NOT_FOUND: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n")); + root->id.bus = 0; + break; + default: + ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BBN")); + result = -ENODEV; + goto end; + } + + /* Some systems have wrong _BBN */ + list_for_each_entry(tmp, &acpi_pci_roots, node) { + if ((tmp->id.segment == root->id.segment) + && (tmp->id.bus == root->id.bus)) { + int bus = 0; + acpi_status status; + + printk(KERN_ERR PREFIX + "Wrong _BBN value, reboot" + " and use option 'pci=noacpi'\n"); + + status = try_get_root_bridge_busnr(device->handle, &bus); + if (ACPI_FAILURE(status)) + break; + if (bus != root->id.bus) { + printk(KERN_INFO PREFIX + "PCI _CRS %d overrides _BBN 0\n", bus); + root->id.bus = bus; + } + break; + } + } + /* + * Device & Function + * ----------------- + * Obtained from _ADR (which has already been evaluated for us). + */ + root->id.device = device->pnp.bus_address >> 16; + root->id.function = device->pnp.bus_address & 0xFFFF; + /* * TBD: Need PCI interface for enumeration/configuration of roots. */ @@ -523,7 +477,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", acpi_device_name(device), acpi_device_bid(device), - root->segment, root->bus_nr); + root->id.segment, root->id.bus); /* * Scan the Root Bridge @@ -532,11 +486,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) * PCI namespace does not get created until this call is made (and * thus the root bridge's pci_dev does not exist). */ - root->bus = pci_acpi_scan_root(device, segment, bus); + root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus); if (!root->bus) { printk(KERN_ERR PREFIX "Bus %04x:%02x not present in PCI namespace\n", - root->segment, root->bus_nr); + root->id.segment, root->id.bus); result = -ENODEV; goto end; } @@ -546,7 +500,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) * ----------------------- * Thus binding the ACPI and PCI devices. */ - result = acpi_pci_bind_root(device); + result = acpi_pci_bind_root(device, &root->id, root->bus); if (result) goto end; @@ -557,7 +511,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) */ status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); if (ACPI_SUCCESS(status)) - result = acpi_pci_irq_add_prt(device->handle, root->bus); + result = acpi_pci_irq_add_prt(device->handle, root->id.segment, + root->id.bus); /* * Scan and bind all _ADR-Based Devices @@ -576,28 +531,42 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) if (flags != base_flags) acpi_pci_osc_support(root, flags); - return 0; + end: + if (result) { + if (!list_empty(&root->node)) + list_del(&root->node); + kfree(root); + } -end: - if (!list_empty(&root->node)) - list_del(&root->node); - kfree(root); return result; } static int acpi_pci_root_start(struct acpi_device *device) { - struct acpi_pci_root *root = acpi_driver_data(device); + struct acpi_pci_root *root; - pci_bus_add_devices(root->bus); - return 0; + + list_for_each_entry(root, &acpi_pci_roots, node) { + if (root->device == device) { + pci_bus_add_devices(root->bus); + return 0; + } + } + return -ENODEV; } static int acpi_pci_root_remove(struct acpi_device *device, int type) { - struct acpi_pci_root *root = acpi_driver_data(device); + struct acpi_pci_root *root = NULL; + + + if (!device || !acpi_driver_data(device)) + return -EINVAL; + + root = acpi_driver_data(device); kfree(root); + return 0; } diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index d74365d4a6e7..56665a63bf19 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -194,7 +194,7 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) { - int result = 0; + int result = 0, state; int found = 0; acpi_status status = AE_OK; struct acpi_power_resource *resource = NULL; @@ -236,6 +236,18 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) if (ACPI_FAILURE(status)) return -ENODEV; + if (!acpi_power_nocheck) { + /* + * If acpi_power_nocheck is set, it is unnecessary to check + * the power state after power transition. + */ + result = acpi_power_get_state(resource->device->handle, + &state); + if (result) + return result; + if (state != ACPI_POWER_RESOURCE_STATE_ON) + return -ENOEXEC; + } /* Update the power resource's _device_ power state */ resource->device->power.state = ACPI_STATE_D0; @@ -246,7 +258,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) { - int result = 0; + int result = 0, state; acpi_status status = AE_OK; struct acpi_power_resource *resource = NULL; struct list_head *node, *next; @@ -281,6 +293,18 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) if (ACPI_FAILURE(status)) return -ENODEV; + if (!acpi_power_nocheck) { + /* + * If acpi_power_nocheck is set, it is unnecessary to check + * the power state after power transition. + */ + result = acpi_power_get_state(handle, &state); + if (result) + return result; + if (state != ACPI_POWER_RESOURCE_STATE_OFF) + return -ENOEXEC; + } + /* Update the power resource's _device_ power state */ resource->device->power.state = ACPI_STATE_D3; diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 84e0f3c07442..23f0fb84f1c1 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -89,7 +89,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr); static const struct acpi_device_id processor_device_ids[] = { {ACPI_PROCESSOR_OBJECT_HID, 0}, - {"ACPI0007", 0}, + {ACPI_PROCESSOR_HID, 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, processor_device_ids); @@ -596,21 +596,7 @@ static int acpi_processor_get_info(struct acpi_device *device) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No bus mastering arbitration control\n")); - if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) { - /* Declared with "Processor" statement; match ProcessorID */ - status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Evaluating processor object\n"); - return -ENODEV; - } - - /* - * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. - * >>> 'acpi_get_processor_id(acpi_id, &id)' in - * arch/xxx/acpi.c - */ - pr->acpi_id = object.processor.proc_id; - } else { + if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) { /* * Declared with "Device" statement; match _UID. * Note that we don't handle string _UIDs yet. @@ -625,6 +611,20 @@ static int acpi_processor_get_info(struct acpi_device *device) } device_declaration = 1; pr->acpi_id = value; + } else { + /* Declared with "Processor" statement; match ProcessorID */ + status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Evaluating processor object\n"); + return -ENODEV; + } + + /* + * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. + * >>> 'acpi_get_processor_id(acpi_id, &id)' in + * arch/xxx/acpi.c + */ + pr->acpi_id = object.processor.proc_id; } cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); @@ -649,16 +649,7 @@ static int acpi_processor_get_info(struct acpi_device *device) return -ENODEV; } } - /* - * On some boxes several processors use the same processor bus id. - * But they are located in different scope. For example: - * \_SB.SCK0.CPU0 - * \_SB.SCK1.CPU0 - * Rename the processor device bus id. And the new bus id will be - * generated as the following format: - * CPU+CPU ID. - */ - sprintf(acpi_device_bid(device), "CPU%X", pr->id); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, pr->acpi_id)); @@ -740,8 +731,6 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) /* _PDC call should be done before doing anything else (if reqd.). */ arch_acpi_processor_init_pdc(pr); acpi_processor_set_pdc(pr); - arch_acpi_processor_cleanup_pdc(pr); - #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr); #endif diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 0efa59e7e3af..10a2d913635a 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -139,7 +139,7 @@ static void acpi_safe_halt(void) * are affected too. We pick the most conservative approach: we assume * that the local APIC stops in both C2 and C3. */ -static void lapic_timer_check_state(int state, struct acpi_processor *pr, +static void acpi_timer_check_state(int state, struct acpi_processor *pr, struct acpi_processor_cx *cx) { struct acpi_processor_power *pwr = &pr->power; @@ -162,7 +162,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr, pr->power.timer_broadcast_on_state = state; } -static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) +static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { unsigned long reason; @@ -173,7 +173,7 @@ static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) } /* Power(C) State timer broadcast control */ -static void lapic_timer_state_broadcast(struct acpi_processor *pr, +static void acpi_state_timer_broadcast(struct acpi_processor *pr, struct acpi_processor_cx *cx, int broadcast) { @@ -190,10 +190,10 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, #else -static void lapic_timer_check_state(int state, struct acpi_processor *pr, +static void acpi_timer_check_state(int state, struct acpi_processor *pr, struct acpi_processor_cx *cstate) { } -static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { } -static void lapic_timer_state_broadcast(struct acpi_processor *pr, +static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { } +static void acpi_state_timer_broadcast(struct acpi_processor *pr, struct acpi_processor_cx *cx, int broadcast) { @@ -515,8 +515,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx) static void acpi_processor_power_verify_c3(struct acpi_processor *pr, struct acpi_processor_cx *cx) { - static int bm_check_flag = -1; - static int bm_control_flag = -1; + static int bm_check_flag; if (!cx->address) @@ -546,14 +545,12 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, } /* All the logic here assumes flags.bm_check is same across all CPUs */ - if (bm_check_flag == -1) { + if (!bm_check_flag) { /* Determine whether bm_check is needed based on CPU */ acpi_processor_power_init_bm_check(&(pr->flags), pr->id); bm_check_flag = pr->flags.bm_check; - bm_control_flag = pr->flags.bm_control; } else { pr->flags.bm_check = bm_check_flag; - pr->flags.bm_control = bm_control_flag; } if (pr->flags.bm_check) { @@ -617,25 +614,29 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) switch (cx->type) { case ACPI_STATE_C1: cx->valid = 1; + acpi_timer_check_state(i, pr, cx); break; case ACPI_STATE_C2: acpi_processor_power_verify_c2(cx); + if (cx->valid) + acpi_timer_check_state(i, pr, cx); break; case ACPI_STATE_C3: acpi_processor_power_verify_c3(pr, cx); + if (cx->valid) + acpi_timer_check_state(i, pr, cx); break; } - if (!cx->valid) - continue; + if (cx->valid) + tsc_check_state(cx->type); - lapic_timer_check_state(i, pr, cx); - tsc_check_state(cx->type); - working++; + if (cx->valid) + working++; } - lapic_timer_propagate_broadcast(pr); + acpi_propagate_timer_broadcast(pr); return (working); } @@ -838,7 +839,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, return 0; } - lapic_timer_state_broadcast(pr, cx, 1); + acpi_state_timer_broadcast(pr, cx, 1); kt1 = ktime_get_real(); acpi_idle_do_entry(cx); kt2 = ktime_get_real(); @@ -846,7 +847,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, local_irq_enable(); cx->usage++; - lapic_timer_state_broadcast(pr, cx, 0); + acpi_state_timer_broadcast(pr, cx, 0); return idle_time; } @@ -891,7 +892,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, * Must be done before busmaster disable as we might need to * access HPET ! */ - lapic_timer_state_broadcast(pr, cx, 1); + acpi_state_timer_broadcast(pr, cx, 1); if (cx->type == ACPI_STATE_C3) ACPI_FLUSH_CPU_CACHE(); @@ -913,7 +914,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, cx->usage++; - lapic_timer_state_broadcast(pr, cx, 0); + acpi_state_timer_broadcast(pr, cx, 0); cx->time += sleep_ticks; return idle_time; } @@ -980,7 +981,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, * Must be done before busmaster disable as we might need to * access HPET ! */ - lapic_timer_state_broadcast(pr, cx, 1); + acpi_state_timer_broadcast(pr, cx, 1); kt1 = ktime_get_real(); /* @@ -1025,7 +1026,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, cx->usage++; - lapic_timer_state_broadcast(pr, cx, 0); + acpi_state_timer_broadcast(pr, cx, 0); cx->time += sleep_ticks; return idle_time; } diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 781435d7e369..8ff510b91d88 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -95,7 +95,7 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha } static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); -static void acpi_bus_hot_remove_device(void *context) +static int acpi_bus_hot_remove_device(void *context) { struct acpi_device *device; acpi_handle handle = context; @@ -104,10 +104,10 @@ static void acpi_bus_hot_remove_device(void *context) acpi_status status = AE_OK; if (acpi_bus_get_device(handle, &device)) - return; + return 0; if (!device) - return; + return 0; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Hot-removing device %s...\n", dev_name(&device->dev))); @@ -115,7 +115,7 @@ static void acpi_bus_hot_remove_device(void *context) if (acpi_bus_trim(device, 1)) { printk(KERN_ERR PREFIX "Removing device failed\n"); - return; + return -1; } /* power off device */ @@ -142,10 +142,9 @@ static void acpi_bus_hot_remove_device(void *context) */ status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); if (ACPI_FAILURE(status)) - printk(KERN_WARNING PREFIX - "Eject device failed\n"); + return -ENODEV; - return; + return 0; } static ssize_t @@ -156,6 +155,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, acpi_status status; acpi_object_type type = 0; struct acpi_device *acpi_device = to_acpi_device(d); + struct task_struct *task; if ((!count) || (buf[0] != '1')) { return -EINVAL; @@ -172,7 +172,11 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, goto err; } - acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_device->handle); + /* remove the device in another thread to fix the deadlock issue */ + task = kthread_run(acpi_bus_hot_remove_device, + acpi_device->handle, "acpi_hot_remove_device"); + if (IS_ERR(task)) + ret = PTR_ERR(task); err: return ret; } @@ -194,12 +198,12 @@ acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *b int result; result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); - if (result) + if(result) goto end; result = sprintf(buf, "%s\n", (char*)path.pointer); kfree(path.pointer); -end: + end: return result; } static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); @@ -213,21 +217,21 @@ static int acpi_device_setup_files(struct acpi_device *dev) /* * Devices gotten from FADT don't have a "path" attribute */ - if (dev->handle) { + if(dev->handle) { result = device_create_file(&dev->dev, &dev_attr_path); - if (result) + if(result) goto end; } - if (dev->flags.hardware_id) { + if(dev->flags.hardware_id) { result = device_create_file(&dev->dev, &dev_attr_hid); - if (result) + if(result) goto end; } - if (dev->flags.hardware_id || dev->flags.compatible_ids) { + if (dev->flags.hardware_id || dev->flags.compatible_ids){ result = device_create_file(&dev->dev, &dev_attr_modalias); - if (result) + if(result) goto end; } @@ -238,7 +242,7 @@ static int acpi_device_setup_files(struct acpi_device *dev) status = acpi_get_handle(dev->handle, "_EJ0", &temp); if (ACPI_SUCCESS(status)) result = device_create_file(&dev->dev, &dev_attr_eject); -end: + end: return result; } @@ -258,9 +262,9 @@ static void acpi_device_remove_files(struct acpi_device *dev) if (dev->flags.hardware_id || dev->flags.compatible_ids) device_remove_file(&dev->dev, &dev_attr_modalias); - if (dev->flags.hardware_id) + if(dev->flags.hardware_id) device_remove_file(&dev->dev, &dev_attr_hid); - if (dev->handle) + if(dev->handle) device_remove_file(&dev->dev, &dev_attr_path); } /* -------------------------------------------------------------------------- @@ -508,7 +512,7 @@ static int acpi_device_register(struct acpi_device *device, break; } } - if (!found) { + if(!found) { acpi_device_bus_id = new_bus_id; strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device"); acpi_device_bus_id->instance_no = 0; @@ -526,21 +530,22 @@ static int acpi_device_register(struct acpi_device *device, if (device->parent) device->dev.parent = &parent->dev; device->dev.bus = &acpi_bus_type; + device_initialize(&device->dev); device->dev.release = &acpi_device_release; - result = device_register(&device->dev); - if (result) { - dev_err(&device->dev, "Error registering device\n"); + result = device_add(&device->dev); + if(result) { + dev_err(&device->dev, "Error adding device\n"); goto end; } result = acpi_device_setup_files(device); - if (result) + if(result) printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", dev_name(&device->dev)); device->removal_type = ACPI_BUS_REMOVAL_NORMAL; return 0; -end: + end: mutex_lock(&acpi_device_lock); if (device->parent) list_del(&device->node); @@ -572,7 +577,7 @@ static void acpi_device_unregister(struct acpi_device *device, int type) * @device: the device to add and initialize * @driver: driver for the device * - * Used to initialize a device via its device driver. Called whenever a + * Used to initialize a device via its device driver. Called whenever a * driver is bound to a device. Invokes the driver's add() ops. */ static int @@ -580,6 +585,7 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) { int result = 0; + if (!device || !driver) return -EINVAL; @@ -796,7 +802,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) if (!acpi_match_device_ids(device, button_device_ids)) device->wakeup.flags.run_wake = 1; -end: + end: if (ACPI_FAILURE(status)) device->flags.wake_capable = 0; return 0; @@ -1064,7 +1070,7 @@ static void acpi_device_set_id(struct acpi_device *device, break; } - /* + /* * \_SB * ---- * Fix for the system root bus device -- the only root-level device. @@ -1314,7 +1320,7 @@ acpi_add_single_object(struct acpi_device **child, device->parent->ops.bind(device); } -end: + end: if (!result) *child = device; else { @@ -1458,6 +1464,7 @@ acpi_bus_add(struct acpi_device **child, return result; } + EXPORT_SYMBOL(acpi_bus_add); int acpi_bus_start(struct acpi_device *device) @@ -1477,6 +1484,7 @@ int acpi_bus_start(struct acpi_device *device) } return result; } + EXPORT_SYMBOL(acpi_bus_start); int acpi_bus_trim(struct acpi_device *start, int rmdevice) @@ -1534,6 +1542,7 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice) } EXPORT_SYMBOL_GPL(acpi_bus_trim); + static int acpi_bus_scan_fixed(struct acpi_device *root) { int result = 0; @@ -1601,6 +1610,6 @@ int __init acpi_scan_init(void) if (result) acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); -Done: + Done: return result; } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 8851315ce858..1bdfb37377e3 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -76,7 +76,6 @@ MODULE_LICENSE("GPL"); static int brightness_switch_enabled = 1; module_param(brightness_switch_enabled, bool, 0644); -static int register_count = 0; static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_remove(struct acpi_device *device, int type); static int acpi_video_resume(struct acpi_device *device); @@ -587,14 +586,6 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), }, }, - { - .callback = video_set_bqc_offset, - .ident = "Acer Aspire 7720", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), - }, - }, {} }; @@ -985,11 +976,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) device->backlight->props.max_brightness = device->brightness->count-3; kfree(name); - result = sysfs_create_link(&device->backlight->dev.kobj, - &device->dev->dev.kobj, "device"); - if (result) - printk(KERN_ERR PREFIX "Create sysfs link\n"); - device->cdev = thermal_cooling_device_register("LCD", device->dev, &video_cooling_ops); if (IS_ERR(device->cdev)) @@ -1068,15 +1054,15 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) static int acpi_video_bus_check(struct acpi_video_bus *video) { acpi_status status = -ENOENT; - struct pci_dev *dev; + struct device *dev; if (!video) return -EINVAL; - dev = acpi_get_pci_dev(video->device->handle); + dev = acpi_get_physical_pci_device(video->device->handle); if (!dev) return -ENODEV; - pci_dev_put(dev); + put_device(dev); /* Since there is no HID, CID and so on for VGA driver, we have * to check well known required nodes. @@ -2004,7 +1990,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) status = acpi_remove_notify_handler(device->dev->handle, ACPI_DEVICE_NOTIFY, acpi_video_device_notify); - sysfs_remove_link(&device->backlight->dev.kobj, "device"); backlight_device_unregister(device->backlight); if (device->cdev) { sysfs_remove_link(&device->dev->dev.kobj, @@ -2333,13 +2318,6 @@ static int __init intel_opregion_present(void) int acpi_video_register(void) { int result = 0; - if (register_count) { - /* - * if the function of acpi_video_register is already called, - * don't register the acpi_vide_bus again and return no error. - */ - return 0; - } acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); if (!acpi_video_dir) @@ -2351,35 +2329,10 @@ int acpi_video_register(void) return -ENODEV; } - /* - * When the acpi_video_bus is loaded successfully, increase - * the counter reference. - */ - register_count = 1; - return 0; } EXPORT_SYMBOL(acpi_video_register); -void acpi_video_unregister(void) -{ - if (!register_count) { - /* - * If the acpi video bus is already unloaded, don't - * unload it again and return directly. - */ - return; - } - acpi_bus_unregister_driver(&acpi_video_bus); - - remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); - - register_count = 0; - - return; -} -EXPORT_SYMBOL(acpi_video_unregister); - /* * This is kind of nasty. Hardware using Intel chipsets may require * the video opregion code to be run first in order to initialise @@ -2397,12 +2350,16 @@ static int __init acpi_video_init(void) return acpi_video_register(); } -static void __exit acpi_video_exit(void) +void acpi_video_exit(void) { - acpi_video_unregister(); + + acpi_bus_unregister_driver(&acpi_video_bus); + + remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); return; } +EXPORT_SYMBOL(acpi_video_exit); module_init(acpi_video_init); module_exit(acpi_video_exit); diff --git a/trunk/drivers/acpi/video_detect.c b/trunk/drivers/acpi/video_detect.c index 7cd2b63435ea..09737275e25f 100644 --- a/trunk/drivers/acpi/video_detect.c +++ b/trunk/drivers/acpi/video_detect.c @@ -10,7 +10,7 @@ * assinged * * After PCI devices are glued with ACPI devices - * acpi_get_pci_dev() can be called to identify ACPI graphics + * acpi_get_physical_pci_device() can be called to identify ACPI graphics * devices for which a real graphics card is plugged in * * Now acpi_video_get_capabilities() can be called to check which @@ -36,7 +36,6 @@ #include #include -#include ACPI_MODULE_NAME("video"); #define _COMPONENT ACPI_VIDEO_COMPONENT @@ -110,7 +109,7 @@ static acpi_status find_video(acpi_handle handle, u32 lvl, void *context, void **rv) { long *cap = context; - struct pci_dev *dev; + struct device *dev; struct acpi_device *acpi_dev; const struct acpi_device_id video_ids[] = { @@ -121,10 +120,10 @@ find_video(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; if (!acpi_match_device_ids(acpi_dev, video_ids)) { - dev = acpi_get_pci_dev(handle); + dev = acpi_get_physical_pci_device(handle); if (!dev) return AE_OK; - pci_dev_put(dev); + put_device(dev); *cap |= acpi_is_video_device(acpi_dev); } return AE_OK; diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index b17c57f85032..2aa1908e5ce0 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -679,14 +679,6 @@ config PATA_PLATFORM If unsure, say N. -config PATA_AT91 - tristate "PATA support for AT91SAM9260" - depends on ARM && ARCH_AT91 - help - This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. - - If unsure, say N. - config PATA_OF_PLATFORM tristate "OpenFirmware platform device PATA support" depends on PATA_PLATFORM && PPC_OF diff --git a/trunk/drivers/ata/Makefile b/trunk/drivers/ata/Makefile index 38906f9bbb4e..1558059874f0 100644 --- a/trunk/drivers/ata/Makefile +++ b/trunk/drivers/ata/Makefile @@ -72,7 +72,6 @@ obj-$(CONFIG_PATA_SCH) += pata_sch.o obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o -obj-$(CONFIG_PATA_AT91) += pata_at91.o obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o # Should be last but two libata driver diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 045a486a09ea..ca4d208ddf3b 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -125,19 +125,19 @@ MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link spe static int atapi_enabled = 1; module_param(atapi_enabled, int, 0444); -MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on [default])"); +MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); static int atapi_dmadir = 0; module_param(atapi_dmadir, int, 0444); -MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off [default], 1=on)"); +MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)"); int atapi_passthru16 = 1; module_param(atapi_passthru16, int, 0444); -MODULE_PARM_DESC(atapi_passthru16, "Enable ATA_16 passthru for ATAPI devices (0=off, 1=on [default])"); +MODULE_PARM_DESC(atapi_passthru16, "Enable ATA_16 passthru for ATAPI devices; on by default (0=off, 1=on)"); int libata_fua = 0; module_param_named(fua, libata_fua, int, 0444); -MODULE_PARM_DESC(fua, "FUA support (0=off [default], 1=on)"); +MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); static int ata_ignore_hpa; module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644); @@ -153,11 +153,11 @@ MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); int libata_noacpi = 0; module_param_named(noacpi, libata_noacpi, int, 0444); -MODULE_PARM_DESC(noacpi, "Disable the use of ACPI in probe/suspend/resume (0=off [default], 1=on)"); +MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in probe/suspend/resume when set"); int libata_allow_tpm = 0; module_param_named(allow_tpm, libata_allow_tpm, int, 0444); -MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands (0=off [default], 1=on)"); +MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands"); MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); @@ -1993,17 +1993,11 @@ unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd) * Check if the current speed of the device requires IORDY. Used * by various controllers for chip configuration. */ + unsigned int ata_pio_need_iordy(const struct ata_device *adev) { - /* Don't set IORDY if we're preparing for reset. IORDY may - * lead to controller lock up on certain controllers if the - * port is not occupied. See bko#11703 for details. - */ - if (adev->link->ap->pflags & ATA_PFLAG_RESETTING) - return 0; - /* Controller doesn't support IORDY. Probably a pointless - * check as the caller should know this. - */ + /* Controller doesn't support IORDY. Probably a pointless check + as the caller should know this */ if (adev->link->ap->flags & ATA_FLAG_NO_IORDY) return 0; /* CF spec. r4.1 Table 22 says no iordy on PIO5 and PIO6. */ @@ -2026,6 +2020,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) * Compute the highest mode possible if we are not using iordy. Return * -1 if no iordy mode is available. */ + static u32 ata_pio_mask_no_iordy(const struct ata_device *adev) { /* If we have no drive specific rule, then PIO 2 is non IORDY */ diff --git a/trunk/drivers/ata/pata_at91.c b/trunk/drivers/ata/pata_at91.c deleted file mode 100644 index 4b27617be26d..000000000000 --- a/trunk/drivers/ata/pata_at91.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * PATA driver for AT91SAM9260 Static Memory Controller - * with CompactFlash interface in True IDE mode - * - * Copyright (C) 2009 Matyukevich Sergey - * - * Based on: - * * generic platform driver by Paul Mundt: drivers/ata/pata_platform.c - * * pata_at32 driver by Kristoffer Nyborg Gregertsen - * * at91_ide driver by Stanislaw Gruszka - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -#define DRV_NAME "pata_at91" -#define DRV_VERSION "0.1" - -#define CF_IDE_OFFSET 0x00c00000 -#define CF_ALT_IDE_OFFSET 0x00e00000 -#define CF_IDE_RES_SIZE 0x08 - -struct at91_ide_info { - unsigned long mode; - unsigned int cs; - - void __iomem *ide_addr; - void __iomem *alt_addr; -}; - -const struct ata_timing initial_timing = - {XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0}; - -static unsigned int calc_mck_cycles(unsigned int ns, unsigned int mck_hz) -{ - unsigned long mul; - - /* - * cycles = x [nsec] * f [Hz] / 10^9 [ns in sec] = - * x * (f / 1_000_000_000) = - * x * ((f * 65536) / 1_000_000_000) / 65536 = - * x * (((f / 10_000) * 65536) / 100_000) / 65536 = - */ - - mul = (mck_hz / 10000) << 16; - mul /= 100000; - - return (ns * mul + 65536) >> 16; /* rounding */ -} - -static void set_smc_mode(struct at91_ide_info *info) -{ - at91_sys_write(AT91_SMC_MODE(info->cs), info->mode); - return; -} - -static void set_smc_timing(struct device *dev, - struct at91_ide_info *info, const struct ata_timing *ata) -{ - int read_cycle, write_cycle, active, recover; - int nrd_setup, nrd_pulse, nrd_recover; - int nwe_setup, nwe_pulse; - - int ncs_write_setup, ncs_write_pulse; - int ncs_read_setup, ncs_read_pulse; - - unsigned int mck_hz; - struct clk *mck; - - read_cycle = ata->cyc8b; - nrd_setup = ata->setup; - nrd_pulse = ata->act8b; - nrd_recover = ata->rec8b; - - mck = clk_get(NULL, "mck"); - BUG_ON(IS_ERR(mck)); - mck_hz = clk_get_rate(mck); - - read_cycle = calc_mck_cycles(read_cycle, mck_hz); - nrd_setup = calc_mck_cycles(nrd_setup, mck_hz); - nrd_pulse = calc_mck_cycles(nrd_pulse, mck_hz); - nrd_recover = calc_mck_cycles(nrd_recover, mck_hz); - - clk_put(mck); - - active = nrd_setup + nrd_pulse; - recover = read_cycle - active; - - /* Need at least two cycles recovery */ - if (recover < 2) - read_cycle = active + 2; - - /* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */ - ncs_read_setup = 1; - ncs_read_pulse = read_cycle - 2; - - /* Write timings same as read timings */ - write_cycle = read_cycle; - nwe_setup = nrd_setup; - nwe_pulse = nrd_pulse; - ncs_write_setup = ncs_read_setup; - ncs_write_pulse = ncs_read_pulse; - - dev_dbg(dev, "ATA timings: nrd_setup = %d nrd_pulse = %d nrd_cycle = %d\n", - nrd_setup, nrd_pulse, read_cycle); - dev_dbg(dev, "ATA timings: nwe_setup = %d nwe_pulse = %d nwe_cycle = %d\n", - nwe_setup, nwe_pulse, write_cycle); - dev_dbg(dev, "ATA timings: ncs_read_setup = %d ncs_read_pulse = %d\n", - ncs_read_setup, ncs_read_pulse); - dev_dbg(dev, "ATA timings: ncs_write_setup = %d ncs_write_pulse = %d\n", - ncs_write_setup, ncs_write_pulse); - - at91_sys_write(AT91_SMC_SETUP(info->cs), - AT91_SMC_NWESETUP_(nwe_setup) | - AT91_SMC_NRDSETUP_(nrd_setup) | - AT91_SMC_NCS_WRSETUP_(ncs_write_setup) | - AT91_SMC_NCS_RDSETUP_(ncs_read_setup)); - - at91_sys_write(AT91_SMC_PULSE(info->cs), - AT91_SMC_NWEPULSE_(nwe_pulse) | - AT91_SMC_NRDPULSE_(nrd_pulse) | - AT91_SMC_NCS_WRPULSE_(ncs_write_pulse) | - AT91_SMC_NCS_RDPULSE_(ncs_read_pulse)); - - at91_sys_write(AT91_SMC_CYCLE(info->cs), - AT91_SMC_NWECYCLE_(write_cycle) | - AT91_SMC_NRDCYCLE_(read_cycle)); - - return; -} - -static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev) -{ - struct at91_ide_info *info = ap->host->private_data; - struct ata_timing timing; - int ret; - - /* Compute ATA timing and set it to SMC */ - ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0); - if (ret) { - dev_warn(ap->dev, "Failed to compute ATA timing %d, \ - set PIO_0 timing\n", ret); - set_smc_timing(ap->dev, info, &initial_timing); - } else { - set_smc_timing(ap->dev, info, &timing); - } - - /* Setup SMC mode */ - set_smc_mode(info); - - return; -} - -static unsigned int pata_at91_data_xfer_noirq(struct ata_device *dev, - unsigned char *buf, unsigned int buflen, int rw) -{ - struct at91_ide_info *info = dev->link->ap->host->private_data; - unsigned int consumed; - unsigned long flags; - unsigned int mode; - - local_irq_save(flags); - mode = at91_sys_read(AT91_SMC_MODE(info->cs)); - - /* set 16bit mode before writing data */ - at91_sys_write(AT91_SMC_MODE(info->cs), - (mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_16); - - consumed = ata_sff_data_xfer(dev, buf, buflen, rw); - - /* restore 8bit mode after data is written */ - at91_sys_write(AT91_SMC_MODE(info->cs), - (mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_8); - - local_irq_restore(flags); - return consumed; -} - -static struct scsi_host_template pata_at91_sht = { - ATA_PIO_SHT(DRV_NAME), -}; - -static struct ata_port_operations pata_at91_port_ops = { - .inherits = &ata_sff_port_ops, - - .sff_data_xfer = pata_at91_data_xfer_noirq, - .set_piomode = pata_at91_set_piomode, - .cable_detect = ata_cable_40wire, - .port_start = ATA_OP_NULL, -}; - -static int __devinit pata_at91_probe(struct platform_device *pdev) -{ - struct at91_cf_data *board = pdev->dev.platform_data; - struct device *dev = &pdev->dev; - struct at91_ide_info *info; - struct resource *mem_res; - struct ata_host *host; - struct ata_port *ap; - int irq_flags = 0; - int irq = 0; - int ret; - - /* get platform resources: IO/CTL memories and irq/rst pins */ - - if (pdev->num_resources != 1) { - dev_err(&pdev->dev, "invalid number of resources\n"); - return -EINVAL; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!mem_res) { - dev_err(dev, "failed to get mem resource\n"); - return -EINVAL; - } - - irq = board->irq_pin; - - /* init ata host */ - - host = ata_host_alloc(dev, 1); - - if (!host) - return -ENOMEM; - - ap = host->ports[0]; - ap->ops = &pata_at91_port_ops; - ap->flags |= ATA_FLAG_SLAVE_POSS; - ap->pio_mask = ATA_PIO4; - - if (!irq) { - ap->flags |= ATA_FLAG_PIO_POLLING; - ata_port_desc(ap, "no IRQ, using PIO polling"); - } - - info = kzalloc(sizeof(*info), GFP_KERNEL); - - if (!info) { - dev_err(dev, "failed to allocate memory for private data\n"); - return -ENOMEM; - } - - info->cs = board->chipselect; - info->mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | - AT91_SMC_EXNWMODE_READY | AT91_SMC_BAT_SELECT | - AT91_SMC_DBW_8 | AT91_SMC_TDF_(0); - - info->ide_addr = devm_ioremap(dev, - mem_res->start + CF_IDE_OFFSET, CF_IDE_RES_SIZE); - - if (!info->ide_addr) { - dev_err(dev, "failed to map IO base\n"); - ret = -ENOMEM; - goto err_ide_ioremap; - } - - info->alt_addr = devm_ioremap(dev, - mem_res->start + CF_ALT_IDE_OFFSET, CF_IDE_RES_SIZE); - - if (!info->alt_addr) { - dev_err(dev, "failed to map CTL base\n"); - ret = -ENOMEM; - goto err_alt_ioremap; - } - - ap->ioaddr.cmd_addr = info->ide_addr; - ap->ioaddr.ctl_addr = info->alt_addr + 0x06; - ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; - - ata_sff_std_ports(&ap->ioaddr); - - ata_port_desc(ap, "mmio cmd 0x%llx ctl 0x%llx", - (unsigned long long)mem_res->start + CF_IDE_OFFSET, - (unsigned long long)mem_res->start + CF_ALT_IDE_OFFSET); - - host->private_data = info; - - return ata_host_activate(host, irq ? gpio_to_irq(irq) : 0, - irq ? ata_sff_interrupt : NULL, - irq_flags, &pata_at91_sht); - -err_alt_ioremap: - devm_iounmap(dev, info->ide_addr); - -err_ide_ioremap: - kfree(info); - - return ret; -} - -static int __devexit pata_at91_remove(struct platform_device *pdev) -{ - struct ata_host *host = dev_get_drvdata(&pdev->dev); - struct at91_ide_info *info = host->private_data; - struct device *dev = &pdev->dev; - - if (!host) - return 0; - - ata_host_detach(host); - - if (!info) - return 0; - - devm_iounmap(dev, info->ide_addr); - devm_iounmap(dev, info->alt_addr); - - kfree(info); - return 0; -} - -static struct platform_driver pata_at91_driver = { - .probe = pata_at91_probe, - .remove = __devexit_p(pata_at91_remove), - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init pata_at91_init(void) -{ - return platform_driver_register(&pata_at91_driver); -} - -static void __exit pata_at91_exit(void) -{ - platform_driver_unregister(&pata_at91_driver); -} - - -module_init(pata_at91_init); -module_exit(pata_at91_exit); - - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Driver for CF in True IDE mode on AT91SAM9260 SoC"); -MODULE_AUTHOR("Matyukevich Sergey"); -MODULE_VERSION(DRV_VERSION); - diff --git a/trunk/drivers/ata/sata_fsl.c b/trunk/drivers/ata/sata_fsl.c index 94eaa432c40a..36b8629203be 100644 --- a/trunk/drivers/ata/sata_fsl.c +++ b/trunk/drivers/ata/sata_fsl.c @@ -1378,37 +1378,6 @@ static int sata_fsl_remove(struct of_device *ofdev) return 0; } -#ifdef CONFIG_PM -static int sata_fsl_suspend(struct of_device *op, pm_message_t state) -{ - struct ata_host *host = dev_get_drvdata(&op->dev); - return ata_host_suspend(host, state); -} - -static int sata_fsl_resume(struct of_device *op) -{ - struct ata_host *host = dev_get_drvdata(&op->dev); - struct sata_fsl_host_priv *host_priv = host->private_data; - int ret; - void __iomem *hcr_base = host_priv->hcr_base; - struct ata_port *ap = host->ports[0]; - struct sata_fsl_port_priv *pp = ap->private_data; - - ret = sata_fsl_init_controller(host); - if (ret) { - dev_printk(KERN_ERR, &op->dev, - "Error initialize hardware\n"); - return ret; - } - - /* Recovery the CHBA register in host controller cmd register set */ - iowrite32(pp->cmdslot_paddr & 0xffffffff, hcr_base + CHBA); - - ata_host_resume(host); - return 0; -} -#endif - static struct of_device_id fsl_sata_match[] = { { .compatible = "fsl,pq-sata", @@ -1423,10 +1392,6 @@ static struct of_platform_driver fsl_sata_driver = { .match_table = fsl_sata_match, .probe = sata_fsl_probe, .remove = sata_fsl_remove, -#ifdef CONFIG_PM - .suspend = sata_fsl_suspend, - .resume = sata_fsl_resume, -#endif }; static int __init sata_fsl_init(void) diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 65a0655e7fc8..c7a527c08a09 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -226,18 +226,8 @@ static inline void addQ(struct hlist_head *list, CommandList_struct *c) static inline void removeQ(CommandList_struct *c) { - /* - * After kexec/dump some commands might still - * be in flight, which the firmware will try - * to complete. Resetting the firmware doesn't work - * with old fw revisions, so we have to mark - * them off as 'stale' to prevent the driver from - * falling over. - */ - if (WARN_ON(hlist_unhashed(&c->list))) { - c->cmd_type = CMD_MSG_STALE; + if (WARN_ON(hlist_unhashed(&c->list))) return; - } hlist_del_init(&c->list); } @@ -4256,8 +4246,7 @@ static void fail_all_cmds(unsigned long ctlr) while (!hlist_empty(&h->cmpQ)) { c = hlist_entry(h->cmpQ.first, CommandList_struct, list); removeQ(c); - if (c->cmd_type != CMD_MSG_STALE) - c->err_info->CommandStatus = CMD_HARDWARE_ERR; + c->err_info->CommandStatus = CMD_HARDWARE_ERR; if (c->cmd_type == CMD_RWREQ) { complete_command(h, c, 0); } else if (c->cmd_type == CMD_IOCTL_PEND) diff --git a/trunk/drivers/block/cciss_cmd.h b/trunk/drivers/block/cciss_cmd.h index dbaed1ea0da3..cd665b00c7c5 100644 --- a/trunk/drivers/block/cciss_cmd.h +++ b/trunk/drivers/block/cciss_cmd.h @@ -274,7 +274,6 @@ typedef struct _ErrorInfo_struct { #define CMD_SCSI 0x03 #define CMD_MSG_DONE 0x04 #define CMD_MSG_TIMEOUT 0x05 -#define CMD_MSG_STALE 0xff /* This structure needs to be divisible by 8 for new * indexing method. diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 91b753013780..862b40c90181 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -3327,10 +3327,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, if (!capable(CAP_SYS_ADMIN)) return -EPERM; mutex_lock(&open_lock); - if (lock_fdc(drive, 1)) { - mutex_unlock(&open_lock); - return -EINTR; - } + LOCK_FDC(drive, 1); floppy_type[type] = *g; floppy_type[type].name = "user format"; for (cnt = type << 2; cnt < (type << 2) + 4; cnt++) diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 6a06913b01d3..0bd01f49cfd8 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -1029,6 +1029,10 @@ config CS5535_GPIO If compiled as a module, it will be called cs5535_gpio. +config GPIO_VR41XX + tristate "NEC VR4100 series General-purpose I/O Unit support" + depends on CPU_VR41XX + config RAW_DRIVER tristate "RAW driver (/dev/raw/rawN)" depends on BLOCK diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 66f779ad4f4c..189efcff08ce 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -95,6 +95,7 @@ obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o +obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o obj-$(CONFIG_GPIO_TB0219) += tb0219.o obj-$(CONFIG_TELCLOCK) += tlclk.o diff --git a/trunk/drivers/char/bsr.c b/trunk/drivers/char/bsr.c index c02db01f736e..140ea10ecb88 100644 --- a/trunk/drivers/char/bsr.c +++ b/trunk/drivers/char/bsr.c @@ -27,7 +27,6 @@ #include #include #include -#include #include /* @@ -76,13 +75,12 @@ static struct class *bsr_class; static int bsr_major; enum { - BSR_8 = 0, - BSR_16 = 1, - BSR_64 = 2, - BSR_128 = 3, - BSR_4096 = 4, - BSR_UNKNOWN = 5, - BSR_MAX = 6, + BSR_8 = 0, + BSR_16 = 1, + BSR_64 = 2, + BSR_128 = 3, + BSR_UNKNOWN = 4, + BSR_MAX = 5, }; static unsigned bsr_types[BSR_MAX]; @@ -119,22 +117,15 @@ static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) { unsigned long size = vma->vm_end - vma->vm_start; struct bsr_dev *dev = filp->private_data; - int ret; - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - /* check for the case of a small BSR device and map one 4k page for it*/ - if (dev->bsr_len < PAGE_SIZE && size == PAGE_SIZE) - ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12, - vma->vm_page_prot); - else if (size <= dev->bsr_len) - ret = io_remap_pfn_range(vma, vma->vm_start, - dev->bsr_addr >> PAGE_SHIFT, - size, vma->vm_page_prot); - else + if (size > dev->bsr_len || (size & (PAGE_SIZE-1))) return -EINVAL; - if (ret) + vma->vm_flags |= (VM_IO | VM_DONTEXPAND); + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, + size, vma->vm_page_prot)) return -EAGAIN; return 0; @@ -214,11 +205,6 @@ static int bsr_add_node(struct device_node *bn) cur->bsr_stride = bsr_stride[i]; cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs); - /* if we have a bsr_len of > 4k and less then PAGE_SIZE (64k pages) */ - /* we can only map 4k of it, so only advertise the 4k in sysfs */ - if (cur->bsr_len > 4096 && cur->bsr_len < PAGE_SIZE) - cur->bsr_len = 4096; - switch(cur->bsr_bytes) { case 8: cur->bsr_type = BSR_8; @@ -232,11 +218,9 @@ static int bsr_add_node(struct device_node *bn) case 128: cur->bsr_type = BSR_128; break; - case 4096: - cur->bsr_type = BSR_4096; - break; default: cur->bsr_type = BSR_UNKNOWN; + printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes); } cur->bsr_num = bsr_types[cur->bsr_type]; diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 52d953eb30c3..9533f43a30bb 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -1048,6 +1048,8 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) if (retval) return retval; + /* unmark here for very high baud rate (ex. 921600 bps) used */ + tty->low_latency = 1; return 0; } diff --git a/trunk/drivers/char/nozomi.c b/trunk/drivers/char/nozomi.c index 574f1c79b6e6..d6102b644b55 100644 --- a/trunk/drivers/char/nozomi.c +++ b/trunk/drivers/char/nozomi.c @@ -1591,6 +1591,8 @@ static int ntty_open(struct tty_struct *tty, struct file *file) /* Enable interrupt downlink for channel */ if (port->port.count == 1) { + /* FIXME: is this needed now ? */ + tty->low_latency = 1; tty->driver_data = port; tty_port_tty_set(&port->port, tty); DBG1("open: %d", port->token_dl); diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index a2e67e6df3a1..1386625fc4ca 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -467,6 +467,7 @@ static unsigned int free_tbuf_count(struct slgt_info *info); static unsigned int tbuf_bytes(struct slgt_info *info); static void reset_tbufs(struct slgt_info *info); static void tdma_reset(struct slgt_info *info); +static void tdma_start(struct slgt_info *info); static void tx_load(struct slgt_info *info, const char *buf, unsigned int count); static void get_signals(struct slgt_info *info); @@ -794,18 +795,6 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) } } -static void update_tx_timer(struct slgt_info *info) -{ - /* - * use worst case speed of 1200bps to calculate transmit timeout - * based on data in buffers (tbuf_bytes) and FIFO (128 bytes) - */ - if (info->params.mode == MGSL_MODE_HDLC) { - int timeout = (tbuf_bytes(info) * 7) + 1000; - mod_timer(&info->tx_timer, jiffies + msecs_to_jiffies(timeout)); - } -} - static int write(struct tty_struct *tty, const unsigned char *buf, int count) { @@ -849,18 +838,8 @@ static int write(struct tty_struct *tty, spin_lock_irqsave(&info->lock,flags); if (!info->tx_active) tx_start(info); - else if (!(rd_reg32(info, TDCSR) & BIT0)) { - /* transmit still active but transmit DMA stopped */ - unsigned int i = info->tbuf_current; - if (!i) - i = info->tbuf_count; - i--; - /* if DMA buf unsent must try later after tx idle */ - if (desc_count(info->tbufs[i])) - ret = 0; - } - if (ret > 0) - update_tx_timer(info); + else + tdma_start(info); spin_unlock_irqrestore(&info->lock,flags); } @@ -1523,9 +1502,10 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) /* save start time for transmit timeout detection */ dev->trans_start = jiffies; + /* start hardware transmitter if necessary */ spin_lock_irqsave(&info->lock,flags); - tx_start(info); - update_tx_timer(info); + if (!info->tx_active) + tx_start(info); spin_unlock_irqrestore(&info->lock,flags); return 0; @@ -3966,19 +3946,50 @@ static void tx_start(struct slgt_info *info) slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE); /* clear tx idle and underrun status bits */ wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); + if (info->params.mode == MGSL_MODE_HDLC) + mod_timer(&info->tx_timer, jiffies + + msecs_to_jiffies(5000)); } else { slgt_irq_off(info, IRQ_TXDATA); slgt_irq_on(info, IRQ_TXIDLE); /* clear tx idle status bit */ wr_reg16(info, SSR, IRQ_TXIDLE); } - /* set 1st descriptor address and start DMA */ - wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); - wr_reg32(info, TDCSR, BIT2 + BIT0); + tdma_start(info); info->tx_active = true; } } +/* + * start transmit DMA if inactive and there are unsent buffers + */ +static void tdma_start(struct slgt_info *info) +{ + unsigned int i; + + if (rd_reg32(info, TDCSR) & BIT0) + return; + + /* transmit DMA inactive, check for unsent buffers */ + i = info->tbuf_start; + while (!desc_count(info->tbufs[i])) { + if (++i == info->tbuf_count) + i = 0; + if (i == info->tbuf_current) + return; + } + info->tbuf_start = i; + + /* there are unsent buffers, start transmit DMA */ + + /* reset needed if previous error condition */ + tdma_reset(info); + + /* set 1st descriptor address */ + wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); + wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ +} + static void tx_stop(struct slgt_info *info) { unsigned short val; @@ -4993,7 +5004,8 @@ static void tx_timeout(unsigned long context) info->icount.txtimeout++; } spin_lock_irqsave(&info->lock,flags); - tx_stop(info); + info->tx_active = false; + info->tx_count = 0; spin_unlock_irqrestore(&info->lock,flags); #if SYNCLINK_GENERIC_HDLC diff --git a/trunk/drivers/char/tb0219.c b/trunk/drivers/char/tb0219.c index b3ec9b10e292..6062b62800fd 100644 --- a/trunk/drivers/char/tb0219.c +++ b/trunk/drivers/char/tb0219.c @@ -1,7 +1,7 @@ /* * Driver for TANBAC TB0219 base board. * - * Copyright (C) 2005 Yoichi Yuasa + * Copyright (C) 2005 Yoichi Yuasa * * 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 @@ -28,7 +28,7 @@ #include #include -MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_AUTHOR("Yoichi Yuasa "); MODULE_DESCRIPTION("TANBAC TB0219 base board driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/tty_ldisc.c b/trunk/drivers/char/tty_ldisc.c index 913aa8d3f1c5..a19e935847b0 100644 --- a/trunk/drivers/char/tty_ldisc.c +++ b/trunk/drivers/char/tty_ldisc.c @@ -867,22 +867,15 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) tty_ldisc_wait_idle(tty); /* - * Now kill off the ldisc + * Shutdown the current line discipline, and reset it to N_TTY. + * + * FIXME: this MUST get fixed for the new reflocking */ - tty_ldisc_close(tty, tty->ldisc); - tty_ldisc_put(tty->ldisc); - /* Force an oops if we mess this up */ - tty->ldisc = NULL; - - /* Ensure the next open requests the N_TTY ldisc */ - tty_set_termios_ldisc(tty, N_TTY); + tty_ldisc_reinit(tty); /* This will need doing differently if we need to lock */ if (o_tty) tty_ldisc_release(o_tty, NULL); - - /* And the memory resources remaining (buffers, termios) will be - disposed of when the kref hits zero */ } /** diff --git a/trunk/drivers/char/tty_port.c b/trunk/drivers/char/tty_port.c index 4e862a75f7ff..62dadfc95e34 100644 --- a/trunk/drivers/char/tty_port.c +++ b/trunk/drivers/char/tty_port.c @@ -193,7 +193,7 @@ int tty_port_block_til_ready(struct tty_port *port, { int do_clocal = 0, retval; unsigned long flags; - DEFINE_WAIT(wait); + DECLARE_WAITQUEUE(wait, current); int cd; /* block if port is in the process of being closed */ diff --git a/trunk/drivers/char/vr41xx_giu.c b/trunk/drivers/char/vr41xx_giu.c index e69de29bb2d1..54c837288d19 100644 --- a/trunk/drivers/char/vr41xx_giu.c +++ b/trunk/drivers/char/vr41xx_giu.c @@ -0,0 +1,680 @@ +/* + * Driver for NEC VR4100 series General-purpose I/O Unit. + * + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa + * Copyright (C) 2003-2007 Yoichi Yuasa + * + * 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 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); +MODULE_LICENSE("GPL"); + +static int major; /* default is dynamic major device number */ +module_param(major, int, 0); +MODULE_PARM_DESC(major, "Major device number"); + +#define GIUIOSELL 0x00 +#define GIUIOSELH 0x02 +#define GIUPIODL 0x04 +#define GIUPIODH 0x06 +#define GIUINTSTATL 0x08 +#define GIUINTSTATH 0x0a +#define GIUINTENL 0x0c +#define GIUINTENH 0x0e +#define GIUINTTYPL 0x10 +#define GIUINTTYPH 0x12 +#define GIUINTALSELL 0x14 +#define GIUINTALSELH 0x16 +#define GIUINTHTSELL 0x18 +#define GIUINTHTSELH 0x1a +#define GIUPODATL 0x1c +#define GIUPODATEN 0x1c +#define GIUPODATH 0x1e + #define PIOEN0 0x0100 + #define PIOEN1 0x0200 +#define GIUPODAT 0x1e +#define GIUFEDGEINHL 0x20 +#define GIUFEDGEINHH 0x22 +#define GIUREDGEINHL 0x24 +#define GIUREDGEINHH 0x26 + +#define GIUUSEUPDN 0x1e0 +#define GIUTERMUPDN 0x1e2 + +#define GPIO_HAS_PULLUPDOWN_IO 0x0001 +#define GPIO_HAS_OUTPUT_ENABLE 0x0002 +#define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 + +static spinlock_t giu_lock; +static unsigned long giu_flags; +static unsigned int giu_nr_pins; + +static void __iomem *giu_base; + +#define giu_read(offset) readw(giu_base + (offset)) +#define giu_write(offset, value) writew((value), giu_base + (offset)) + +#define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) +#define GIUINT_HIGH_OFFSET 16 +#define GIUINT_HIGH_MAX 32 + +static inline uint16_t giu_set(uint16_t offset, uint16_t set) +{ + uint16_t data; + + data = giu_read(offset); + data |= set; + giu_write(offset, data); + + return data; +} + +static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) +{ + uint16_t data; + + data = giu_read(offset); + data &= ~clear; + giu_write(offset, data); + + return data; +} + +static void ack_giuint_low(unsigned int irq) +{ + giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +static void mask_giuint_low(unsigned int irq) +{ + giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +static void mask_ack_giuint_low(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq); + giu_clear(GIUINTENL, 1 << pin); + giu_write(GIUINTSTATL, 1 << pin); +} + +static void unmask_giuint_low(unsigned int irq) +{ + giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +static struct irq_chip giuint_low_irq_chip = { + .name = "GIUINTL", + .ack = ack_giuint_low, + .mask = mask_giuint_low, + .mask_ack = mask_ack_giuint_low, + .unmask = unmask_giuint_low, +}; + +static void ack_giuint_high(unsigned int irq) +{ + giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +static void mask_giuint_high(unsigned int irq) +{ + giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +static void mask_ack_giuint_high(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; + giu_clear(GIUINTENH, 1 << pin); + giu_write(GIUINTSTATH, 1 << pin); +} + +static void unmask_giuint_high(unsigned int irq) +{ + giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +static struct irq_chip giuint_high_irq_chip = { + .name = "GIUINTH", + .ack = ack_giuint_high, + .mask = mask_giuint_high, + .mask_ack = mask_ack_giuint_high, + .unmask = unmask_giuint_high, +}; + +static int giu_get_irq(unsigned int irq) +{ + uint16_t pendl, pendh, maskl, maskh; + int i; + + pendl = giu_read(GIUINTSTATL); + pendh = giu_read(GIUINTSTATH); + maskl = giu_read(GIUINTENL); + maskh = giu_read(GIUINTENH); + + maskl &= pendl; + maskh &= pendh; + + if (maskl) { + for (i = 0; i < 16; i++) { + if (maskl & (1 << i)) + return GIU_IRQ(i); + } + } else if (maskh) { + for (i = 0; i < 16; i++) { + if (maskh & (1 << i)) + return GIU_IRQ(i + GIUINT_HIGH_OFFSET); + } + } + + printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", + maskl, pendl, maskh, pendh); + + atomic_inc(&irq_err_count); + + return -EINVAL; +} + +void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal) +{ + uint16_t mask; + + if (pin < GIUINT_HIGH_OFFSET) { + mask = 1 << pin; + if (trigger != IRQ_TRIGGER_LEVEL) { + giu_set(GIUINTTYPL, mask); + if (signal == IRQ_SIGNAL_HOLD) + giu_set(GIUINTHTSELL, mask); + else + giu_clear(GIUINTHTSELL, mask); + if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { + switch (trigger) { + case IRQ_TRIGGER_EDGE_FALLING: + giu_set(GIUFEDGEINHL, mask); + giu_clear(GIUREDGEINHL, mask); + break; + case IRQ_TRIGGER_EDGE_RISING: + giu_clear(GIUFEDGEINHL, mask); + giu_set(GIUREDGEINHL, mask); + break; + default: + giu_set(GIUFEDGEINHL, mask); + giu_set(GIUREDGEINHL, mask); + break; + } + } + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_low_irq_chip, + handle_edge_irq); + } else { + giu_clear(GIUINTTYPL, mask); + giu_clear(GIUINTHTSELL, mask); + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_low_irq_chip, + handle_level_irq); + } + giu_write(GIUINTSTATL, mask); + } else if (pin < GIUINT_HIGH_MAX) { + mask = 1 << (pin - GIUINT_HIGH_OFFSET); + if (trigger != IRQ_TRIGGER_LEVEL) { + giu_set(GIUINTTYPH, mask); + if (signal == IRQ_SIGNAL_HOLD) + giu_set(GIUINTHTSELH, mask); + else + giu_clear(GIUINTHTSELH, mask); + if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { + switch (trigger) { + case IRQ_TRIGGER_EDGE_FALLING: + giu_set(GIUFEDGEINHH, mask); + giu_clear(GIUREDGEINHH, mask); + break; + case IRQ_TRIGGER_EDGE_RISING: + giu_clear(GIUFEDGEINHH, mask); + giu_set(GIUREDGEINHH, mask); + break; + default: + giu_set(GIUFEDGEINHH, mask); + giu_set(GIUREDGEINHH, mask); + break; + } + } + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_high_irq_chip, + handle_edge_irq); + } else { + giu_clear(GIUINTTYPH, mask); + giu_clear(GIUINTHTSELH, mask); + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_high_irq_chip, + handle_level_irq); + } + giu_write(GIUINTSTATH, mask); + } +} +EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); + +void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) +{ + uint16_t mask; + + if (pin < GIUINT_HIGH_OFFSET) { + mask = 1 << pin; + if (level == IRQ_LEVEL_HIGH) + giu_set(GIUINTALSELL, mask); + else + giu_clear(GIUINTALSELL, mask); + giu_write(GIUINTSTATL, mask); + } else if (pin < GIUINT_HIGH_MAX) { + mask = 1 << (pin - GIUINT_HIGH_OFFSET); + if (level == IRQ_LEVEL_HIGH) + giu_set(GIUINTALSELH, mask); + else + giu_clear(GIUINTALSELH, mask); + giu_write(GIUINTSTATH, mask); + } +} +EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); + +gpio_data_t vr41xx_gpio_get_pin(unsigned int pin) +{ + uint16_t reg, mask; + + if (pin >= giu_nr_pins) + return GPIO_DATA_INVAL; + + if (pin < 16) { + reg = giu_read(GIUPIODL); + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + reg = giu_read(GIUPIODH); + mask = (uint16_t)1 << (pin - 16); + } else if (pin < 48) { + reg = giu_read(GIUPODATL); + mask = (uint16_t)1 << (pin - 32); + } else { + reg = giu_read(GIUPODATH); + mask = (uint16_t)1 << (pin - 48); + } + + if (reg & mask) + return GPIO_DATA_HIGH; + + return GPIO_DATA_LOW; +} +EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin); + +int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data) +{ + uint16_t offset, mask, reg; + unsigned long flags; + + if (pin >= giu_nr_pins) + return -EINVAL; + + if (pin < 16) { + offset = GIUPIODL; + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + offset = GIUPIODH; + mask = (uint16_t)1 << (pin - 16); + } else if (pin < 48) { + offset = GIUPODATL; + mask = (uint16_t)1 << (pin - 32); + } else { + offset = GIUPODATH; + mask = (uint16_t)1 << (pin - 48); + } + + spin_lock_irqsave(&giu_lock, flags); + + reg = giu_read(offset); + if (data == GPIO_DATA_HIGH) + reg |= mask; + else + reg &= ~mask; + giu_write(offset, reg); + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin); + +int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir) +{ + uint16_t offset, mask, reg; + unsigned long flags; + + if (pin >= giu_nr_pins) + return -EINVAL; + + if (pin < 16) { + offset = GIUIOSELL; + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + offset = GIUIOSELH; + mask = (uint16_t)1 << (pin - 16); + } else { + if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { + offset = GIUPODATEN; + mask = (uint16_t)1 << (pin - 32); + } else { + switch (pin) { + case 48: + offset = GIUPODATH; + mask = PIOEN0; + break; + case 49: + offset = GIUPODATH; + mask = PIOEN1; + break; + default: + return -EINVAL; + } + } + } + + spin_lock_irqsave(&giu_lock, flags); + + reg = giu_read(offset); + if (dir == GPIO_OUTPUT) + reg |= mask; + else + reg &= ~mask; + giu_write(offset, reg); + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction); + +int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) +{ + uint16_t reg, mask; + unsigned long flags; + + if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) + return -EPERM; + + if (pin >= 15) + return -EINVAL; + + mask = (uint16_t)1 << pin; + + spin_lock_irqsave(&giu_lock, flags); + + if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { + reg = giu_read(GIUTERMUPDN); + if (pull == GPIO_PULL_UP) + reg |= mask; + else + reg &= ~mask; + giu_write(GIUTERMUPDN, reg); + + reg = giu_read(GIUUSEUPDN); + reg |= mask; + giu_write(GIUUSEUPDN, reg); + } else { + reg = giu_read(GIUUSEUPDN); + reg &= ~mask; + giu_write(GIUUSEUPDN, reg); + } + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); + +static ssize_t gpio_read(struct file *file, char __user *buf, size_t len, + loff_t *ppos) +{ + unsigned int pin; + char value = '0'; + + pin = iminor(file->f_path.dentry->d_inode); + if (pin >= giu_nr_pins) + return -EBADF; + + if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH) + value = '1'; + + if (len <= 0) + return -EFAULT; + + if (put_user(value, buf)) + return -EFAULT; + + return 1; +} + +static ssize_t gpio_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + unsigned int pin; + size_t i; + char c; + int retval = 0; + + pin = iminor(file->f_path.dentry->d_inode); + if (pin >= giu_nr_pins) + return -EBADF; + + for (i = 0; i < len; i++) { + if (get_user(c, data + i)) + return -EFAULT; + + switch (c) { + case '0': + retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW); + break; + case '1': + retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH); + break; + case 'D': + printk(KERN_INFO "GPIO%d: pull down\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN); + break; + case 'd': + printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); + break; + case 'I': + printk(KERN_INFO "GPIO%d: input\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT); + break; + case 'O': + printk(KERN_INFO "GPIO%d: output\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT); + break; + case 'o': + printk(KERN_INFO "GPIO%d: output disable\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE); + break; + case 'P': + printk(KERN_INFO "GPIO%d: pull up\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP); + break; + case 'p': + printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); + break; + default: + break; + } + + if (retval < 0) + break; + } + + return i; +} + +static int gpio_open(struct inode *inode, struct file *file) +{ + unsigned int pin; + + cycle_kernel_lock(); + pin = iminor(inode); + if (pin >= giu_nr_pins) + return -EBADF; + + return nonseekable_open(inode, file); +} + +static int gpio_release(struct inode *inode, struct file *file) +{ + unsigned int pin; + + pin = iminor(inode); + if (pin >= giu_nr_pins) + return -EBADF; + + return 0; +} + +static const struct file_operations gpio_fops = { + .owner = THIS_MODULE, + .read = gpio_read, + .write = gpio_write, + .open = gpio_open, + .release = gpio_release, +}; + +static int __devinit giu_probe(struct platform_device *dev) +{ + struct resource *res; + unsigned int trigger, i, pin; + struct irq_chip *chip; + int irq, retval; + + switch (dev->id) { + case GPIO_50PINS_PULLUPDOWN: + giu_flags = GPIO_HAS_PULLUPDOWN_IO; + giu_nr_pins = 50; + break; + case GPIO_36PINS: + giu_nr_pins = 36; + break; + case GPIO_48PINS_EDGE_SELECT: + giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; + giu_nr_pins = 48; + break; + default: + printk(KERN_ERR "GIU: unknown ID %d\n", dev->id); + return -ENODEV; + } + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!res) + return -EBUSY; + + giu_base = ioremap(res->start, res->end - res->start + 1); + if (!giu_base) + return -ENOMEM; + + retval = register_chrdev(major, "GIU", &gpio_fops); + if (retval < 0) { + iounmap(giu_base); + giu_base = NULL; + return retval; + } + + if (major == 0) { + major = retval; + printk(KERN_INFO "GIU: major number %d\n", major); + } + + spin_lock_init(&giu_lock); + + giu_write(GIUINTENL, 0); + giu_write(GIUINTENH, 0); + + trigger = giu_read(GIUINTTYPH) << 16; + trigger |= giu_read(GIUINTTYPL); + for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { + pin = GPIO_PIN_OF_IRQ(i); + if (pin < GIUINT_HIGH_OFFSET) + chip = &giuint_low_irq_chip; + else + chip = &giuint_high_irq_chip; + + if (trigger & (1 << pin)) + set_irq_chip_and_handler(i, chip, handle_edge_irq); + else + set_irq_chip_and_handler(i, chip, handle_level_irq); + + } + + irq = platform_get_irq(dev, 0); + if (irq < 0 || irq >= nr_irqs) + return -EBUSY; + + return cascade_irq(irq, giu_get_irq); +} + +static int __devexit giu_remove(struct platform_device *dev) +{ + if (giu_base) { + iounmap(giu_base); + giu_base = NULL; + } + + return 0; +} + +static struct platform_driver giu_device_driver = { + .probe = giu_probe, + .remove = __devexit_p(giu_remove), + .driver = { + .name = "GIU", + .owner = THIS_MODULE, + }, +}; + +static int __init vr41xx_giu_init(void) +{ + return platform_driver_register(&giu_device_driver); +} + +static void __exit vr41xx_giu_exit(void) +{ + platform_driver_unregister(&giu_device_driver); +} + +module_init(vr41xx_giu_init); +module_exit(vr41xx_giu_exit); diff --git a/trunk/drivers/clocksource/sh_tmu.c b/trunk/drivers/clocksource/sh_tmu.c index 93c2322feab7..9ffb05f4095d 100644 --- a/trunk/drivers/clocksource/sh_tmu.c +++ b/trunk/drivers/clocksource/sh_tmu.c @@ -161,7 +161,7 @@ static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, if (periodic) sh_tmu_write(p, TCOR, delta); else - sh_tmu_write(p, TCOR, 0xffffffff); + sh_tmu_write(p, TCOR, 0); sh_tmu_write(p, TCNT, delta); diff --git a/trunk/drivers/dma/txx9dmac.c b/trunk/drivers/dma/txx9dmac.c index 88dab52926f4..9aa9ea9822c8 100644 --- a/trunk/drivers/dma/txx9dmac.c +++ b/trunk/drivers/dma/txx9dmac.c @@ -432,27 +432,23 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc, list_splice_init(&txd->tx_list, &dc->free_list); list_move(&desc->desc_node, &dc->free_list); + /* + * We use dma_unmap_page() regardless of how the buffers were + * mapped before they were submitted... + */ if (!ds) { dma_addr_t dmaaddr; if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) { dmaaddr = is_dmac64(dc) ? desc->hwdesc.DAR : desc->hwdesc32.DAR; - if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE) - dma_unmap_single(chan2parent(&dc->chan), - dmaaddr, desc->len, DMA_FROM_DEVICE); - else - dma_unmap_page(chan2parent(&dc->chan), - dmaaddr, desc->len, DMA_FROM_DEVICE); + dma_unmap_page(chan2parent(&dc->chan), dmaaddr, + desc->len, DMA_FROM_DEVICE); } if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) { dmaaddr = is_dmac64(dc) ? desc->hwdesc.SAR : desc->hwdesc32.SAR; - if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE) - dma_unmap_single(chan2parent(&dc->chan), - dmaaddr, desc->len, DMA_TO_DEVICE); - else - dma_unmap_page(chan2parent(&dc->chan), - dmaaddr, desc->len, DMA_TO_DEVICE); + dma_unmap_page(chan2parent(&dc->chan), dmaaddr, + desc->len, DMA_TO_DEVICE); } } diff --git a/trunk/drivers/edac/amd64_edac.c b/trunk/drivers/edac/amd64_edac.c index 858fe6037223..c36bf40568cf 100644 --- a/trunk/drivers/edac/amd64_edac.c +++ b/trunk/drivers/edac/amd64_edac.c @@ -754,13 +754,13 @@ static void amd64_cpu_display_info(struct amd64_pvt *pvt) static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt) { int bit; - enum dev_type edac_cap = EDAC_FLAG_NONE; + enum dev_type edac_cap = EDAC_NONE; bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F) ? 19 : 17; - if (pvt->dclr0 & BIT(bit)) + if (pvt->dclr0 >> BIT(bit)) edac_cap = EDAC_FLAG_SECDED; return edac_cap; @@ -1269,7 +1269,7 @@ static int f10_early_channel_count(struct amd64_pvt *pvt) if (channels == 0) channels = 1; - debugf0("MCT channel count: %d\n", channels); + debugf0("DIMM count= %d\n", channels); return channels; @@ -2966,12 +2966,7 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) " Use of the override can cause " "unknown side effects.\n"); ret = -ENODEV; - } else - /* - * enable further driver loading if ECC enable is - * overridden. - */ - ret = 0; + } } else { amd64_printk(KERN_INFO, "ECC is enabled by BIOS, Proceeding " @@ -3011,6 +3006,7 @@ static void amd64_setup_mci_misc_attributes(struct mem_ctl_info *mci) mci->mtype_cap = MEM_FLAG_DDR2 | MEM_FLAG_RDDR2; mci->edac_ctl_cap = EDAC_FLAG_NONE; + mci->edac_cap = EDAC_FLAG_NONE; if (pvt->nbcap & K8_NBCAP_SECDED) mci->edac_ctl_cap |= EDAC_FLAG_SECDED; @@ -3056,7 +3052,7 @@ static int amd64_probe_one_instance(struct pci_dev *dram_f2_ctl, if (!pvt) goto err_exit; - pvt->mc_node_id = get_node_id(dram_f2_ctl); + pvt->mc_node_id = get_mc_node_id_from_pdev(dram_f2_ctl); pvt->dram_f2_ctl = dram_f2_ctl; pvt->ext_model = boot_cpu_data.x86_model >> 4; @@ -3183,7 +3179,8 @@ static int __devinit amd64_init_one_instance(struct pci_dev *pdev, { int ret = 0; - debugf0("(MC node=%d,mc_type='%s')\n", get_node_id(pdev), + debugf0("(MC node=%d,mc_type='%s')\n", + get_mc_node_id_from_pdev(pdev), get_amd_family_name(mc_type->driver_data)); ret = pci_enable_device(pdev); @@ -3322,17 +3319,15 @@ static int __init amd64_edac_init(void) err = amd64_init_2nd_stage(pvt_lookup[nb]); if (err) - goto err_2nd_stage; + goto err_exit; } amd64_setup_pci_device(); return 0; -err_2nd_stage: - debugf0("2nd stage failed\n"); - err_exit: + debugf0("'finish_setup' stage failed\n"); pci_unregister_driver(&amd64_pci_driver); return err; diff --git a/trunk/drivers/edac/amd64_edac.h b/trunk/drivers/edac/amd64_edac.h index ba73015af8e4..a159957e167b 100644 --- a/trunk/drivers/edac/amd64_edac.h +++ b/trunk/drivers/edac/amd64_edac.h @@ -444,7 +444,7 @@ enum { #define K8_MSR_MC4ADDR 0x0412 /* AMD sets the first MC device at device ID 0x18. */ -static inline int get_node_id(struct pci_dev *pdev) +static inline int get_mc_node_id_from_pdev(struct pci_dev *pdev) { return PCI_SLOT(pdev->devfn) - 0x18; } diff --git a/trunk/drivers/edac/edac_core.h b/trunk/drivers/edac/edac_core.h index 871c13b4c148..3493c6bdb820 100644 --- a/trunk/drivers/edac/edac_core.h +++ b/trunk/drivers/edac/edac_core.h @@ -150,8 +150,6 @@ enum mem_type { MEM_FB_DDR2, /* fully buffered DDR2 */ MEM_RDDR2, /* Registered DDR2 RAM */ MEM_XDR, /* Rambus XDR */ - MEM_DDR3, /* DDR3 RAM */ - MEM_RDDR3, /* Registered DDR3 RAM */ }; #define MEM_FLAG_EMPTY BIT(MEM_EMPTY) @@ -169,8 +167,6 @@ enum mem_type { #define MEM_FLAG_FB_DDR2 BIT(MEM_FB_DDR2) #define MEM_FLAG_RDDR2 BIT(MEM_RDDR2) #define MEM_FLAG_XDR BIT(MEM_XDR) -#define MEM_FLAG_DDR3 BIT(MEM_DDR3) -#define MEM_FLAG_RDDR3 BIT(MEM_RDDR3) /* chipset Error Detection and Correction capabilities and mode */ enum edac_type { diff --git a/trunk/drivers/edac/edac_mc_sysfs.c b/trunk/drivers/edac/edac_mc_sysfs.c index e1d4ce083481..ad218fe4942d 100644 --- a/trunk/drivers/edac/edac_mc_sysfs.c +++ b/trunk/drivers/edac/edac_mc_sysfs.c @@ -94,9 +94,7 @@ static const char *mem_types[] = { [MEM_DDR2] = "Unbuffered-DDR2", [MEM_FB_DDR2] = "FullyBuffered-DDR2", [MEM_RDDR2] = "Registered-DDR2", - [MEM_XDR] = "XDR", - [MEM_DDR3] = "Unbuffered-DDR3", - [MEM_RDDR3] = "Registered-DDR3" + [MEM_XDR] = "XDR" }; static const char *dev_types[] = { diff --git a/trunk/drivers/edac/mpc85xx_edac.c b/trunk/drivers/edac/mpc85xx_edac.c index 3f2ccfc6407c..7c8c2d72916f 100644 --- a/trunk/drivers/edac/mpc85xx_edac.c +++ b/trunk/drivers/edac/mpc85xx_edac.c @@ -757,9 +757,6 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) case DSC_SDTYPE_DDR2: mtype = MEM_RDDR2; break; - case DSC_SDTYPE_DDR3: - mtype = MEM_RDDR3; - break; default: mtype = MEM_UNKNOWN; break; @@ -772,9 +769,6 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) case DSC_SDTYPE_DDR2: mtype = MEM_DDR2; break; - case DSC_SDTYPE_DDR3: - mtype = MEM_DDR3; - break; default: mtype = MEM_UNKNOWN; break; diff --git a/trunk/drivers/edac/mpc85xx_edac.h b/trunk/drivers/edac/mpc85xx_edac.h index 52432ee7c4b9..135b3539a030 100644 --- a/trunk/drivers/edac/mpc85xx_edac.h +++ b/trunk/drivers/edac/mpc85xx_edac.h @@ -53,7 +53,6 @@ #define DSC_SDTYPE_DDR 0x02000000 #define DSC_SDTYPE_DDR2 0x03000000 -#define DSC_SDTYPE_DDR3 0x07000000 #define DSC_X32_EN 0x00000020 /* Err_Int_En */ diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index 96dda81c9228..3582c39f9725 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -79,12 +79,6 @@ config GPIO_XILINX help Say yes here to support the Xilinx FPGA GPIO device -config GPIO_VR41XX - tristate "NEC VR4100 series General-purpose I/O Uint support" - depends on CPU_VR41XX - help - Say yes here to support the NEC VR4100 series General-purpose I/O Uint - comment "I2C GPIO expanders:" config GPIO_MAX732X diff --git a/trunk/drivers/gpio/Makefile b/trunk/drivers/gpio/Makefile index 9244c6fcd8be..ef90203e8f3c 100644 --- a/trunk/drivers/gpio/Makefile +++ b/trunk/drivers/gpio/Makefile @@ -13,4 +13,3 @@ obj-$(CONFIG_GPIO_PL061) += pl061.o obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o -obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o diff --git a/trunk/drivers/gpio/pl061.c b/trunk/drivers/gpio/pl061.c index 4ee4c8367a3f..aa8e7cb020d9 100644 --- a/trunk/drivers/gpio/pl061.c +++ b/trunk/drivers/gpio/pl061.c @@ -109,16 +109,6 @@ static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value) writeb(!!value << offset, chip->base + (1 << (offset + 2))); } -static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) -{ - struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); - - if (chip->irq_base == (unsigned) -1) - return -EINVAL; - - return chip->irq_base + offset; -} - /* * PL061 GPIO IRQ */ @@ -210,7 +200,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) desc->chip->ack(irq); list_for_each(ptr, chip_list) { unsigned long pending; - int offset; + int gpio; chip = list_entry(ptr, struct pl061_gpio, list); pending = readb(chip->base + GPIOMIS); @@ -219,8 +209,8 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc) if (pending == 0) continue; - for_each_bit(offset, &pending, PL061_GPIO_NR) - generic_handle_irq(pl061_to_irq(&chip->gc, offset)); + for_each_bit(gpio, &pending, PL061_GPIO_NR) + generic_handle_irq(gpio_to_irq(gpio)); } desc->chip->unmask(irq); } @@ -231,7 +221,7 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) struct pl061_gpio *chip; struct list_head *chip_list; int ret, irq, i; - static DECLARE_BITMAP(init_irq, NR_IRQS); + static unsigned long init_irq[BITS_TO_LONGS(NR_IRQS)]; pdata = dev->dev.platform_data; if (pdata == NULL) @@ -261,7 +251,6 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) chip->gc.direction_output = pl061_direction_output; chip->gc.get = pl061_get_value; chip->gc.set = pl061_set_value; - chip->gc.to_irq = pl061_to_irq; chip->gc.base = pdata->gpio_base; chip->gc.ngpio = PL061_GPIO_NR; chip->gc.label = dev_name(&dev->dev); @@ -291,7 +280,6 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id) if (!test_and_set_bit(irq, init_irq)) { /* list initialized? */ chip_list = kmalloc(sizeof(*chip_list), GFP_KERNEL); if (chip_list == NULL) { - clear_bit(irq, init_irq); ret = -ENOMEM; goto iounmap; } diff --git a/trunk/drivers/gpio/vr41xx_giu.c b/trunk/drivers/gpio/vr41xx_giu.c deleted file mode 100644 index b70e06133e78..000000000000 --- a/trunk/drivers/gpio/vr41xx_giu.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Driver for NEC VR4100 series General-purpose I/O Unit. - * - * Copyright (C) 2002 MontaVista Software Inc. - * Author: Yoichi Yuasa - * Copyright (C) 2003-2009 Yoichi Yuasa - * - * 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 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -MODULE_AUTHOR("Yoichi Yuasa "); -MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); -MODULE_LICENSE("GPL"); - -#define GIUIOSELL 0x00 -#define GIUIOSELH 0x02 -#define GIUPIODL 0x04 -#define GIUPIODH 0x06 -#define GIUINTSTATL 0x08 -#define GIUINTSTATH 0x0a -#define GIUINTENL 0x0c -#define GIUINTENH 0x0e -#define GIUINTTYPL 0x10 -#define GIUINTTYPH 0x12 -#define GIUINTALSELL 0x14 -#define GIUINTALSELH 0x16 -#define GIUINTHTSELL 0x18 -#define GIUINTHTSELH 0x1a -#define GIUPODATL 0x1c -#define GIUPODATEN 0x1c -#define GIUPODATH 0x1e - #define PIOEN0 0x0100 - #define PIOEN1 0x0200 -#define GIUPODAT 0x1e -#define GIUFEDGEINHL 0x20 -#define GIUFEDGEINHH 0x22 -#define GIUREDGEINHL 0x24 -#define GIUREDGEINHH 0x26 - -#define GIUUSEUPDN 0x1e0 -#define GIUTERMUPDN 0x1e2 - -#define GPIO_HAS_PULLUPDOWN_IO 0x0001 -#define GPIO_HAS_OUTPUT_ENABLE 0x0002 -#define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 - -enum { - GPIO_INPUT, - GPIO_OUTPUT, -}; - -static DEFINE_SPINLOCK(giu_lock); -static unsigned long giu_flags; - -static void __iomem *giu_base; - -#define giu_read(offset) readw(giu_base + (offset)) -#define giu_write(offset, value) writew((value), giu_base + (offset)) - -#define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) -#define GIUINT_HIGH_OFFSET 16 -#define GIUINT_HIGH_MAX 32 - -static inline u16 giu_set(u16 offset, u16 set) -{ - u16 data; - - data = giu_read(offset); - data |= set; - giu_write(offset, data); - - return data; -} - -static inline u16 giu_clear(u16 offset, u16 clear) -{ - u16 data; - - data = giu_read(offset); - data &= ~clear; - giu_write(offset, data); - - return data; -} - -static void ack_giuint_low(unsigned int irq) -{ - giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); -} - -static void mask_giuint_low(unsigned int irq) -{ - giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); -} - -static void mask_ack_giuint_low(unsigned int irq) -{ - unsigned int pin; - - pin = GPIO_PIN_OF_IRQ(irq); - giu_clear(GIUINTENL, 1 << pin); - giu_write(GIUINTSTATL, 1 << pin); -} - -static void unmask_giuint_low(unsigned int irq) -{ - giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); -} - -static struct irq_chip giuint_low_irq_chip = { - .name = "GIUINTL", - .ack = ack_giuint_low, - .mask = mask_giuint_low, - .mask_ack = mask_ack_giuint_low, - .unmask = unmask_giuint_low, -}; - -static void ack_giuint_high(unsigned int irq) -{ - giu_write(GIUINTSTATH, - 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); -} - -static void mask_giuint_high(unsigned int irq) -{ - giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); -} - -static void mask_ack_giuint_high(unsigned int irq) -{ - unsigned int pin; - - pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; - giu_clear(GIUINTENH, 1 << pin); - giu_write(GIUINTSTATH, 1 << pin); -} - -static void unmask_giuint_high(unsigned int irq) -{ - giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); -} - -static struct irq_chip giuint_high_irq_chip = { - .name = "GIUINTH", - .ack = ack_giuint_high, - .mask = mask_giuint_high, - .mask_ack = mask_ack_giuint_high, - .unmask = unmask_giuint_high, -}; - -static int giu_get_irq(unsigned int irq) -{ - u16 pendl, pendh, maskl, maskh; - int i; - - pendl = giu_read(GIUINTSTATL); - pendh = giu_read(GIUINTSTATH); - maskl = giu_read(GIUINTENL); - maskh = giu_read(GIUINTENH); - - maskl &= pendl; - maskh &= pendh; - - if (maskl) { - for (i = 0; i < 16; i++) { - if (maskl & (1 << i)) - return GIU_IRQ(i); - } - } else if (maskh) { - for (i = 0; i < 16; i++) { - if (maskh & (1 << i)) - return GIU_IRQ(i + GIUINT_HIGH_OFFSET); - } - } - - printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", - maskl, pendl, maskh, pendh); - - atomic_inc(&irq_err_count); - - return -EINVAL; -} - -void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, - irq_signal_t signal) -{ - u16 mask; - - if (pin < GIUINT_HIGH_OFFSET) { - mask = 1 << pin; - if (trigger != IRQ_TRIGGER_LEVEL) { - giu_set(GIUINTTYPL, mask); - if (signal == IRQ_SIGNAL_HOLD) - giu_set(GIUINTHTSELL, mask); - else - giu_clear(GIUINTHTSELL, mask); - if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { - switch (trigger) { - case IRQ_TRIGGER_EDGE_FALLING: - giu_set(GIUFEDGEINHL, mask); - giu_clear(GIUREDGEINHL, mask); - break; - case IRQ_TRIGGER_EDGE_RISING: - giu_clear(GIUFEDGEINHL, mask); - giu_set(GIUREDGEINHL, mask); - break; - default: - giu_set(GIUFEDGEINHL, mask); - giu_set(GIUREDGEINHL, mask); - break; - } - } - set_irq_chip_and_handler(GIU_IRQ(pin), - &giuint_low_irq_chip, - handle_edge_irq); - } else { - giu_clear(GIUINTTYPL, mask); - giu_clear(GIUINTHTSELL, mask); - set_irq_chip_and_handler(GIU_IRQ(pin), - &giuint_low_irq_chip, - handle_level_irq); - } - giu_write(GIUINTSTATL, mask); - } else if (pin < GIUINT_HIGH_MAX) { - mask = 1 << (pin - GIUINT_HIGH_OFFSET); - if (trigger != IRQ_TRIGGER_LEVEL) { - giu_set(GIUINTTYPH, mask); - if (signal == IRQ_SIGNAL_HOLD) - giu_set(GIUINTHTSELH, mask); - else - giu_clear(GIUINTHTSELH, mask); - if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) { - switch (trigger) { - case IRQ_TRIGGER_EDGE_FALLING: - giu_set(GIUFEDGEINHH, mask); - giu_clear(GIUREDGEINHH, mask); - break; - case IRQ_TRIGGER_EDGE_RISING: - giu_clear(GIUFEDGEINHH, mask); - giu_set(GIUREDGEINHH, mask); - break; - default: - giu_set(GIUFEDGEINHH, mask); - giu_set(GIUREDGEINHH, mask); - break; - } - } - set_irq_chip_and_handler(GIU_IRQ(pin), - &giuint_high_irq_chip, - handle_edge_irq); - } else { - giu_clear(GIUINTTYPH, mask); - giu_clear(GIUINTHTSELH, mask); - set_irq_chip_and_handler(GIU_IRQ(pin), - &giuint_high_irq_chip, - handle_level_irq); - } - giu_write(GIUINTSTATH, mask); - } -} -EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); - -void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) -{ - u16 mask; - - if (pin < GIUINT_HIGH_OFFSET) { - mask = 1 << pin; - if (level == IRQ_LEVEL_HIGH) - giu_set(GIUINTALSELL, mask); - else - giu_clear(GIUINTALSELL, mask); - giu_write(GIUINTSTATL, mask); - } else if (pin < GIUINT_HIGH_MAX) { - mask = 1 << (pin - GIUINT_HIGH_OFFSET); - if (level == IRQ_LEVEL_HIGH) - giu_set(GIUINTALSELH, mask); - else - giu_clear(GIUINTALSELH, mask); - giu_write(GIUINTSTATH, mask); - } -} -EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); - -static int giu_set_direction(struct gpio_chip *chip, unsigned pin, int dir) -{ - u16 offset, mask, reg; - unsigned long flags; - - if (pin >= chip->ngpio) - return -EINVAL; - - if (pin < 16) { - offset = GIUIOSELL; - mask = 1 << pin; - } else if (pin < 32) { - offset = GIUIOSELH; - mask = 1 << (pin - 16); - } else { - if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { - offset = GIUPODATEN; - mask = 1 << (pin - 32); - } else { - switch (pin) { - case 48: - offset = GIUPODATH; - mask = PIOEN0; - break; - case 49: - offset = GIUPODATH; - mask = PIOEN1; - break; - default: - return -EINVAL; - } - } - } - - spin_lock_irqsave(&giu_lock, flags); - - reg = giu_read(offset); - if (dir == GPIO_OUTPUT) - reg |= mask; - else - reg &= ~mask; - giu_write(offset, reg); - - spin_unlock_irqrestore(&giu_lock, flags); - - return 0; -} - -int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) -{ - u16 reg, mask; - unsigned long flags; - - if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) - return -EPERM; - - if (pin >= 15) - return -EINVAL; - - mask = 1 << pin; - - spin_lock_irqsave(&giu_lock, flags); - - if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { - reg = giu_read(GIUTERMUPDN); - if (pull == GPIO_PULL_UP) - reg |= mask; - else - reg &= ~mask; - giu_write(GIUTERMUPDN, reg); - - reg = giu_read(GIUUSEUPDN); - reg |= mask; - giu_write(GIUUSEUPDN, reg); - } else { - reg = giu_read(GIUUSEUPDN); - reg &= ~mask; - giu_write(GIUUSEUPDN, reg); - } - - spin_unlock_irqrestore(&giu_lock, flags); - - return 0; -} -EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); - -static int vr41xx_gpio_get(struct gpio_chip *chip, unsigned pin) -{ - u16 reg, mask; - - if (pin >= chip->ngpio) - return -EINVAL; - - if (pin < 16) { - reg = giu_read(GIUPIODL); - mask = 1 << pin; - } else if (pin < 32) { - reg = giu_read(GIUPIODH); - mask = 1 << (pin - 16); - } else if (pin < 48) { - reg = giu_read(GIUPODATL); - mask = 1 << (pin - 32); - } else { - reg = giu_read(GIUPODATH); - mask = 1 << (pin - 48); - } - - if (reg & mask) - return 1; - - return 0; -} - -static void vr41xx_gpio_set(struct gpio_chip *chip, unsigned pin, - int value) -{ - u16 offset, mask, reg; - unsigned long flags; - - if (pin >= chip->ngpio) - return; - - if (pin < 16) { - offset = GIUPIODL; - mask = 1 << pin; - } else if (pin < 32) { - offset = GIUPIODH; - mask = 1 << (pin - 16); - } else if (pin < 48) { - offset = GIUPODATL; - mask = 1 << (pin - 32); - } else { - offset = GIUPODATH; - mask = 1 << (pin - 48); - } - - spin_lock_irqsave(&giu_lock, flags); - - reg = giu_read(offset); - if (value) - reg |= mask; - else - reg &= ~mask; - giu_write(offset, reg); - - spin_unlock_irqrestore(&giu_lock, flags); -} - - -static int vr41xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - return giu_set_direction(chip, offset, GPIO_INPUT); -} - -static int vr41xx_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - vr41xx_gpio_set(chip, offset, value); - - return giu_set_direction(chip, offset, GPIO_OUTPUT); -} - -static int vr41xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - if (offset >= chip->ngpio) - return -EINVAL; - - return GIU_IRQ_BASE + offset; -} - -static struct gpio_chip vr41xx_gpio_chip = { - .label = "vr41xx", - .owner = THIS_MODULE, - .direction_input = vr41xx_gpio_direction_input, - .get = vr41xx_gpio_get, - .direction_output = vr41xx_gpio_direction_output, - .set = vr41xx_gpio_set, - .to_irq = vr41xx_gpio_to_irq, -}; - -static int __devinit giu_probe(struct platform_device *pdev) -{ - struct resource *res; - unsigned int trigger, i, pin; - struct irq_chip *chip; - int irq, retval; - - switch (pdev->id) { - case GPIO_50PINS_PULLUPDOWN: - giu_flags = GPIO_HAS_PULLUPDOWN_IO; - vr41xx_gpio_chip.ngpio = 50; - break; - case GPIO_36PINS: - vr41xx_gpio_chip.ngpio = 36; - break; - case GPIO_48PINS_EDGE_SELECT: - giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; - vr41xx_gpio_chip.ngpio = 48; - break; - default: - dev_err(&pdev->dev, "GIU: unknown ID %d\n", pdev->id); - return -ENODEV; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EBUSY; - - giu_base = ioremap(res->start, res->end - res->start + 1); - if (!giu_base) - return -ENOMEM; - - vr41xx_gpio_chip.dev = &pdev->dev; - - retval = gpiochip_add(&vr41xx_gpio_chip); - - giu_write(GIUINTENL, 0); - giu_write(GIUINTENH, 0); - - trigger = giu_read(GIUINTTYPH) << 16; - trigger |= giu_read(GIUINTTYPL); - for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { - pin = GPIO_PIN_OF_IRQ(i); - if (pin < GIUINT_HIGH_OFFSET) - chip = &giuint_low_irq_chip; - else - chip = &giuint_high_irq_chip; - - if (trigger & (1 << pin)) - set_irq_chip_and_handler(i, chip, handle_edge_irq); - else - set_irq_chip_and_handler(i, chip, handle_level_irq); - - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0 || irq >= nr_irqs) - return -EBUSY; - - return cascade_irq(irq, giu_get_irq); -} - -static int __devexit giu_remove(struct platform_device *pdev) -{ - if (giu_base) { - iounmap(giu_base); - giu_base = NULL; - } - - return 0; -} - -static struct platform_driver giu_device_driver = { - .probe = giu_probe, - .remove = __devexit_p(giu_remove), - .driver = { - .name = "GIU", - .owner = THIS_MODULE, - }, -}; - -static int __init vr41xx_giu_init(void) -{ - return platform_driver_register(&giu_device_driver); -} - -static void __exit vr41xx_giu_exit(void) -{ - platform_driver_unregister(&giu_device_driver); -} - -module_init(vr41xx_giu_init); -module_exit(vr41xx_giu_exit); diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index 39b393d38bb3..c961fe415aef 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -81,7 +81,6 @@ config DRM_I830 config DRM_I915 tristate "i915 driver" - depends on AGP_INTEL select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/trunk/drivers/gpu/drm/Makefile b/trunk/drivers/gpu/drm/Makefile index fe23f29f7cba..4e89ab08b7b8 100644 --- a/trunk/drivers/gpu/drm/Makefile +++ b/trunk/drivers/gpu/drm/Makefile @@ -16,7 +16,6 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm-$(CONFIG_COMPAT) += drm_ioc32.o obj-$(CONFIG_DRM) += drm.o -obj-$(CONFIG_DRM_TTM) += ttm/ obj-$(CONFIG_DRM_TDFX) += tdfx/ obj-$(CONFIG_DRM_R128) += r128/ obj-$(CONFIG_DRM_RADEON)+= radeon/ @@ -27,3 +26,4 @@ obj-$(CONFIG_DRM_I915) += i915/ obj-$(CONFIG_DRM_SIS) += sis/ obj-$(CONFIG_DRM_SAVAGE)+= savage/ obj-$(CONFIG_DRM_VIA) +=via/ +obj-$(CONFIG_DRM_TTM) += ttm/ diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index 80cc6d06d61b..7d0835226f6e 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -294,10 +294,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; - unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo; - unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo; - unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; - unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf); + unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 8 | pt->hsync_offset_lo; + unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 6 | pt->hsync_pulse_width_lo; + unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) | (pt->vsync_offset_pulse_width_lo & 0xf); + unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; /* ignore tiny modes */ if (hactive < 64 || vactive < 64) @@ -347,8 +347,8 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; - mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; - mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; + mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; + mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; if (quirks & EDID_QUIRK_DETAILED_IN_CM) { mode->width_mm *= 10; diff --git a/trunk/drivers/gpu/drm/i915/Makefile b/trunk/drivers/gpu/drm/i915/Makefile index 30d6b99fb302..51c5a050aa73 100644 --- a/trunk/drivers/gpu/drm/i915/Makefile +++ b/trunk/drivers/gpu/drm/i915/Makefile @@ -13,8 +13,6 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ intel_crt.o \ intel_lvds.o \ intel_bios.o \ - intel_dp.o \ - intel_dp_i2c.o \ intel_hdmi.o \ intel_sdvo.o \ intel_modes.o \ diff --git a/trunk/drivers/gpu/drm/i915/dvo.h b/trunk/drivers/gpu/drm/i915/dvo.h index 288fc50627e2..e747ac42fe3a 100644 --- a/trunk/drivers/gpu/drm/i915/dvo.h +++ b/trunk/drivers/gpu/drm/i915/dvo.h @@ -37,7 +37,7 @@ struct intel_dvo_device { /* GPIO register used for i2c bus to control this device */ u32 gpio; int slave_addr; - struct i2c_adapter *i2c_bus; + struct intel_i2c_chan *i2c_bus; const struct intel_dvo_dev_ops *dev_ops; void *dev_priv; @@ -52,7 +52,7 @@ struct intel_dvo_dev_ops { * Returns NULL if the device does not exist. */ bool (*init)(struct intel_dvo_device *dvo, - struct i2c_adapter *i2cbus); + struct intel_i2c_chan *i2cbus); /* * Called to allow the output a chance to create properties after the diff --git a/trunk/drivers/gpu/drm/i915/dvo_ch7017.c b/trunk/drivers/gpu/drm/i915/dvo_ch7017.c index 621815b531db..03d4b4973b02 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/trunk/drivers/gpu/drm/i915/dvo_ch7017.c @@ -176,20 +176,19 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode); static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) { - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = in_buf, @@ -209,11 +208,10 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) { - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; uint8_t out_buf[2]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -230,9 +228,8 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) /** Probes for a CH7017 on the given bus and slave address. */ static bool ch7017_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); struct ch7017_priv *priv; uint8_t val; @@ -240,7 +237,8 @@ static bool ch7017_init(struct intel_dvo_device *dvo, if (priv == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = priv; if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val)) @@ -250,7 +248,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo, val != CH7018_DEVICE_ID_VALUE && val != CH7019_DEVICE_ID_VALUE) { DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n", - val, i2cbus->adapter.name,dvo->slave_addr); + val, i2cbus->adapter.name,i2cbus->slave_addr); goto fail; } diff --git a/trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c b/trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c index a9b896289680..d2fd95dbd034 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/trunk/drivers/gpu/drm/i915/dvo_ch7xxx.c @@ -123,20 +123,19 @@ static char *ch7xxx_get_id(uint8_t vid) static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) { struct ch7xxx_priv *ch7xxx= dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = in_buf, @@ -153,7 +152,7 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) if (!ch7xxx->quiet) { DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } @@ -162,11 +161,10 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) { struct ch7xxx_priv *ch7xxx = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; uint8_t out_buf[2]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -180,14 +178,14 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) if (!ch7xxx->quiet) { DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } static bool ch7xxx_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { /* this will detect the CH7xxx chip on the specified i2c bus */ struct ch7xxx_priv *ch7xxx; @@ -198,7 +196,8 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, if (ch7xxx == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = ch7xxx; ch7xxx->quiet = true; @@ -208,7 +207,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, name = ch7xxx_get_id(vendor); if (!name) { DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", - vendor, adapter->name, dvo->slave_addr); + vendor, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } @@ -218,7 +217,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, if (device != CH7xxx_DID) { DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", - vendor, adapter->name, dvo->slave_addr); + vendor, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } diff --git a/trunk/drivers/gpu/drm/i915/dvo_ivch.c b/trunk/drivers/gpu/drm/i915/dvo_ivch.c index aa176f9921fe..0c8d375e8e37 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_ivch.c +++ b/trunk/drivers/gpu/drm/i915/dvo_ivch.c @@ -169,14 +169,13 @@ static void ivch_dump_regs(struct intel_dvo_device *dvo); static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) { struct ivch_priv *priv = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[1]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 0, }, @@ -187,7 +186,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD | I2C_M_NOSTART, .len = 2, .buf = in_buf, @@ -203,7 +202,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) if (!priv->quiet) { DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } @@ -212,11 +211,10 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) { struct ivch_priv *priv = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[3]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 3, .buf = out_buf, @@ -231,7 +229,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) if (!priv->quiet) { DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; @@ -239,7 +237,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) /** Probes the given bus and slave address for an ivch */ static bool ivch_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { struct ivch_priv *priv; uint16_t temp; @@ -248,7 +246,8 @@ static bool ivch_init(struct intel_dvo_device *dvo, if (priv == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = priv; priv->quiet = true; diff --git a/trunk/drivers/gpu/drm/i915/dvo_sil164.c b/trunk/drivers/gpu/drm/i915/dvo_sil164.c index e1c1f7341e5c..033a4bb070b2 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_sil164.c +++ b/trunk/drivers/gpu/drm/i915/dvo_sil164.c @@ -76,20 +76,19 @@ struct sil164_priv { static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) { struct sil164_priv *sil = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = in_buf, @@ -106,7 +105,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) if (!sil->quiet) { DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } @@ -114,11 +113,10 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) { struct sil164_priv *sil= dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; uint8_t out_buf[2]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -132,7 +130,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) if (!sil->quiet) { DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; @@ -140,7 +138,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) /* Silicon Image 164 driver for chip on i2c bus */ static bool sil164_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { /* this will detect the SIL164 chip on the specified i2c bus */ struct sil164_priv *sil; @@ -150,7 +148,8 @@ static bool sil164_init(struct intel_dvo_device *dvo, if (sil == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = sil; sil->quiet = true; @@ -159,7 +158,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, if (ch != (SIL164_VID & 0xff)) { DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", - ch, adapter->name, dvo->slave_addr); + ch, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } @@ -168,7 +167,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, if (ch != (SIL164_DID & 0xff)) { DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", - ch, adapter->name, dvo->slave_addr); + ch, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } sil->quiet = false; diff --git a/trunk/drivers/gpu/drm/i915/dvo_tfp410.c b/trunk/drivers/gpu/drm/i915/dvo_tfp410.c index 9ecc907384ec..207fda806ebf 100644 --- a/trunk/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/trunk/drivers/gpu/drm/i915/dvo_tfp410.c @@ -101,20 +101,19 @@ struct tfp410_priv { static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) { struct tfp410_priv *tfp = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; u8 out_buf[2]; u8 in_buf[2]; struct i2c_msg msgs[] = { { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = in_buf, @@ -131,7 +130,7 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) if (!tfp->quiet) { DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; } @@ -139,11 +138,10 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) { struct tfp410_priv *tfp = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); + struct intel_i2c_chan *i2cbus = dvo->i2c_bus; uint8_t out_buf[2]; struct i2c_msg msg = { - .addr = dvo->slave_addr, + .addr = i2cbus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -157,7 +155,7 @@ static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) if (!tfp->quiet) { DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", - addr, i2cbus->adapter.name, dvo->slave_addr); + addr, i2cbus->adapter.name, i2cbus->slave_addr); } return false; @@ -176,7 +174,7 @@ static int tfp410_getid(struct intel_dvo_device *dvo, int addr) /* Ti TFP410 driver for chip on i2c bus */ static bool tfp410_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) + struct intel_i2c_chan *i2cbus) { /* this will detect the tfp410 chip on the specified i2c bus */ struct tfp410_priv *tfp; @@ -186,19 +184,20 @@ static bool tfp410_init(struct intel_dvo_device *dvo, if (tfp == NULL) return false; - dvo->i2c_bus = adapter; + dvo->i2c_bus = i2cbus; + dvo->i2c_bus->slave_addr = dvo->slave_addr; dvo->dev_priv = tfp; tfp->quiet = true; if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) { DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n", - id, adapter->name, dvo->slave_addr); + id, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) { DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n", - id, adapter->name, dvo->slave_addr); + id, i2cbus->adapter.name, i2cbus->slave_addr); goto out; } tfp->quiet = false; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index e3cb4025e323..98560e1e899a 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -67,6 +67,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) pci_save_state(dev->pdev); + i915_save_state(dev); + /* If KMS is active, we do the leavevt stuff here */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (i915_gem_idle(dev)) @@ -75,8 +77,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) drm_irq_uninstall(dev); } - i915_save_state(dev); - intel_opregion_free(dev, 1); if (state.event == PM_EVENT_SUSPEND) { diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index bb4c2d387b6c..7a84f04e8439 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -306,17 +306,6 @@ typedef struct drm_i915_private { u32 saveCURBPOS; u32 saveCURBBASE; u32 saveCURSIZE; - u32 saveDP_B; - u32 saveDP_C; - u32 saveDP_D; - u32 savePIPEA_GMCH_DATA_M; - u32 savePIPEB_GMCH_DATA_M; - u32 savePIPEA_GMCH_DATA_N; - u32 savePIPEB_GMCH_DATA_N; - u32 savePIPEA_DP_LINK_M; - u32 savePIPEB_DP_LINK_M; - u32 savePIPEA_DP_LINK_N; - u32 savePIPEB_DP_LINK_N; struct { struct drm_mm gtt_space; @@ -868,7 +857,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ IS_I915GM(dev))) #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) -#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 876b65cb7629..fd2b8bdffe3f 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1006,7 +1006,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); #if WATCH_BUF - DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", + DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", obj, obj->size, read_domains, write_domain); #endif if (read_domains & I915_GEM_DOMAIN_GTT) { @@ -1050,7 +1050,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, } #if WATCH_BUF - DRM_INFO("%s: sw_finish %d (%p %zd)\n", + DRM_INFO("%s: sw_finish %d (%p %d)\n", __func__, args->handle, obj, obj->size); #endif obj_priv = obj->driver_private; @@ -2423,7 +2423,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) } #if WATCH_BUF - DRM_INFO("Binding object of size %zd at 0x%08x\n", + DRM_INFO("Binding object of size %d at 0x%08x\n", obj->size, obj_priv->gtt_offset); #endif ret = i915_gem_object_get_pages(obj); @@ -4227,7 +4227,6 @@ i915_gem_lastclose(struct drm_device *dev) void i915_gem_load(struct drm_device *dev) { - int i; drm_i915_private_t *dev_priv = dev->dev_private; spin_lock_init(&dev_priv->mm.active_list_lock); @@ -4247,18 +4246,6 @@ i915_gem_load(struct drm_device *dev) else dev_priv->num_fence_regs = 8; - /* Initialize fence registers to zero */ - if (IS_I965G(dev)) { - for (i = 0; i < 16; i++) - I915_WRITE64(FENCE_REG_965_0 + (i * 8), 0); - } else { - for (i = 0; i < 8; i++) - I915_WRITE(FENCE_REG_830_0 + (i * 4), 0); - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - for (i = 0; i < 8; i++) - I915_WRITE(FENCE_REG_945_8 + (i * 4), 0); - } - i915_gem_detect_bit_6_swizzle(dev); } diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_debug.c b/trunk/drivers/gpu/drm/i915/i915_gem_debug.c index e602614bd3f8..8d0b943e2c5a 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_debug.c @@ -87,7 +87,7 @@ i915_gem_dump_object(struct drm_gem_object *obj, int len, chunk_len = page_len - chunk; if (chunk_len > 128) chunk_len = 128; - i915_gem_dump_page(obj_priv->pages[page], + i915_gem_dump_page(obj_priv->page_list[page], chunk, chunk + chunk_len, obj_priv->gtt_offset + page * PAGE_SIZE, @@ -143,7 +143,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) uint32_t *backing_map = NULL; int bad_count = 0; - DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", + DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n", __func__, obj, obj_priv->gtt_offset, handle, obj->size / 1024); @@ -157,7 +157,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) for (page = 0; page < obj->size / PAGE_SIZE; page++) { int i; - backing_map = kmap_atomic(obj_priv->pages[page], KM_USER0); + backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0); if (backing_map == NULL) { DRM_ERROR("failed to map backing page\n"); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c index daeae62e1c28..5c1ceec49f5b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -114,13 +114,11 @@ intel_alloc_mchbar_resource(struct drm_device *dev) mchbar_addr = ((u64)temp_hi << 32) | temp_lo; /* If ACPI doesn't have it, assume we need to allocate it ourselves */ -#ifdef CONFIG_PNP if (mchbar_addr && pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { ret = 0; goto out_put; } -#endif /* Get some space for it */ ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 228546f6eaa4..b86b7b7130c6 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -232,17 +232,7 @@ static void i915_hotplug_work_func(struct work_struct *work) drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, hotplug_work); struct drm_device *dev = dev_priv->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - - if (mode_config->num_connector) { - list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - - if (intel_output->hot_plug) - (*intel_output->hot_plug) (intel_output); - } - } + /* Just fire off a uevent and let userspace tell us what to do */ drm_sysfs_hotplug_event(dev); } diff --git a/trunk/drivers/gpu/drm/i915/i915_opregion.c b/trunk/drivers/gpu/drm/i915/i915_opregion.c index e4b4e8898e39..dc425e74a268 100644 --- a/trunk/drivers/gpu/drm/i915/i915_opregion.c +++ b/trunk/drivers/gpu/drm/i915/i915_opregion.c @@ -419,7 +419,7 @@ void intel_opregion_free(struct drm_device *dev, int suspend) return; if (!suspend) - acpi_video_unregister(); + acpi_video_exit(); opregion->acpi->drdy = 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 88bf7521405f..f6237a0b1133 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -569,19 +569,6 @@ #define C0DRB3 0x10206 #define C1DRB3 0x10606 -/* Clocking configuration register */ -#define CLKCFG 0x10c00 -#define CLKCFG_FSB_400 (0 << 0) /* hrawclk 100 */ -#define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ -#define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ -#define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ -#define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ -#define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ -/* this is a guess, could be 5 as well */ -#define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ -#define CLKCFG_FSB_1600_ALT (5 << 0) /* hrawclk 400 */ -#define CLKCFG_FSB_MASK (7 << 0) - /** GM965 GM45 render standby register */ #define MCHBAR_RENDER_STANDBY 0x111B8 @@ -847,25 +834,9 @@ #define HORIZ_INTERP_MASK (3 << 6) #define HORIZ_AUTO_SCALE (1 << 5) #define PANEL_8TO6_DITHER_ENABLE (1 << 3) -#define PFIT_FILTER_FUZZY (0 << 24) -#define PFIT_SCALING_AUTO (0 << 26) -#define PFIT_SCALING_PROGRAMMED (1 << 26) -#define PFIT_SCALING_PILLAR (2 << 26) -#define PFIT_SCALING_LETTER (3 << 26) #define PFIT_PGM_RATIOS 0x61234 #define PFIT_VERT_SCALE_MASK 0xfff00000 #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 -/* Pre-965 */ -#define PFIT_VERT_SCALE_SHIFT 20 -#define PFIT_VERT_SCALE_MASK 0xfff00000 -#define PFIT_HORIZ_SCALE_SHIFT 4 -#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 -/* 965+ */ -#define PFIT_VERT_SCALE_SHIFT_965 16 -#define PFIT_VERT_SCALE_MASK_965 0x1fff0000 -#define PFIT_HORIZ_SCALE_SHIFT_965 0 -#define PFIT_HORIZ_SCALE_MASK_965 0x00001fff - #define PFIT_AUTO_RATIOS 0x61238 /* Backlight control */ diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 8d8e083d14ab..a98e2831ed31 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -322,20 +322,6 @@ int i915_save_state(struct drm_device *dev) dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); - /* Display Port state */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - dev_priv->saveDP_B = I915_READ(DP_B); - dev_priv->saveDP_C = I915_READ(DP_C); - dev_priv->saveDP_D = I915_READ(DP_D); - dev_priv->savePIPEA_GMCH_DATA_M = I915_READ(PIPEA_GMCH_DATA_M); - dev_priv->savePIPEB_GMCH_DATA_M = I915_READ(PIPEB_GMCH_DATA_M); - dev_priv->savePIPEA_GMCH_DATA_N = I915_READ(PIPEA_GMCH_DATA_N); - dev_priv->savePIPEB_GMCH_DATA_N = I915_READ(PIPEB_GMCH_DATA_N); - dev_priv->savePIPEA_DP_LINK_M = I915_READ(PIPEA_DP_LINK_M); - dev_priv->savePIPEB_DP_LINK_M = I915_READ(PIPEB_DP_LINK_M); - dev_priv->savePIPEA_DP_LINK_N = I915_READ(PIPEA_DP_LINK_N); - dev_priv->savePIPEB_DP_LINK_N = I915_READ(PIPEB_DP_LINK_N); - } /* FIXME: save TV & SDVO state */ /* FBC state */ @@ -418,19 +404,7 @@ int i915_restore_state(struct drm_device *dev) for (i = 0; i < 8; i++) I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); } - - /* Display port ratios (must be done before clock is set) */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - I915_WRITE(PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); - I915_WRITE(PIPEB_GMCH_DATA_M, dev_priv->savePIPEB_GMCH_DATA_M); - I915_WRITE(PIPEA_GMCH_DATA_N, dev_priv->savePIPEA_GMCH_DATA_N); - I915_WRITE(PIPEB_GMCH_DATA_N, dev_priv->savePIPEB_GMCH_DATA_N); - I915_WRITE(PIPEA_DP_LINK_M, dev_priv->savePIPEA_DP_LINK_M); - I915_WRITE(PIPEB_DP_LINK_M, dev_priv->savePIPEB_DP_LINK_M); - I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); - I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); - } - + /* Pipe & plane A info */ /* Prime the clock */ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { @@ -544,12 +518,6 @@ int i915_restore_state(struct drm_device *dev) I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); - /* Display Port state */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - I915_WRITE(DP_B, dev_priv->saveDP_B); - I915_WRITE(DP_C, dev_priv->saveDP_C); - I915_WRITE(DP_D, dev_priv->saveDP_D); - } /* FIXME: restore TV & SDVO state */ /* FBC info */ diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.c b/trunk/drivers/gpu/drm/i915/intel_bios.c index 716409a57244..cdd126d068a7 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.c +++ b/trunk/drivers/gpu/drm/i915/intel_bios.c @@ -99,11 +99,9 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, { struct bdb_lvds_options *lvds_options; struct bdb_lvds_lfp_data *lvds_lfp_data; - struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; struct bdb_lvds_lfp_data_entry *entry; struct lvds_dvo_timing *dvo_timing; struct drm_display_mode *panel_fixed_mode; - int lfp_data_size; /* Defaults if we can't find VBT info */ dev_priv->lvds_dither = 0; @@ -121,17 +119,9 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, if (!lvds_lfp_data) return; - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); - if (!lvds_lfp_data_ptrs) - return; - dev_priv->lvds_vbt = 1; - lfp_data_size = lvds_lfp_data_ptrs->ptr[1].dvo_timing_offset - - lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset; - entry = (struct bdb_lvds_lfp_data_entry *) - ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * - lvds_options->panel_type)); + entry = &lvds_lfp_data->data[lvds_options->panel_type]; dvo_timing = &entry->dvo_timing; panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 73e7b9cecac8..3e1c78162119 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -29,7 +29,6 @@ #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" -#include "intel_dp.h" #include "drm_crtc_helper.h" @@ -128,6 +127,19 @@ struct intel_limit { #define I9XX_P2_LVDS_FAST 7 #define I9XX_P2_LVDS_SLOW_LIMIT 112000 +#define INTEL_LIMIT_I8XX_DVO_DAC 0 +#define INTEL_LIMIT_I8XX_LVDS 1 +#define INTEL_LIMIT_I9XX_SDVO_DAC 2 +#define INTEL_LIMIT_I9XX_LVDS 3 +#define INTEL_LIMIT_G4X_SDVO 4 +#define INTEL_LIMIT_G4X_HDMI_DAC 5 +#define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6 +#define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7 +#define INTEL_LIMIT_IGD_SDVO_DAC 8 +#define INTEL_LIMIT_IGD_LVDS 9 +#define INTEL_LIMIT_IGDNG_SDVO_DAC 10 +#define INTEL_LIMIT_IGDNG_LVDS 11 + /*The parameter is for SDVO on G4x platform*/ #define G4X_DOT_SDVO_MIN 25000 #define G4X_DOT_SDVO_MAX 270000 @@ -206,25 +218,6 @@ struct intel_limit { #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 -/*The parameter is for DISPLAY PORT on G4x platform*/ -#define G4X_DOT_DISPLAY_PORT_MIN 161670 -#define G4X_DOT_DISPLAY_PORT_MAX 227000 -#define G4X_N_DISPLAY_PORT_MIN 1 -#define G4X_N_DISPLAY_PORT_MAX 2 -#define G4X_M_DISPLAY_PORT_MIN 97 -#define G4X_M_DISPLAY_PORT_MAX 108 -#define G4X_M1_DISPLAY_PORT_MIN 0x10 -#define G4X_M1_DISPLAY_PORT_MAX 0x12 -#define G4X_M2_DISPLAY_PORT_MIN 0x05 -#define G4X_M2_DISPLAY_PORT_MAX 0x06 -#define G4X_P_DISPLAY_PORT_MIN 10 -#define G4X_P_DISPLAY_PORT_MAX 20 -#define G4X_P1_DISPLAY_PORT_MIN 1 -#define G4X_P1_DISPLAY_PORT_MAX 2 -#define G4X_P2_DISPLAY_PORT_SLOW 10 -#define G4X_P2_DISPLAY_PORT_FAST 10 -#define G4X_P2_DISPLAY_PORT_LIMIT 0 - /* IGDNG */ /* as we calculate clock using (register_value + 2) for N/M1/M2, so here the range value for them is (actual_value-2). @@ -263,11 +256,8 @@ static bool intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); -static bool -intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); - -static const intel_limit_t intel_limits_i8xx_dvo = { +static const intel_limit_t intel_limits[] = { + { /* INTEL_LIMIT_I8XX_DVO_DAC */ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, @@ -279,9 +269,8 @@ static const intel_limit_t intel_limits_i8xx_dvo = { .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i8xx_lvds = { + }, + { /* INTEL_LIMIT_I8XX_LVDS */ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, @@ -293,9 +282,8 @@ static const intel_limit_t intel_limits_i8xx_lvds = { .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i9xx_sdvo = { + }, + { /* INTEL_LIMIT_I9XX_SDVO_DAC */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, @@ -307,9 +295,8 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i9xx_lvds = { + }, + { /* INTEL_LIMIT_I9XX_LVDS */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, @@ -324,10 +311,9 @@ static const intel_limit_t intel_limits_i9xx_lvds = { .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, .find_pll = intel_find_best_PLL, -}; - + }, /* below parameter and function is for G4X Chipset Family*/ -static const intel_limit_t intel_limits_g4x_sdvo = { + { /* INTEL_LIMIT_G4X_SDVO */ .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, @@ -341,9 +327,8 @@ static const intel_limit_t intel_limits_g4x_sdvo = { .p2_fast = G4X_P2_SDVO_FAST }, .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_hdmi = { + }, + { /* INTEL_LIMIT_G4X_HDMI_DAC */ .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, @@ -357,9 +342,8 @@ static const intel_limit_t intel_limits_g4x_hdmi = { .p2_fast = G4X_P2_HDMI_DAC_FAST }, .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_single_channel_lvds = { + }, + { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */ .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, .vco = { .min = G4X_VCO_MIN, @@ -381,9 +365,8 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST }, .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { + }, + { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */ .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, .vco = { .min = G4X_VCO_MIN, @@ -405,32 +388,8 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST }, .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_display_port = { - .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN, - .max = G4X_DOT_DISPLAY_PORT_MAX }, - .vco = { .min = G4X_VCO_MIN, - .max = G4X_VCO_MAX}, - .n = { .min = G4X_N_DISPLAY_PORT_MIN, - .max = G4X_N_DISPLAY_PORT_MAX }, - .m = { .min = G4X_M_DISPLAY_PORT_MIN, - .max = G4X_M_DISPLAY_PORT_MAX }, - .m1 = { .min = G4X_M1_DISPLAY_PORT_MIN, - .max = G4X_M1_DISPLAY_PORT_MAX }, - .m2 = { .min = G4X_M2_DISPLAY_PORT_MIN, - .max = G4X_M2_DISPLAY_PORT_MAX }, - .p = { .min = G4X_P_DISPLAY_PORT_MIN, - .max = G4X_P_DISPLAY_PORT_MAX }, - .p1 = { .min = G4X_P1_DISPLAY_PORT_MIN, - .max = G4X_P1_DISPLAY_PORT_MAX}, - .p2 = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT, - .p2_slow = G4X_P2_DISPLAY_PORT_SLOW, - .p2_fast = G4X_P2_DISPLAY_PORT_FAST }, - .find_pll = intel_find_pll_g4x_dp, -}; - -static const intel_limit_t intel_limits_igd_sdvo = { + }, + { /* INTEL_LIMIT_IGD_SDVO */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, @@ -442,9 +401,8 @@ static const intel_limit_t intel_limits_igd_sdvo = { .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_igd_lvds = { + }, + { /* INTEL_LIMIT_IGD_LVDS */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, @@ -457,9 +415,8 @@ static const intel_limit_t intel_limits_igd_lvds = { .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_igdng_sdvo = { + }, + { /* INTEL_LIMIT_IGDNG_SDVO_DAC */ .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, @@ -472,9 +429,8 @@ static const intel_limit_t intel_limits_igdng_sdvo = { .p2_slow = IGDNG_P2_SDVO_DAC_SLOW, .p2_fast = IGDNG_P2_SDVO_DAC_FAST }, .find_pll = intel_igdng_find_best_PLL, -}; - -static const intel_limit_t intel_limits_igdng_lvds = { + }, + { /* INTEL_LIMIT_IGDNG_LVDS */ .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, @@ -487,15 +443,16 @@ static const intel_limit_t intel_limits_igdng_lvds = { .p2_slow = IGDNG_P2_LVDS_SLOW, .p2_fast = IGDNG_P2_LVDS_FAST }, .find_pll = intel_igdng_find_best_PLL, + }, }; static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc) { const intel_limit_t *limit; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_igdng_lvds; + limit = &intel_limits[INTEL_LIMIT_IGDNG_LVDS]; else - limit = &intel_limits_igdng_sdvo; + limit = &intel_limits[INTEL_LIMIT_IGDNG_SDVO_DAC]; return limit; } @@ -510,19 +467,19 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) /* LVDS with dual channel */ - limit = &intel_limits_g4x_dual_channel_lvds; + limit = &intel_limits + [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS]; else /* LVDS with dual channel */ - limit = &intel_limits_g4x_single_channel_lvds; + limit = &intel_limits + [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS]; } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { - limit = &intel_limits_g4x_hdmi; + limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { - limit = &intel_limits_g4x_sdvo; - } else if (intel_pipe_has_type (crtc, INTEL_OUTPUT_DISPLAYPORT)) { - limit = &intel_limits_g4x_display_port; + limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; } else /* The option is for other outputs */ - limit = &intel_limits_i9xx_sdvo; + limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; return limit; } @@ -538,19 +495,19 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) limit = intel_g4x_limit(crtc); } else if (IS_I9XX(dev) && !IS_IGD(dev)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_i9xx_lvds; + limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; else - limit = &intel_limits_i9xx_sdvo; + limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; } else if (IS_IGD(dev)) { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_igd_lvds; + limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; else - limit = &intel_limits_igd_sdvo; + limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; } else { if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_i8xx_lvds; + limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; else - limit = &intel_limits_i8xx_dvo; + limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; } return limit; } @@ -807,35 +764,6 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, return found; } -/* DisplayPort has only two frequencies, 162MHz and 270MHz */ -static bool -intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) -{ - intel_clock_t clock; - if (target < 200000) { - clock.dot = 161670; - clock.p = 20; - clock.p1 = 2; - clock.p2 = 10; - clock.n = 0x01; - clock.m = 97; - clock.m1 = 0x10; - clock.m2 = 0x05; - } else { - clock.dot = 270000; - clock.p = 10; - clock.p1 = 1; - clock.p2 = 10; - clock.n = 0x02; - clock.m = 108; - clock.m1 = 0x12; - clock.m2 = 0x06; - } - memcpy(best_clock, &clock, sizeof(intel_clock_t)); - return true; -} - void intel_wait_for_vblank(struct drm_device *dev) { @@ -1613,7 +1541,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, intel_clock_t clock; u32 dpll = 0, fp = 0, dspcntr, pipeconf; bool ok, is_sdvo = false, is_dvo = false; - bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; + bool is_crt = false, is_lvds = false, is_tv = false; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; const intel_limit_t *limit; @@ -1657,9 +1585,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, case INTEL_OUTPUT_ANALOG: is_crt = true; break; - case INTEL_OUTPUT_DISPLAYPORT: - is_dp = true; - break; } num_outputs++; @@ -1675,7 +1600,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } else { refclk = 48000; } - /* * Returns a set of divisors for the desired target clock with the given @@ -1738,8 +1662,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, else if (IS_IGDNG(dev)) dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; } - if (is_dp) - dpll |= DPLL_DVO_HIGH_SPEED; /* compute bitmask from p1 value */ if (IS_IGD(dev)) @@ -1887,8 +1809,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(lvds_reg, lvds); I915_READ(lvds_reg); } - if (is_dp) - intel_dp_set_m_n(crtc, mode, adjusted_mode); I915_WRITE(fp_reg, fp); I915_WRITE(dpll_reg, dpll); @@ -2555,8 +2475,6 @@ static void intel_setup_outputs(struct drm_device *dev) found = intel_sdvo_init(dev, SDVOB); if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) intel_hdmi_init(dev, SDVOB); - if (!found && SUPPORTS_INTEGRATED_DP(dev)) - intel_dp_init(dev, DP_B); } /* Before G4X SDVOC doesn't have its own detect register */ @@ -2569,11 +2487,7 @@ static void intel_setup_outputs(struct drm_device *dev) found = intel_sdvo_init(dev, SDVOC); if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) intel_hdmi_init(dev, SDVOC); - if (!found && SUPPORTS_INTEGRATED_DP(dev)) - intel_dp_init(dev, DP_C); } - if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) - intel_dp_init(dev, DP_D); } else intel_dvo_init(dev); @@ -2616,11 +2530,6 @@ static void intel_setup_outputs(struct drm_device *dev) (1 << 1)); clone_mask = (1 << INTEL_OUTPUT_TVOUT); break; - case INTEL_OUTPUT_DISPLAYPORT: - crtc_mask = ((1 << 0) | - (1 << 1)); - clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); - break; } encoder->possible_crtcs = crtc_mask; encoder->possible_clones = intel_connector_clones(dev, clone_mask); diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c deleted file mode 100644 index 8f8d37d5663a..000000000000 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ /dev/null @@ -1,1153 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Keith Packard - * - */ - -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "intel_dp.h" - -#define DP_LINK_STATUS_SIZE 6 -#define DP_LINK_CHECK_TIMEOUT (10 * 1000) - -#define DP_LINK_CONFIGURATION_SIZE 9 - -struct intel_dp_priv { - uint32_t output_reg; - uint32_t DP; - uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; - uint32_t save_DP; - uint8_t save_link_configuration[DP_LINK_CONFIGURATION_SIZE]; - bool has_audio; - int dpms_mode; - uint8_t link_bw; - uint8_t lane_count; - uint8_t dpcd[4]; - struct intel_output *intel_output; - struct i2c_adapter adapter; - struct i2c_algo_dp_aux_data algo; -}; - -static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, - uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); - -static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); - -static int -intel_dp_max_lane_count(struct intel_output *intel_output) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - int max_lane_count = 4; - - if (dp_priv->dpcd[0] >= 0x11) { - max_lane_count = dp_priv->dpcd[2] & 0x1f; - switch (max_lane_count) { - case 1: case 2: case 4: - break; - default: - max_lane_count = 4; - } - } - return max_lane_count; -} - -static int -intel_dp_max_link_bw(struct intel_output *intel_output) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - int max_link_bw = dp_priv->dpcd[1]; - - switch (max_link_bw) { - case DP_LINK_BW_1_62: - case DP_LINK_BW_2_7: - break; - default: - max_link_bw = DP_LINK_BW_1_62; - break; - } - return max_link_bw; -} - -static int -intel_dp_link_clock(uint8_t link_bw) -{ - if (link_bw == DP_LINK_BW_2_7) - return 270000; - else - return 162000; -} - -/* I think this is a fiction */ -static int -intel_dp_link_required(int pixel_clock) -{ - return pixel_clock * 3; -} - -static int -intel_dp_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct intel_output *intel_output = to_intel_output(connector); - int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); - int max_lanes = intel_dp_max_lane_count(intel_output); - - if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes) - return MODE_CLOCK_HIGH; - - if (mode->clock < 10000) - return MODE_CLOCK_LOW; - - return MODE_OK; -} - -static uint32_t -pack_aux(uint8_t *src, int src_bytes) -{ - int i; - uint32_t v = 0; - - if (src_bytes > 4) - src_bytes = 4; - for (i = 0; i < src_bytes; i++) - v |= ((uint32_t) src[i]) << ((3-i) * 8); - return v; -} - -static void -unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) -{ - int i; - if (dst_bytes > 4) - dst_bytes = 4; - for (i = 0; i < dst_bytes; i++) - dst[i] = src >> ((3-i) * 8); -} - -/* hrawclock is 1/4 the FSB frequency */ -static int -intel_hrawclk(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t clkcfg; - - clkcfg = I915_READ(CLKCFG); - switch (clkcfg & CLKCFG_FSB_MASK) { - case CLKCFG_FSB_400: - return 100; - case CLKCFG_FSB_533: - return 133; - case CLKCFG_FSB_667: - return 166; - case CLKCFG_FSB_800: - return 200; - case CLKCFG_FSB_1067: - return 266; - case CLKCFG_FSB_1333: - return 333; - /* these two are just a guess; one of them might be right */ - case CLKCFG_FSB_1600: - case CLKCFG_FSB_1600_ALT: - return 400; - default: - return 133; - } -} - -static int -intel_dp_aux_ch(struct intel_output *intel_output, - uint8_t *send, int send_bytes, - uint8_t *recv, int recv_size) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - uint32_t output_reg = dp_priv->output_reg; - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t ch_ctl = output_reg + 0x10; - uint32_t ch_data = ch_ctl + 4; - int i; - int recv_bytes; - uint32_t ctl; - uint32_t status; - uint32_t aux_clock_divider; - int try; - - /* The clock divider is based off the hrawclk, - * and would like to run at 2MHz. So, take the - * hrawclk value and divide by 2 and use that - */ - aux_clock_divider = intel_hrawclk(dev) / 2; - /* Must try at least 3 times according to DP spec */ - for (try = 0; try < 5; try++) { - /* Load the send data into the aux channel data registers */ - for (i = 0; i < send_bytes; i += 4) { - uint32_t d = pack_aux(send + i, send_bytes - i);; - - I915_WRITE(ch_data + i, d); - } - - ctl = (DP_AUX_CH_CTL_SEND_BUSY | - DP_AUX_CH_CTL_TIME_OUT_400us | - (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - (5 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | - (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | - DP_AUX_CH_CTL_DONE | - DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR); - - /* Send the command and wait for it to complete */ - I915_WRITE(ch_ctl, ctl); - (void) I915_READ(ch_ctl); - for (;;) { - udelay(100); - status = I915_READ(ch_ctl); - if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) - break; - } - - /* Clear done status and any errors */ - I915_WRITE(ch_ctl, (ctl | - DP_AUX_CH_CTL_DONE | - DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR)); - (void) I915_READ(ch_ctl); - if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0) - break; - } - - if ((status & DP_AUX_CH_CTL_DONE) == 0) { - printk(KERN_ERR "dp_aux_ch not done status 0x%08x\n", status); - return -EBUSY; - } - - /* Check for timeout or receive error. - * Timeouts occur when the sink is not connected - */ - if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { - printk(KERN_ERR "dp_aux_ch receive error status 0x%08x\n", status); - return -EIO; - } - if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { - printk(KERN_ERR "dp_aux_ch timeout status 0x%08x\n", status); - return -ETIMEDOUT; - } - - /* Unload any bytes sent back from the other side */ - recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> - DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); - - if (recv_bytes > recv_size) - recv_bytes = recv_size; - - for (i = 0; i < recv_bytes; i += 4) { - uint32_t d = I915_READ(ch_data + i); - - unpack_aux(d, recv + i, recv_bytes - i); - } - - return recv_bytes; -} - -/* Write data to the aux channel in native mode */ -static int -intel_dp_aux_native_write(struct intel_output *intel_output, - uint16_t address, uint8_t *send, int send_bytes) -{ - int ret; - uint8_t msg[20]; - int msg_bytes; - uint8_t ack; - - if (send_bytes > 16) - return -1; - msg[0] = AUX_NATIVE_WRITE << 4; - msg[1] = address >> 8; - msg[2] = address; - msg[3] = send_bytes - 1; - memcpy(&msg[4], send, send_bytes); - msg_bytes = send_bytes + 4; - for (;;) { - ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1); - if (ret < 0) - return ret; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - break; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(100); - else - return -EIO; - } - return send_bytes; -} - -/* Write a single byte to the aux channel in native mode */ -static int -intel_dp_aux_native_write_1(struct intel_output *intel_output, - uint16_t address, uint8_t byte) -{ - return intel_dp_aux_native_write(intel_output, address, &byte, 1); -} - -/* read bytes from a native aux channel */ -static int -intel_dp_aux_native_read(struct intel_output *intel_output, - uint16_t address, uint8_t *recv, int recv_bytes) -{ - uint8_t msg[4]; - int msg_bytes; - uint8_t reply[20]; - int reply_bytes; - uint8_t ack; - int ret; - - msg[0] = AUX_NATIVE_READ << 4; - msg[1] = address >> 8; - msg[2] = address & 0xff; - msg[3] = recv_bytes - 1; - - msg_bytes = 4; - reply_bytes = recv_bytes + 1; - - for (;;) { - ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, - reply, reply_bytes); - if (ret == 0) - return -EPROTO; - if (ret < 0) - return ret; - ack = reply[0]; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) { - memcpy(recv, reply + 1, ret - 1); - return ret - 1; - } - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(100); - else - return -EIO; - } -} - -static int -intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, - uint8_t *send, int send_bytes, - uint8_t *recv, int recv_bytes) -{ - struct intel_dp_priv *dp_priv = container_of(adapter, - struct intel_dp_priv, - adapter); - struct intel_output *intel_output = dp_priv->intel_output; - - return intel_dp_aux_ch(intel_output, - send, send_bytes, recv, recv_bytes); -} - -static int -intel_dp_i2c_init(struct intel_output *intel_output, const char *name) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - DRM_ERROR("i2c_init %s\n", name); - dp_priv->algo.running = false; - dp_priv->algo.address = 0; - dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; - - memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); - dp_priv->adapter.owner = THIS_MODULE; - dp_priv->adapter.class = I2C_CLASS_DDC; - strncpy (dp_priv->adapter.name, name, sizeof dp_priv->adapter.name - 1); - dp_priv->adapter.name[sizeof dp_priv->adapter.name - 1] = '\0'; - dp_priv->adapter.algo_data = &dp_priv->algo; - dp_priv->adapter.dev.parent = &intel_output->base.kdev; - - return i2c_dp_aux_add_bus(&dp_priv->adapter); -} - -static bool -intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - int lane_count, clock; - int max_lane_count = intel_dp_max_lane_count(intel_output); - int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0; - static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; - - for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { - for (clock = 0; clock <= max_clock; clock++) { - int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; - - if (intel_dp_link_required(mode->clock) <= link_avail) { - dp_priv->link_bw = bws[clock]; - dp_priv->lane_count = lane_count; - adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); - printk(KERN_ERR "link bw %02x lane count %d clock %d\n", - dp_priv->link_bw, dp_priv->lane_count, - adjusted_mode->clock); - return true; - } - } - } - return false; -} - -struct intel_dp_m_n { - uint32_t tu; - uint32_t gmch_m; - uint32_t gmch_n; - uint32_t link_m; - uint32_t link_n; -}; - -static void -intel_reduce_ratio(uint32_t *num, uint32_t *den) -{ - while (*num > 0xffffff || *den > 0xffffff) { - *num >>= 1; - *den >>= 1; - } -} - -static void -intel_dp_compute_m_n(int bytes_per_pixel, - int nlanes, - int pixel_clock, - int link_clock, - struct intel_dp_m_n *m_n) -{ - m_n->tu = 64; - m_n->gmch_m = pixel_clock * bytes_per_pixel; - m_n->gmch_n = link_clock * nlanes; - intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); - m_n->link_m = pixel_clock; - m_n->link_n = link_clock; - intel_reduce_ratio(&m_n->link_m, &m_n->link_n); -} - -void -intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int lane_count = 4; - struct intel_dp_m_n m_n; - - /* - * Find the lane count in the intel_output private - */ - list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - if (!connector->encoder || connector->encoder->crtc != crtc) - continue; - - if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) { - lane_count = dp_priv->lane_count; - break; - } - } - - /* - * Compute the GMCH and Link ratios. The '3' here is - * the number of bytes_per_pixel post-LUT, which we always - * set up for 8-bits of R/G/B, or 3 bytes total. - */ - intel_dp_compute_m_n(3, lane_count, - mode->clock, adjusted_mode->clock, &m_n); - - if (intel_crtc->pipe == 0) { - I915_WRITE(PIPEA_GMCH_DATA_M, - ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | - m_n.gmch_m); - I915_WRITE(PIPEA_GMCH_DATA_N, - m_n.gmch_n); - I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m); - I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n); - } else { - I915_WRITE(PIPEB_GMCH_DATA_M, - ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | - m_n.gmch_m); - I915_WRITE(PIPEB_GMCH_DATA_N, - m_n.gmch_n); - I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m); - I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); - } -} - -static void -intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - struct drm_crtc *crtc = intel_output->enc.crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - dp_priv->DP = (DP_LINK_TRAIN_OFF | - DP_VOLTAGE_0_4 | - DP_PRE_EMPHASIS_0 | - DP_SYNC_VS_HIGH | - DP_SYNC_HS_HIGH); - - switch (dp_priv->lane_count) { - case 1: - dp_priv->DP |= DP_PORT_WIDTH_1; - break; - case 2: - dp_priv->DP |= DP_PORT_WIDTH_2; - break; - case 4: - dp_priv->DP |= DP_PORT_WIDTH_4; - break; - } - if (dp_priv->has_audio) - dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE; - - memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); - dp_priv->link_configuration[0] = dp_priv->link_bw; - dp_priv->link_configuration[1] = dp_priv->lane_count; - - /* - * Check for DPCD version > 1.1, - * enable enahanced frame stuff in that case - */ - if (dp_priv->dpcd[0] >= 0x11) { - dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; - dp_priv->DP |= DP_ENHANCED_FRAMING; - } - - if (intel_crtc->pipe == 1) - dp_priv->DP |= DP_PIPEB_SELECT; -} - - -static void -intel_dp_dpms(struct drm_encoder *encoder, int mode) -{ - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dp_reg = I915_READ(dp_priv->output_reg); - - if (mode != DRM_MODE_DPMS_ON) { - if (dp_reg & DP_PORT_EN) - intel_dp_link_down(intel_output, dp_priv->DP); - } else { - if (!(dp_reg & DP_PORT_EN)) - intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); - } - dp_priv->dpms_mode = mode; -} - -/* - * Fetch AUX CH registers 0x202 - 0x207 which contain - * link status information - */ -static bool -intel_dp_get_link_status(struct intel_output *intel_output, - uint8_t link_status[DP_LINK_STATUS_SIZE]) -{ - int ret; - - ret = intel_dp_aux_native_read(intel_output, - DP_LANE0_1_STATUS, - link_status, DP_LINK_STATUS_SIZE); - if (ret != DP_LINK_STATUS_SIZE) - return false; - return true; -} - -static uint8_t -intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], - int r) -{ - return link_status[r - DP_LANE0_1_STATUS]; -} - -static void -intel_dp_save(struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - dp_priv->save_DP = I915_READ(dp_priv->output_reg); - intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET, - dp_priv->save_link_configuration, - sizeof (dp_priv->save_link_configuration)); -} - -static uint8_t -intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); - int s = ((lane & 1) ? - DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : - DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); - uint8_t l = intel_dp_link_status(link_status, i); - - return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; -} - -static uint8_t -intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); - int s = ((lane & 1) ? - DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : - DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); - uint8_t l = intel_dp_link_status(link_status, i); - - return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; -} - - -#if 0 -static char *voltage_names[] = { - "0.4V", "0.6V", "0.8V", "1.2V" -}; -static char *pre_emph_names[] = { - "0dB", "3.5dB", "6dB", "9.5dB" -}; -static char *link_train_names[] = { - "pattern 1", "pattern 2", "idle", "off" -}; -#endif - -/* - * These are source-specific values; current Intel hardware supports - * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB - */ -#define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 - -static uint8_t -intel_dp_pre_emphasis_max(uint8_t voltage_swing) -{ - switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { - case DP_TRAIN_VOLTAGE_SWING_400: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_600: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_800: - return DP_TRAIN_PRE_EMPHASIS_3_5; - case DP_TRAIN_VOLTAGE_SWING_1200: - default: - return DP_TRAIN_PRE_EMPHASIS_0; - } -} - -static void -intel_get_adjust_train(struct intel_output *intel_output, - uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane_count, - uint8_t train_set[4]) -{ - uint8_t v = 0; - uint8_t p = 0; - int lane; - - for (lane = 0; lane < lane_count; lane++) { - uint8_t this_v = intel_get_adjust_request_voltage(link_status, lane); - uint8_t this_p = intel_get_adjust_request_pre_emphasis(link_status, lane); - - if (this_v > v) - v = this_v; - if (this_p > p) - p = this_p; - } - - if (v >= I830_DP_VOLTAGE_MAX) - v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; - - if (p >= intel_dp_pre_emphasis_max(v)) - p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; - - for (lane = 0; lane < 4; lane++) - train_set[lane] = v | p; -} - -static uint32_t -intel_dp_signal_levels(uint8_t train_set, int lane_count) -{ - uint32_t signal_levels = 0; - - switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { - case DP_TRAIN_VOLTAGE_SWING_400: - default: - signal_levels |= DP_VOLTAGE_0_4; - break; - case DP_TRAIN_VOLTAGE_SWING_600: - signal_levels |= DP_VOLTAGE_0_6; - break; - case DP_TRAIN_VOLTAGE_SWING_800: - signal_levels |= DP_VOLTAGE_0_8; - break; - case DP_TRAIN_VOLTAGE_SWING_1200: - signal_levels |= DP_VOLTAGE_1_2; - break; - } - switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { - case DP_TRAIN_PRE_EMPHASIS_0: - default: - signal_levels |= DP_PRE_EMPHASIS_0; - break; - case DP_TRAIN_PRE_EMPHASIS_3_5: - signal_levels |= DP_PRE_EMPHASIS_3_5; - break; - case DP_TRAIN_PRE_EMPHASIS_6: - signal_levels |= DP_PRE_EMPHASIS_6; - break; - case DP_TRAIN_PRE_EMPHASIS_9_5: - signal_levels |= DP_PRE_EMPHASIS_9_5; - break; - } - return signal_levels; -} - -static uint8_t -intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int i = DP_LANE0_1_STATUS + (lane >> 1); - int s = (lane & 1) * 4; - uint8_t l = intel_dp_link_status(link_status, i); - - return (l >> s) & 0xf; -} - -/* Check for clock recovery is done on all channels */ -static bool -intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) -{ - int lane; - uint8_t lane_status; - - for (lane = 0; lane < lane_count; lane++) { - lane_status = intel_get_lane_status(link_status, lane); - if ((lane_status & DP_LANE_CR_DONE) == 0) - return false; - } - return true; -} - -/* Check to see if channel eq is done on all channels */ -#define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\ - DP_LANE_CHANNEL_EQ_DONE|\ - DP_LANE_SYMBOL_LOCKED) -static bool -intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) -{ - uint8_t lane_align; - uint8_t lane_status; - int lane; - - lane_align = intel_dp_link_status(link_status, - DP_LANE_ALIGN_STATUS_UPDATED); - if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) - return false; - for (lane = 0; lane < lane_count; lane++) { - lane_status = intel_get_lane_status(link_status, lane); - if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) - return false; - } - return true; -} - -static bool -intel_dp_set_link_train(struct intel_output *intel_output, - uint32_t dp_reg_value, - uint8_t dp_train_pat, - uint8_t train_set[4], - bool first) -{ - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - int ret; - - I915_WRITE(dp_priv->output_reg, dp_reg_value); - POSTING_READ(dp_priv->output_reg); - if (first) - intel_wait_for_vblank(dev); - - intel_dp_aux_native_write_1(intel_output, - DP_TRAINING_PATTERN_SET, - dp_train_pat); - - ret = intel_dp_aux_native_write(intel_output, - DP_TRAINING_LANE0_SET, train_set, 4); - if (ret != 4) - return false; - - return true; -} - -static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, - uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) -{ - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - uint8_t train_set[4]; - uint8_t link_status[DP_LINK_STATUS_SIZE]; - int i; - uint8_t voltage; - bool clock_recovery = false; - bool channel_eq = false; - bool first = true; - int tries; - - /* Write the link configuration data */ - intel_dp_aux_native_write(intel_output, 0x100, - link_configuration, DP_LINK_CONFIGURATION_SIZE); - - DP |= DP_PORT_EN; - DP &= ~DP_LINK_TRAIN_MASK; - memset(train_set, 0, 4); - voltage = 0xff; - tries = 0; - clock_recovery = false; - for (;;) { - /* Use train_set[0] to set the voltage and pre emphasis values */ - uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); - DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; - - if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1, - DP_TRAINING_PATTERN_1, train_set, first)) - break; - first = false; - /* Set training pattern 1 */ - - udelay(100); - if (!intel_dp_get_link_status(intel_output, link_status)) - break; - - if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { - clock_recovery = true; - break; - } - - /* Check to see if we've tried the max voltage */ - for (i = 0; i < dp_priv->lane_count; i++) - if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) - break; - if (i == dp_priv->lane_count) - break; - - /* Check to see if we've tried the same voltage 5 times */ - if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { - ++tries; - if (tries == 5) - break; - } else - tries = 0; - voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; - - /* Compute new train_set as requested by target */ - intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); - } - - /* channel equalization */ - tries = 0; - channel_eq = false; - for (;;) { - /* Use train_set[0] to set the voltage and pre emphasis values */ - uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); - DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; - - /* channel eq pattern */ - if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2, - DP_TRAINING_PATTERN_2, train_set, - false)) - break; - - udelay(400); - if (!intel_dp_get_link_status(intel_output, link_status)) - break; - - if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { - channel_eq = true; - break; - } - - /* Try 5 times */ - if (tries > 5) - break; - - /* Compute new train_set as requested by target */ - intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); - ++tries; - } - - I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); - POSTING_READ(dp_priv->output_reg); - intel_dp_aux_native_write_1(intel_output, - DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); -} - -static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) -{ - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); - POSTING_READ(dp_priv->output_reg); -} - -static void -intel_dp_restore(struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - if (dp_priv->save_DP & DP_PORT_EN) - intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration); - else - intel_dp_link_down(intel_output, dp_priv->save_DP); -} - -/* - * According to DP spec - * 5.1.2: - * 1. Read DPCD - * 2. Configure link according to Receiver Capabilities - * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 - * 4. Check link status on receipt of hot-plug interrupt - */ - -static void -intel_dp_check_link_status(struct intel_output *intel_output) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - uint8_t link_status[DP_LINK_STATUS_SIZE]; - - if (!intel_output->enc.crtc) - return; - - if (!intel_dp_get_link_status(intel_output, link_status)) { - intel_dp_link_down(intel_output, dp_priv->DP); - return; - } - - if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) - intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); -} - -/** - * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. - * - * \return true if DP port is connected. - * \return false if DP port is disconnected. - */ -static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - uint32_t temp, bit; - enum drm_connector_status status; - - dp_priv->has_audio = false; - - temp = I915_READ(PORT_HOTPLUG_EN); - - I915_WRITE(PORT_HOTPLUG_EN, - temp | - DPB_HOTPLUG_INT_EN | - DPC_HOTPLUG_INT_EN | - DPD_HOTPLUG_INT_EN); - - POSTING_READ(PORT_HOTPLUG_EN); - - switch (dp_priv->output_reg) { - case DP_B: - bit = DPB_HOTPLUG_INT_STATUS; - break; - case DP_C: - bit = DPC_HOTPLUG_INT_STATUS; - break; - case DP_D: - bit = DPD_HOTPLUG_INT_STATUS; - break; - default: - return connector_status_unknown; - } - - temp = I915_READ(PORT_HOTPLUG_STAT); - - if ((temp & bit) == 0) - return connector_status_disconnected; - - status = connector_status_disconnected; - if (intel_dp_aux_native_read(intel_output, - 0x000, dp_priv->dpcd, - sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) - { - if (dp_priv->dpcd[0] != 0) - status = connector_status_connected; - } - return status; -} - -static int intel_dp_get_modes(struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - - /* We should parse the EDID data and find out if it has an audio sink - */ - - return intel_ddc_get_modes(intel_output); -} - -static void -intel_dp_destroy (struct drm_connector *connector) -{ - struct intel_output *intel_output = to_intel_output(connector); - - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(intel_output); -} - -static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { - .dpms = intel_dp_dpms, - .mode_fixup = intel_dp_mode_fixup, - .prepare = intel_encoder_prepare, - .mode_set = intel_dp_mode_set, - .commit = intel_encoder_commit, -}; - -static const struct drm_connector_funcs intel_dp_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .save = intel_dp_save, - .restore = intel_dp_restore, - .detect = intel_dp_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = intel_dp_destroy, -}; - -static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { - .get_modes = intel_dp_get_modes, - .mode_valid = intel_dp_mode_valid, - .best_encoder = intel_best_encoder, -}; - -static void intel_dp_enc_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -static const struct drm_encoder_funcs intel_dp_enc_funcs = { - .destroy = intel_dp_enc_destroy, -}; - -void -intel_dp_hot_plug(struct intel_output *intel_output) -{ - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - - if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) - intel_dp_check_link_status(intel_output); -} - -void -intel_dp_init(struct drm_device *dev, int output_reg) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_connector *connector; - struct intel_output *intel_output; - struct intel_dp_priv *dp_priv; - - intel_output = kcalloc(sizeof(struct intel_output) + - sizeof(struct intel_dp_priv), 1, GFP_KERNEL); - if (!intel_output) - return; - - dp_priv = (struct intel_dp_priv *)(intel_output + 1); - - connector = &intel_output->base; - drm_connector_init(dev, connector, &intel_dp_connector_funcs, - DRM_MODE_CONNECTOR_DisplayPort); - drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); - - intel_output->type = INTEL_OUTPUT_DISPLAYPORT; - - connector->interlace_allowed = true; - connector->doublescan_allowed = 0; - - dp_priv->intel_output = intel_output; - dp_priv->output_reg = output_reg; - dp_priv->has_audio = false; - dp_priv->dpms_mode = DRM_MODE_DPMS_ON; - intel_output->dev_priv = dp_priv; - - drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs, - DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs); - - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); - drm_sysfs_connector_add(connector); - - /* Set up the DDC bus. */ - intel_dp_i2c_init(intel_output, - (output_reg == DP_B) ? "DPDDC-B" : - (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D"); - intel_output->ddc_bus = &dp_priv->adapter; - intel_output->hot_plug = intel_dp_hot_plug; - - /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written - * 0xd. Failure to do so will result in spurious interrupts being - * generated on the port when a cable is not attached. - */ - if (IS_G4X(dev) && !IS_GM45(dev)) { - u32 temp = I915_READ(PEG_BAND_GAP_DATA); - I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); - } -} diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.h b/trunk/drivers/gpu/drm/i915/intel_dp.h deleted file mode 100644 index 2b38054d3b6d..000000000000 --- a/trunk/drivers/gpu/drm/i915/intel_dp.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright © 2008 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _INTEL_DP_H_ -#define _INTEL_DP_H_ - -/* From the VESA DisplayPort spec */ - -#define AUX_NATIVE_WRITE 0x8 -#define AUX_NATIVE_READ 0x9 -#define AUX_I2C_WRITE 0x0 -#define AUX_I2C_READ 0x1 -#define AUX_I2C_STATUS 0x2 -#define AUX_I2C_MOT 0x4 - -#define AUX_NATIVE_REPLY_ACK (0x0 << 4) -#define AUX_NATIVE_REPLY_NACK (0x1 << 4) -#define AUX_NATIVE_REPLY_DEFER (0x2 << 4) -#define AUX_NATIVE_REPLY_MASK (0x3 << 4) - -#define AUX_I2C_REPLY_ACK (0x0 << 6) -#define AUX_I2C_REPLY_NACK (0x1 << 6) -#define AUX_I2C_REPLY_DEFER (0x2 << 6) -#define AUX_I2C_REPLY_MASK (0x3 << 6) - -/* AUX CH addresses */ -#define DP_LINK_BW_SET 0x100 -# define DP_LINK_BW_1_62 0x06 -# define DP_LINK_BW_2_7 0x0a - -#define DP_LANE_COUNT_SET 0x101 -# define DP_LANE_COUNT_MASK 0x0f -# define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) - -#define DP_TRAINING_PATTERN_SET 0x102 - -# define DP_TRAINING_PATTERN_DISABLE 0 -# define DP_TRAINING_PATTERN_1 1 -# define DP_TRAINING_PATTERN_2 2 -# define DP_TRAINING_PATTERN_MASK 0x3 - -# define DP_LINK_QUAL_PATTERN_DISABLE (0 << 2) -# define DP_LINK_QUAL_PATTERN_D10_2 (1 << 2) -# define DP_LINK_QUAL_PATTERN_ERROR_RATE (2 << 2) -# define DP_LINK_QUAL_PATTERN_PRBS7 (3 << 2) -# define DP_LINK_QUAL_PATTERN_MASK (3 << 2) - -# define DP_RECOVERED_CLOCK_OUT_EN (1 << 4) -# define DP_LINK_SCRAMBLING_DISABLE (1 << 5) - -# define DP_SYMBOL_ERROR_COUNT_BOTH (0 << 6) -# define DP_SYMBOL_ERROR_COUNT_DISPARITY (1 << 6) -# define DP_SYMBOL_ERROR_COUNT_SYMBOL (2 << 6) -# define DP_SYMBOL_ERROR_COUNT_MASK (3 << 6) - -#define DP_TRAINING_LANE0_SET 0x103 -#define DP_TRAINING_LANE1_SET 0x104 -#define DP_TRAINING_LANE2_SET 0x105 -#define DP_TRAINING_LANE3_SET 0x106 - -# define DP_TRAIN_VOLTAGE_SWING_MASK 0x3 -# define DP_TRAIN_VOLTAGE_SWING_SHIFT 0 -# define DP_TRAIN_MAX_SWING_REACHED (1 << 2) -# define DP_TRAIN_VOLTAGE_SWING_400 (0 << 0) -# define DP_TRAIN_VOLTAGE_SWING_600 (1 << 0) -# define DP_TRAIN_VOLTAGE_SWING_800 (2 << 0) -# define DP_TRAIN_VOLTAGE_SWING_1200 (3 << 0) - -# define DP_TRAIN_PRE_EMPHASIS_MASK (3 << 3) -# define DP_TRAIN_PRE_EMPHASIS_0 (0 << 3) -# define DP_TRAIN_PRE_EMPHASIS_3_5 (1 << 3) -# define DP_TRAIN_PRE_EMPHASIS_6 (2 << 3) -# define DP_TRAIN_PRE_EMPHASIS_9_5 (3 << 3) - -# define DP_TRAIN_PRE_EMPHASIS_SHIFT 3 -# define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED (1 << 5) - -#define DP_DOWNSPREAD_CTRL 0x107 -# define DP_SPREAD_AMP_0_5 (1 << 4) - -#define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 -# define DP_SET_ANSI_8B10B (1 << 0) - -#define DP_LANE0_1_STATUS 0x202 -#define DP_LANE2_3_STATUS 0x203 - -# define DP_LANE_CR_DONE (1 << 0) -# define DP_LANE_CHANNEL_EQ_DONE (1 << 1) -# define DP_LANE_SYMBOL_LOCKED (1 << 2) - -#define DP_LANE_ALIGN_STATUS_UPDATED 0x204 - -#define DP_INTERLANE_ALIGN_DONE (1 << 0) -#define DP_DOWNSTREAM_PORT_STATUS_CHANGED (1 << 6) -#define DP_LINK_STATUS_UPDATED (1 << 7) - -#define DP_SINK_STATUS 0x205 - -#define DP_RECEIVE_PORT_0_STATUS (1 << 0) -#define DP_RECEIVE_PORT_1_STATUS (1 << 1) - -#define DP_ADJUST_REQUEST_LANE0_1 0x206 -#define DP_ADJUST_REQUEST_LANE2_3 0x207 - -#define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 -#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 -#define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c -#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 -#define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 -#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 -#define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 -#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 - -struct i2c_algo_dp_aux_data { - bool running; - u16 address; - int (*aux_ch) (struct i2c_adapter *adapter, - uint8_t *send, int send_bytes, - uint8_t *recv, int recv_bytes); -}; - -int -i2c_dp_aux_add_bus(struct i2c_adapter *adapter); - -#endif /* _INTEL_DP_H_ */ diff --git a/trunk/drivers/gpu/drm/i915/intel_dp_i2c.c b/trunk/drivers/gpu/drm/i915/intel_dp_i2c.c deleted file mode 100644 index 4e60f14b1a6d..000000000000 --- a/trunk/drivers/gpu/drm/i915/intel_dp_i2c.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright © 2009 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "intel_dp.h" - -/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ - -#define MODE_I2C_START 1 -#define MODE_I2C_WRITE 2 -#define MODE_I2C_READ 4 -#define MODE_I2C_STOP 8 - -static int -i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, - uint8_t write_byte, uint8_t *read_byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - uint16_t address = algo_data->address; - uint8_t msg[5]; - uint8_t reply[2]; - int msg_bytes; - int reply_bytes; - int ret; - - /* Set up the command byte */ - if (mode & MODE_I2C_READ) - msg[0] = AUX_I2C_READ << 4; - else - msg[0] = AUX_I2C_WRITE << 4; - - if (!(mode & MODE_I2C_STOP)) - msg[0] |= AUX_I2C_MOT << 4; - - msg[1] = address >> 8; - msg[2] = address; - - switch (mode) { - case MODE_I2C_WRITE: - msg[3] = 0; - msg[4] = write_byte; - msg_bytes = 5; - reply_bytes = 1; - break; - case MODE_I2C_READ: - msg[3] = 0; - msg_bytes = 4; - reply_bytes = 2; - break; - default: - msg_bytes = 3; - reply_bytes = 1; - break; - } - - for (;;) { - ret = (*algo_data->aux_ch)(adapter, - msg, msg_bytes, - reply, reply_bytes); - if (ret < 0) { - printk(KERN_ERR "aux_ch failed %d\n", ret); - return ret; - } - switch (reply[0] & AUX_I2C_REPLY_MASK) { - case AUX_I2C_REPLY_ACK: - if (mode == MODE_I2C_READ) { - *read_byte = reply[1]; - } - return reply_bytes - 1; - case AUX_I2C_REPLY_NACK: - printk(KERN_ERR "aux_ch nack\n"); - return -EREMOTEIO; - case AUX_I2C_REPLY_DEFER: - printk(KERN_ERR "aux_ch defer\n"); - udelay(100); - break; - default: - printk(KERN_ERR "aux_ch invalid reply 0x%02x\n", reply[0]); - return -EREMOTEIO; - } - } -} - -/* - * I2C over AUX CH - */ - -/* - * Send the address. If the I2C link is running, this 'restarts' - * the connection with the new address, this is used for doing - * a write followed by a read (as needed for DDC) - */ -static int -i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int mode = MODE_I2C_START; - int ret; - - if (reading) - mode |= MODE_I2C_READ; - else - mode |= MODE_I2C_WRITE; - algo_data->address = address; - algo_data->running = true; - ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); - return ret; -} - -/* - * Stop the I2C transaction. This closes out the link, sending - * a bare address packet with the MOT bit turned off - */ -static void -i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int mode = MODE_I2C_STOP; - - if (reading) - mode |= MODE_I2C_READ; - else - mode |= MODE_I2C_WRITE; - if (algo_data->running) { - (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); - algo_data->running = false; - } -} - -/* - * Write a single byte to the current I2C address, the - * the I2C link must be running or this returns -EIO - */ -static int -i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - if (!algo_data->running) - return -EIO; - - ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL); - return ret; -} - -/* - * Read a single byte from the current I2C address, the - * I2C link must be running or this returns -EIO - */ -static int -i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - if (!algo_data->running) - return -EIO; - - ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret); - return ret; -} - -static int -i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - int ret = 0; - bool reading = false; - int m; - int b; - - for (m = 0; m < num; m++) { - u16 len = msgs[m].len; - u8 *buf = msgs[m].buf; - reading = (msgs[m].flags & I2C_M_RD) != 0; - ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading); - if (ret < 0) - break; - if (reading) { - for (b = 0; b < len; b++) { - ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]); - if (ret < 0) - break; - } - } else { - for (b = 0; b < len; b++) { - ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]); - if (ret < 0) - break; - } - } - if (ret < 0) - break; - } - if (ret >= 0) - ret = num; - i2c_algo_dp_aux_stop(adapter, reading); - printk(KERN_ERR "dp_aux_xfer return %d\n", ret); - return ret; -} - -static u32 -i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_BLOCK_PROC_CALL | - I2C_FUNC_10BIT_ADDR; -} - -static const struct i2c_algorithm i2c_dp_aux_algo = { - .master_xfer = i2c_algo_dp_aux_xfer, - .functionality = i2c_algo_dp_aux_functionality, -}; - -static void -i2c_dp_aux_reset_bus(struct i2c_adapter *adapter) -{ - (void) i2c_algo_dp_aux_address(adapter, 0, false); - (void) i2c_algo_dp_aux_stop(adapter, false); - -} - -static int -i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) -{ - adapter->algo = &i2c_dp_aux_algo; - adapter->retries = 3; - i2c_dp_aux_reset_bus(adapter); - return 0; -} - -int -i2c_dp_aux_add_bus(struct i2c_adapter *adapter) -{ - int error; - - error = i2c_dp_aux_prepare_bus(adapter); - if (error) - return error; - error = i2c_add_adapter(adapter); - return error; -} -EXPORT_SYMBOL(i2c_dp_aux_add_bus); diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 004541c935a8..cd4b9c5f715e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -54,7 +54,6 @@ #define INTEL_OUTPUT_LVDS 4 #define INTEL_OUTPUT_TVOUT 5 #define INTEL_OUTPUT_HDMI 6 -#define INTEL_OUTPUT_DISPLAYPORT 7 #define INTEL_DVO_CHIP_NONE 0 #define INTEL_DVO_CHIP_LVDS 1 @@ -66,6 +65,7 @@ struct intel_i2c_chan { u32 reg; /* GPIO reg */ struct i2c_adapter adapter; struct i2c_algo_bit_data algo; + u8 slave_addr; }; struct intel_framebuffer { @@ -79,12 +79,11 @@ struct intel_output { struct drm_encoder enc; int type; - struct i2c_adapter *i2c_bus; - struct i2c_adapter *ddc_bus; + struct intel_i2c_chan *i2c_bus; /* for control functions */ + struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */ bool load_detect_temp; bool needs_tv_clock; void *dev_priv; - void (*hot_plug)(struct intel_output *); }; struct intel_crtc { @@ -105,9 +104,9 @@ struct intel_crtc { #define enc_to_intel_output(x) container_of(x, struct intel_output, enc) #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) -struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, - const char *name); -void intel_i2c_destroy(struct i2c_adapter *adapter); +struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, + const char *name); +void intel_i2c_destroy(struct intel_i2c_chan *chan); int intel_ddc_get_modes(struct intel_output *intel_output); extern bool intel_ddc_probe(struct intel_output *intel_output); void intel_i2c_quirk_set(struct drm_device *dev, bool enable); @@ -117,10 +116,6 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device); extern void intel_dvo_init(struct drm_device *dev); extern void intel_tv_init(struct drm_device *dev); extern void intel_lvds_init(struct drm_device *dev); -extern void intel_dp_init(struct drm_device *dev, int dp_reg); -void -intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); extern void intel_crtc_load_lut(struct drm_crtc *crtc); extern void intel_encoder_prepare (struct drm_encoder *encoder); diff --git a/trunk/drivers/gpu/drm/i915/intel_dvo.c b/trunk/drivers/gpu/drm/i915/intel_dvo.c index 13bff20930e8..1ee3007d6ec0 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_dvo.c @@ -384,9 +384,10 @@ void intel_dvo_init(struct drm_device *dev) { struct intel_output *intel_output; struct intel_dvo_device *dvo; - struct i2c_adapter *i2cbus = NULL; + struct intel_i2c_chan *i2cbus = NULL; int ret = 0; int i; + int gpio_inited = 0; int encoder_type = DRM_MODE_ENCODER_NONE; intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) @@ -419,11 +420,14 @@ void intel_dvo_init(struct drm_device *dev) * It appears that everything is on GPIOE except for panels * on i830 laptops, which are on GPIOB (DVOA). */ - if (i2cbus != NULL) - intel_i2c_destroy(i2cbus); - if (!(i2cbus = intel_i2c_create(dev, gpio, - gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { - continue; + if (gpio_inited != gpio) { + if (i2cbus != NULL) + intel_i2c_destroy(i2cbus); + if (!(i2cbus = intel_i2c_create(dev, gpio, + gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { + continue; + } + gpio_inited = gpio; } if (dvo->dev_ops!= NULL) diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 9e30daae37dc..4ea2a651b92c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -31,7 +31,6 @@ #include "drmP.h" #include "drm.h" #include "drm_crtc.h" -#include "drm_edid.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" @@ -57,7 +56,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE | SDVO_VSYNC_ACTIVE_HIGH | - SDVO_HSYNC_ACTIVE_HIGH; + SDVO_HSYNC_ACTIVE_HIGH | + SDVO_NULL_PACKETS_DURING_VSYNC; if (hdmi_priv->has_hdmi_sink) sdvox |= SDVO_AUDIO_ENABLE; @@ -129,26 +129,20 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, return true; } -static enum drm_connector_status -intel_hdmi_edid_detect(struct drm_connector *connector) +static void +intel_hdmi_sink_detect(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; struct edid *edid = NULL; - enum drm_connector_status status = connector_status_disconnected; edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); - hdmi_priv->has_hdmi_sink = false; - if (edid) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) { - status = connector_status_connected; - hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); - } - intel_output->base.display_info.raw_edid = NULL; + &intel_output->ddc_bus->adapter); + if (edid != NULL) { + hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); kfree(edid); + intel_output->base.display_info.raw_edid = NULL; } - return status; } static enum drm_connector_status @@ -160,7 +154,11 @@ igdng_hdmi_detect(struct drm_connector *connector) /* FIXME hotplug detect */ hdmi_priv->has_hdmi_sink = false; - return intel_hdmi_edid_detect(connector); + intel_hdmi_sink_detect(connector); + if (hdmi_priv->has_hdmi_sink) + return connector_status_connected; + else + return connector_status_disconnected; } static enum drm_connector_status @@ -203,9 +201,10 @@ intel_hdmi_detect(struct drm_connector *connector) return connector_status_unknown; } - if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) - return intel_hdmi_edid_detect(connector); - else + if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) { + intel_hdmi_sink_detect(connector); + return connector_status_connected; + } else return connector_status_disconnected; } diff --git a/trunk/drivers/gpu/drm/i915/intel_i2c.c b/trunk/drivers/gpu/drm/i915/intel_i2c.c index 62b8bead7652..f7061f68d050 100644 --- a/trunk/drivers/gpu/drm/i915/intel_i2c.c +++ b/trunk/drivers/gpu/drm/i915/intel_i2c.c @@ -124,7 +124,6 @@ static void set_data(void *data, int state_high) * @output: driver specific output device * @reg: GPIO reg to use * @name: name for this bus - * @slave_addr: slave address (if fixed) * * Creates and registers a new i2c bus with the Linux i2c layer, for use * in output probing and control (e.g. DDC or SDVO control functions). @@ -140,8 +139,8 @@ static void set_data(void *data, int state_high) * %GPIOH * see PRM for details on how these different busses are used. */ -struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, - const char *name) +struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, + const char *name) { struct intel_i2c_chan *chan; @@ -175,7 +174,7 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, intel_i2c_quirk_set(dev, false); udelay(20); - return &chan->adapter; + return chan; out_free: kfree(chan); @@ -188,16 +187,11 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, * * Unregister the adapter from the i2c layer, then free the structure. */ -void intel_i2c_destroy(struct i2c_adapter *adapter) +void intel_i2c_destroy(struct intel_i2c_chan *chan) { - struct intel_i2c_chan *chan; - - if (!adapter) + if (!chan) return; - chan = container_of(adapter, - struct intel_i2c_chan, - adapter); i2c_del_adapter(&chan->adapter); kfree(chan); } diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 9564ca44a977..f073ed8432e8 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -39,21 +39,6 @@ #define I915_LVDS "i915_lvds" -/* - * the following four scaling options are defined. - * #define DRM_MODE_SCALE_NON_GPU 0 - * #define DRM_MODE_SCALE_FULLSCREEN 1 - * #define DRM_MODE_SCALE_NO_SCALE 2 - * #define DRM_MODE_SCALE_ASPECT 3 - */ - -/* Private structure for the integrated LVDS support */ -struct intel_lvds_priv { - int fitting_mode; - u32 pfit_control; - u32 pfit_pgm_ratios; -}; - /** * Sets the backlight level. * @@ -228,27 +213,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - /* - * float point operation is not supported . So the PANEL_RATIO_FACTOR - * is defined, which can avoid the float point computation when - * calculating the panel ratio. - */ -#define PANEL_RATIO_FACTOR 8192 struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct drm_encoder *tmp_encoder; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; - u32 pfit_control = 0, pfit_pgm_ratios = 0; - int left_border = 0, right_border = 0, top_border = 0; - int bottom_border = 0; - bool border = 0; - int panel_ratio, desired_ratio, vert_scale, horiz_scale; - int horiz_ratio, vert_ratio; - u32 hsync_width, vsync_width; - u32 hblank_width, vblank_width; - u32 hsync_pos, vsync_pos; /* Should never happen!! */ if (!IS_I965G(dev) && intel_crtc->pipe == 0) { @@ -264,9 +232,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, return false; } } - /* If we don't have a panel mode, there is nothing we can do */ - if (dev_priv->panel_fixed_mode == NULL) - return true; + /* * If we have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, @@ -290,243 +256,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); } - /* Make sure pre-965s set dither correctly */ - if (!IS_I965G(dev)) { - if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - } - - /* Native modes don't need fitting */ - if (adjusted_mode->hdisplay == mode->hdisplay && - adjusted_mode->vdisplay == mode->vdisplay) { - pfit_pgm_ratios = 0; - border = 0; - goto out; - } - - /* 965+ wants fuzzy fitting */ - if (IS_I965G(dev)) - pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | - PFIT_FILTER_FUZZY; - - hsync_width = adjusted_mode->crtc_hsync_end - - adjusted_mode->crtc_hsync_start; - vsync_width = adjusted_mode->crtc_vsync_end - - adjusted_mode->crtc_vsync_start; - hblank_width = adjusted_mode->crtc_hblank_end - - adjusted_mode->crtc_hblank_start; - vblank_width = adjusted_mode->crtc_vblank_end - - adjusted_mode->crtc_vblank_start; - /* - * Deal with panel fitting options. Figure out how to stretch the - * image based on its aspect ratio & the current panel fitting mode. - */ - panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR / - adjusted_mode->vdisplay; - desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR / - mode->vdisplay; - /* - * Enable automatic panel scaling for non-native modes so that they fill - * the screen. Should be enabled before the pipe is enabled, according - * to register description and PRM. - * Change the value here to see the borders for debugging - */ - I915_WRITE(BCLRPAT_A, 0); - I915_WRITE(BCLRPAT_B, 0); - - switch (lvds_priv->fitting_mode) { - case DRM_MODE_SCALE_NO_SCALE: - /* - * For centered modes, we have to calculate border widths & - * heights and modify the values programmed into the CRTC. - */ - left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2; - right_border = left_border; - if (mode->hdisplay & 1) - right_border++; - top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2; - bottom_border = top_border; - if (mode->vdisplay & 1) - bottom_border++; - /* Set active & border values */ - adjusted_mode->crtc_hdisplay = mode->hdisplay; - /* Keep the boder be even */ - if (right_border & 1) - right_border++; - /* use the border directly instead of border minuse one */ - adjusted_mode->crtc_hblank_start = mode->hdisplay + - right_border; - /* keep the blank width constant */ - adjusted_mode->crtc_hblank_end = - adjusted_mode->crtc_hblank_start + hblank_width; - /* get the hsync pos relative to hblank start */ - hsync_pos = (hblank_width - hsync_width) / 2; - /* keep the hsync pos be even */ - if (hsync_pos & 1) - hsync_pos++; - adjusted_mode->crtc_hsync_start = - adjusted_mode->crtc_hblank_start + hsync_pos; - /* keep the hsync width constant */ - adjusted_mode->crtc_hsync_end = - adjusted_mode->crtc_hsync_start + hsync_width; - adjusted_mode->crtc_vdisplay = mode->vdisplay; - /* use the border instead of border minus one */ - adjusted_mode->crtc_vblank_start = mode->vdisplay + - bottom_border; - /* keep the vblank width constant */ - adjusted_mode->crtc_vblank_end = - adjusted_mode->crtc_vblank_start + vblank_width; - /* get the vsync start postion relative to vblank start */ - vsync_pos = (vblank_width - vsync_width) / 2; - adjusted_mode->crtc_vsync_start = - adjusted_mode->crtc_vblank_start + vsync_pos; - /* keep the vsync width constant */ - adjusted_mode->crtc_vsync_end = - adjusted_mode->crtc_vblank_start + vsync_width; - border = 1; - break; - case DRM_MODE_SCALE_ASPECT: - /* Scale but preserve the spect ratio */ - pfit_control |= PFIT_ENABLE; - if (IS_I965G(dev)) { - /* 965+ is easy, it does everything in hw */ - if (panel_ratio > desired_ratio) - pfit_control |= PFIT_SCALING_PILLAR; - else if (panel_ratio < desired_ratio) - pfit_control |= PFIT_SCALING_LETTER; - else - pfit_control |= PFIT_SCALING_AUTO; - } else { - /* - * For earlier chips we have to calculate the scaling - * ratio by hand and program it into the - * PFIT_PGM_RATIO register - */ - u32 horiz_bits, vert_bits, bits = 12; - horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/ - adjusted_mode->hdisplay; - vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/ - adjusted_mode->vdisplay; - horiz_scale = adjusted_mode->hdisplay * - PANEL_RATIO_FACTOR / mode->hdisplay; - vert_scale = adjusted_mode->vdisplay * - PANEL_RATIO_FACTOR / mode->vdisplay; - - /* retain aspect ratio */ - if (panel_ratio > desired_ratio) { /* Pillar */ - u32 scaled_width; - scaled_width = mode->hdisplay * vert_scale / - PANEL_RATIO_FACTOR; - horiz_ratio = vert_ratio; - pfit_control |= (VERT_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - /* Pillar will have left/right borders */ - left_border = (adjusted_mode->hdisplay - - scaled_width) / 2; - right_border = left_border; - if (mode->hdisplay & 1) /* odd resolutions */ - right_border++; - /* keep the border be even */ - if (right_border & 1) - right_border++; - adjusted_mode->crtc_hdisplay = scaled_width; - /* use border instead of border minus one */ - adjusted_mode->crtc_hblank_start = - scaled_width + right_border; - /* keep the hblank width constant */ - adjusted_mode->crtc_hblank_end = - adjusted_mode->crtc_hblank_start + - hblank_width; - /* - * get the hsync start pos relative to - * hblank start - */ - hsync_pos = (hblank_width - hsync_width) / 2; - /* keep the hsync_pos be even */ - if (hsync_pos & 1) - hsync_pos++; - adjusted_mode->crtc_hsync_start = - adjusted_mode->crtc_hblank_start + - hsync_pos; - /* keept hsync width constant */ - adjusted_mode->crtc_hsync_end = - adjusted_mode->crtc_hsync_start + - hsync_width; - border = 1; - } else if (panel_ratio < desired_ratio) { /* letter */ - u32 scaled_height = mode->vdisplay * - horiz_scale / PANEL_RATIO_FACTOR; - vert_ratio = horiz_ratio; - pfit_control |= (HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - /* Letterbox will have top/bottom border */ - top_border = (adjusted_mode->vdisplay - - scaled_height) / 2; - bottom_border = top_border; - if (mode->vdisplay & 1) - bottom_border++; - adjusted_mode->crtc_vdisplay = scaled_height; - /* use border instead of border minus one */ - adjusted_mode->crtc_vblank_start = - scaled_height + bottom_border; - /* keep the vblank width constant */ - adjusted_mode->crtc_vblank_end = - adjusted_mode->crtc_vblank_start + - vblank_width; - /* - * get the vsync start pos relative to - * vblank start - */ - vsync_pos = (vblank_width - vsync_width) / 2; - adjusted_mode->crtc_vsync_start = - adjusted_mode->crtc_vblank_start + - vsync_pos; - /* keep the vsync width constant */ - adjusted_mode->crtc_vsync_end = - adjusted_mode->crtc_vsync_start + - vsync_width; - border = 1; - } else { - /* Aspects match, Let hw scale both directions */ - pfit_control |= (VERT_AUTO_SCALE | - HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - } - horiz_bits = (1 << bits) * horiz_ratio / - PANEL_RATIO_FACTOR; - vert_bits = (1 << bits) * vert_ratio / - PANEL_RATIO_FACTOR; - pfit_pgm_ratios = - ((vert_bits << PFIT_VERT_SCALE_SHIFT) & - PFIT_VERT_SCALE_MASK) | - ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) & - PFIT_HORIZ_SCALE_MASK); - } - break; - - case DRM_MODE_SCALE_FULLSCREEN: - /* - * Full scaling, even if it changes the aspect ratio. - * Fortunately this is all done for us in hw. - */ - pfit_control |= PFIT_ENABLE; - if (IS_I965G(dev)) - pfit_control |= PFIT_SCALING_AUTO; - else - pfit_control |= (VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - break; - default: - break; - } - -out: - lvds_priv->pfit_control = pfit_control; - lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; /* * XXX: It would be nice to support lower refresh rates on the * panels to reduce power consumption, and perhaps match the @@ -572,8 +301,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + u32 pfit_control; /* * The LVDS pin pair will already have been turned on in the @@ -590,8 +319,22 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, * screen. Should be enabled before the pipe is enabled, according to * register description and PRM. */ - I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); - I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); + if (mode->hdisplay != adjusted_mode->hdisplay || + mode->vdisplay != adjusted_mode->vdisplay) + pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | + HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | + HORIZ_INTERP_BILINEAR); + else + pfit_control = 0; + + if (!IS_I965G(dev)) { + if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + } + else + pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT; + + I915_WRITE(PFIT_CONTROL, pfit_control); } /** @@ -663,34 +406,6 @@ static int intel_lvds_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t value) { - struct drm_device *dev = connector->dev; - struct intel_output *intel_output = - to_intel_output(connector); - - if (property == dev->mode_config.scaling_mode_property && - connector->encoder) { - struct drm_crtc *crtc = connector->encoder->crtc; - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; - if (value == DRM_MODE_SCALE_NON_GPU) { - DRM_DEBUG_KMS(I915_LVDS, - "non_GPU property is unsupported\n"); - return 0; - } - if (lvds_priv->fitting_mode == value) { - /* the LVDS scaling property is not changed */ - return 0; - } - lvds_priv->fitting_mode = value; - if (crtc && crtc->enabled) { - /* - * If the CRTC is enabled, the display will be changed - * according to the new panel fitting mode. - */ - drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, crtc->fb); - } - } - return 0; } @@ -741,7 +456,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .callback = intel_no_lvds_dmi_callback, .ident = "Apple Mac Mini (Core series)", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple"), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), }, }, @@ -749,7 +464,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .callback = intel_no_lvds_dmi_callback, .ident = "Apple Mac Mini (Core 2 series)", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple"), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), }, }, @@ -803,7 +518,6 @@ void intel_lvds_init(struct drm_device *dev) struct drm_encoder *encoder; struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_crtc *crtc; - struct intel_lvds_priv *lvds_priv; u32 lvds; int pipe, gpio = GPIOC; @@ -817,8 +531,7 @@ void intel_lvds_init(struct drm_device *dev) gpio = PCH_GPIOC; } - intel_output = kzalloc(sizeof(struct intel_output) + - sizeof(struct intel_lvds_priv), GFP_KERNEL); + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) { return; } @@ -840,18 +553,7 @@ void intel_lvds_init(struct drm_device *dev) connector->interlace_allowed = false; connector->doublescan_allowed = false; - lvds_priv = (struct intel_lvds_priv *)(intel_output + 1); - intel_output->dev_priv = lvds_priv; - /* create the scaling mode property */ - drm_mode_create_scaling_mode_property(dev); - /* - * the initial panel fitting mode will be FULL_SCREEN. - */ - drm_connector_attach_property(&intel_output->base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; /* * LVDS discovery: * 1) check for EDID on DDC @@ -947,5 +649,5 @@ void intel_lvds_init(struct drm_device *dev) if (intel_output->ddc_bus) intel_i2c_destroy(intel_output->ddc_bus); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(connector); } diff --git a/trunk/drivers/gpu/drm/i915/intel_modes.c b/trunk/drivers/gpu/drm/i915/intel_modes.c index 67e2f4632a24..e0910fefce87 100644 --- a/trunk/drivers/gpu/drm/i915/intel_modes.c +++ b/trunk/drivers/gpu/drm/i915/intel_modes.c @@ -53,9 +53,10 @@ bool intel_ddc_probe(struct intel_output *intel_output) } }; - intel_i2c_quirk_set(intel_output->base.dev, true); - ret = i2c_transfer(intel_output->ddc_bus, msgs, 2); - intel_i2c_quirk_set(intel_output->base.dev, false); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); + ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); + if (ret == 2) return true; @@ -73,9 +74,10 @@ int intel_ddc_get_modes(struct intel_output *intel_output) struct edid *edid; int ret = 0; - intel_i2c_quirk_set(intel_output->base.dev, true); - edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); - intel_i2c_quirk_set(intel_output->base.dev, false); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); + edid = drm_get_edid(&intel_output->base, + &intel_output->ddc_bus->adapter); + intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); if (edid) { drm_mode_connector_update_edid_property(&intel_output->base, edid); diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index f03473779feb..9a00adb3a508 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -38,7 +38,8 @@ #undef SDVO_DEBUG #define I915_SDVO "i915_sdvo" struct intel_sdvo_priv { - u8 slave_addr; + struct intel_i2c_chan *i2c_bus; + int slaveaddr; /* Register for the SDVO device: SDVOB or SDVOC */ int output_device; @@ -145,13 +146,13 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, struct i2c_msg msgs[] = { { - .addr = sdvo_priv->slave_addr >> 1, + .addr = sdvo_priv->i2c_bus->slave_addr, .flags = 0, .len = 1, .buf = out_buf, }, { - .addr = sdvo_priv->slave_addr >> 1, + .addr = sdvo_priv->i2c_bus->slave_addr, .flags = I2C_M_RD, .len = 1, .buf = buf, @@ -161,7 +162,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, out_buf[0] = addr; out_buf[1] = 0; - if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) + if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2) { *ch = buf[0]; return true; @@ -174,11 +175,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, u8 ch) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; u8 out_buf[2]; struct i2c_msg msgs[] = { { - .addr = sdvo_priv->slave_addr >> 1, + .addr = intel_output->i2c_bus->slave_addr, .flags = 0, .len = 2, .buf = out_buf, @@ -188,7 +188,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, out_buf[0] = addr; out_buf[1] = ch; - if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) + if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1) { return true; } @@ -1369,8 +1369,9 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; struct edid *edid = NULL; + intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); + &intel_output->ddc_bus->adapter); if (edid != NULL) { sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); kfree(edid); @@ -1548,6 +1549,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; struct drm_i915_private *dev_priv = connector->dev->dev_private; /* @@ -1555,6 +1557,8 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) * Assume that the preferred modes are * arranged in priority order. */ + /* set the bus switch and get the modes */ + intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); intel_ddc_get_modes(intel_output); if (list_empty(&connector->probed_modes) == false) return; @@ -1705,7 +1709,7 @@ intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (to_intel_output(connector)->ddc_bus == &chan->adapter) { + if (to_intel_output(connector)->ddc_bus == chan) { intel_output = to_intel_output(connector); break; } @@ -1719,7 +1723,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, struct intel_output *intel_output; struct intel_sdvo_priv *sdvo_priv; struct i2c_algo_bit_data *algo_data; - const struct i2c_algorithm *algo; + struct i2c_algorithm *algo; algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; intel_output = @@ -1729,7 +1733,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, return -EINVAL; sdvo_priv = intel_output->dev_priv; - algo = intel_output->i2c_bus->algo; + algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo; intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); return algo->master_xfer(i2c_adap, msgs, num); @@ -1781,11 +1785,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) struct drm_connector *connector; struct intel_output *intel_output; struct intel_sdvo_priv *sdvo_priv; - + struct intel_i2c_chan *i2cbus = NULL; + struct intel_i2c_chan *ddcbus = NULL; int connector_type; u8 ch[0x40]; int i; - int encoder_type; + int encoder_type, output_id; + u8 slave_addr; intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); if (!intel_output) { @@ -1793,24 +1799,29 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) } sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); - sdvo_priv->output_device = output_device; - - intel_output->dev_priv = sdvo_priv; intel_output->type = INTEL_OUTPUT_SDVO; /* setup the DDC bus. */ if (output_device == SDVOB) - intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); + i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); else - intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); + i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); - if (!intel_output->i2c_bus) + if (!i2cbus) goto err_inteloutput; - sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); + slave_addr = intel_sdvo_get_slave_addr(dev, output_device); + sdvo_priv->i2c_bus = i2cbus; - /* Save the bit-banging i2c functionality for use by the DDC wrapper */ - intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; + if (output_device == SDVOB) { + output_id = 1; + } else { + output_id = 2; + } + sdvo_priv->i2c_bus->slave_addr = slave_addr >> 1; + sdvo_priv->output_device = output_device; + intel_output->i2c_bus = i2cbus; + intel_output->dev_priv = sdvo_priv; /* Read the regs to test if we can talk to the device */ for (i = 0; i < 0x40; i++) { @@ -1824,15 +1835,17 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) /* setup the DDC bus. */ if (output_device == SDVOB) - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); + ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); else - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); + ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); - if (intel_output->ddc_bus == NULL) + if (ddcbus == NULL) goto err_i2c; - /* Wrap with our custom algo which switches to DDC mode */ - intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; + intel_sdvo_i2c_bit_algo.functionality = + intel_output->i2c_bus->adapter.algo->functionality; + ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo; + intel_output->ddc_bus = ddcbus; /* In defaut case sdvo lvds is false */ sdvo_priv->is_lvds = false; @@ -1952,10 +1965,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) return true; err_i2c: - if (intel_output->ddc_bus != NULL) + if (ddcbus != NULL) intel_i2c_destroy(intel_output->ddc_bus); - if (intel_output->i2c_bus != NULL) - intel_i2c_destroy(intel_output->i2c_bus); + intel_i2c_destroy(intel_output->i2c_bus); err_inteloutput: kfree(intel_output); diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index a43c98e3f077..ea68992e4416 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -1383,31 +1383,34 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) /* * Detect TV by polling) */ - save_tv_dac = tv_dac; - tv_ctl = I915_READ(TV_CTL); - save_tv_ctl = tv_ctl; - tv_ctl &= ~TV_ENC_ENABLE; - tv_ctl &= ~TV_TEST_MODE_MASK; - tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; - tv_dac &= ~TVDAC_SENSE_MASK; - tv_dac &= ~DAC_A_MASK; - tv_dac &= ~DAC_B_MASK; - tv_dac &= ~DAC_C_MASK; - tv_dac |= (TVDAC_STATE_CHG_EN | - TVDAC_A_SENSE_CTL | - TVDAC_B_SENSE_CTL | - TVDAC_C_SENSE_CTL | - DAC_CTL_OVERRIDE | - DAC_A_0_7_V | - DAC_B_0_7_V | - DAC_C_0_7_V); - I915_WRITE(TV_CTL, tv_ctl); - I915_WRITE(TV_DAC, tv_dac); - intel_wait_for_vblank(dev); - tv_dac = I915_READ(TV_DAC); - I915_WRITE(TV_DAC, save_tv_dac); - I915_WRITE(TV_CTL, save_tv_ctl); - intel_wait_for_vblank(dev); + if (intel_output->load_detect_temp) { + /* TV not currently running, prod it with destructive detect */ + save_tv_dac = tv_dac; + tv_ctl = I915_READ(TV_CTL); + save_tv_ctl = tv_ctl; + tv_ctl &= ~TV_ENC_ENABLE; + tv_ctl &= ~TV_TEST_MODE_MASK; + tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; + tv_dac &= ~TVDAC_SENSE_MASK; + tv_dac &= ~DAC_A_MASK; + tv_dac &= ~DAC_B_MASK; + tv_dac &= ~DAC_C_MASK; + tv_dac |= (TVDAC_STATE_CHG_EN | + TVDAC_A_SENSE_CTL | + TVDAC_B_SENSE_CTL | + TVDAC_C_SENSE_CTL | + DAC_CTL_OVERRIDE | + DAC_A_0_7_V | + DAC_B_0_7_V | + DAC_C_0_7_V); + I915_WRITE(TV_CTL, tv_ctl); + I915_WRITE(TV_DAC, tv_dac); + intel_wait_for_vblank(dev); + tv_dac = I915_READ(TV_DAC); + I915_WRITE(TV_DAC, save_tv_dac); + I915_WRITE(TV_CTL, save_tv_ctl); + intel_wait_for_vblank(dev); + } /* * A B C * 0 1 1 Composite diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index f97563db4e59..f30aa7274a54 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -34,23 +34,6 @@ #include "radeon_asic.h" #include "atom.h" -/* - * Clear GPU surface registers. - */ -static void radeon_surface_init(struct radeon_device *rdev) -{ - /* FIXME: check this out */ - if (rdev->family < CHIP_R600) { - int i; - - for (i = 0; i < 8; i++) { - WREG32(RADEON_SURFACE0_INFO + - i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO), - 0); - } - } -} - /* * GPU scratch registers helpers function. */ @@ -513,8 +496,6 @@ int radeon_device_init(struct radeon_device *rdev, radeon_errata(rdev); /* Initialize scratch registers */ radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); /* TODO: disable VGA need to use VGA request */ /* BIOS*/ @@ -623,6 +604,9 @@ int radeon_device_init(struct radeon_device *rdev, if (r) { return r; } + if (rdev->fbdev_rfb && rdev->fbdev_rfb->obj) { + rdev->fbdev_robj = rdev->fbdev_rfb->obj->driver_private; + } if (!ret) { DRM_INFO("radeon: kernel modesetting successfully initialized.\n"); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 84ba69f48784..09c9fb9f6210 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -345,7 +345,7 @@ static void __exit radeon_exit(void) drm_exit(driver); } -module_init(radeon_init); +late_initcall(radeon_init); module_exit(radeon_exit); MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_fb.c b/trunk/drivers/gpu/drm/radeon/radeon_fb.c index 9e8f191eb64a..fa86d398945e 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_fb.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_fb.c @@ -478,16 +478,14 @@ int radeonfb_create(struct radeon_device *rdev, { struct fb_info *info; struct radeon_fb_device *rfbdev; - struct drm_framebuffer *fb = NULL; + struct drm_framebuffer *fb; struct radeon_framebuffer *rfb; struct drm_mode_fb_cmd mode_cmd; struct drm_gem_object *gobj = NULL; struct radeon_object *robj = NULL; struct device *device = &rdev->pdev->dev; int size, aligned_size, ret; - u64 fb_gpuaddr; void *fbptr = NULL; - unsigned long tmp; mode_cmd.width = surface_width; mode_cmd.height = surface_height; @@ -500,12 +498,11 @@ int radeonfb_create(struct radeon_device *rdev, aligned_size = ALIGN(size, PAGE_SIZE); ret = radeon_gem_object_create(rdev, aligned_size, 0, - RADEON_GEM_DOMAIN_VRAM, - false, ttm_bo_type_kernel, - false, &gobj); + RADEON_GEM_DOMAIN_VRAM, + false, ttm_bo_type_kernel, + false, &gobj); if (ret) { - printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", - surface_width, surface_height); + printk(KERN_ERR "failed to allocate framebuffer\n"); ret = -ENOMEM; goto out; } @@ -518,19 +515,12 @@ int radeonfb_create(struct radeon_device *rdev, ret = -ENOMEM; goto out_unref; } - ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr); - if (ret) { - printk(KERN_ERR "failed to pin framebuffer\n"); - ret = -ENOMEM; - goto out_unref; - } list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); rfb = to_radeon_framebuffer(fb); *rfb_p = rfb; rdev->fbdev_rfb = rfb; - rdev->fbdev_robj = robj; info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); if (info == NULL) { @@ -551,13 +541,13 @@ int radeonfb_create(struct radeon_device *rdev, info->fix.xpanstep = 1; /* doing it in hw */ info->fix.ypanstep = 1; /* doing it in hw */ info->fix.ywrapstep = 0; - info->fix.accel = FB_ACCEL_NONE; + info->fix.accel = FB_ACCEL_I830; info->fix.type_aux = 0; info->flags = FBINFO_DEFAULT; info->fbops = &radeonfb_ops; info->fix.line_length = fb->pitch; - tmp = fb_gpuaddr - rdev->mc.vram_location; - info->fix.smem_start = rdev->mc.aper_base + tmp; + info->screen_base = fbptr; + info->fix.smem_start = (unsigned long)fbptr; info->fix.smem_len = size; info->screen_base = fbptr; info->screen_size = size; @@ -572,8 +562,8 @@ int radeonfb_create(struct radeon_device *rdev, info->var.width = -1; info->var.xres = fb_width; info->var.yres = fb_height; - info->fix.mmio_start = 0; - info->fix.mmio_len = 0; + info->fix.mmio_start = pci_resource_start(rdev->pdev, 2); + info->fix.mmio_len = pci_resource_len(rdev->pdev, 2); info->pixmap.size = 64*1024; info->pixmap.buf_align = 8; info->pixmap.access_align = 32; @@ -654,7 +644,7 @@ int radeonfb_create(struct radeon_device *rdev, if (robj) { radeon_object_kunmap(robj); } - if (fb && ret) { + if (ret) { list_del(&fb->filp_head); drm_gem_object_unreference(gobj); drm_framebuffer_cleanup(fb); @@ -823,7 +813,6 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) robj = rfb->obj->driver_private; unregister_framebuffer(info); radeon_object_kunmap(robj); - radeon_object_unpin(robj); framebuffer_release(info); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.c b/trunk/drivers/gpu/drm/radeon/radeon_object.c index bac0d06c52ac..983e8df5e000 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.c @@ -223,6 +223,7 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, { uint32_t flags; uint32_t tmp; + void *fbptr; int r; flags = radeon_object_flags_from_domain(domain); @@ -241,6 +242,10 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, DRM_ERROR("radeon: failed to reserve object for pinning it.\n"); return r; } + if (robj->rdev->fbdev_robj == robj) { + mutex_lock(&robj->rdev->fbdev_info->lock); + radeon_object_kunmap(robj); + } tmp = robj->tobj.mem.placement; ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM); robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING; @@ -256,12 +261,23 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, DRM_ERROR("radeon: failed to pin object.\n"); } radeon_object_unreserve(robj); + if (robj->rdev->fbdev_robj == robj) { + if (!r) { + r = radeon_object_kmap(robj, &fbptr); + } + if (!r) { + robj->rdev->fbdev_info->screen_base = fbptr; + robj->rdev->fbdev_info->fix.smem_start = (unsigned long)fbptr; + } + mutex_unlock(&robj->rdev->fbdev_info->lock); + } return r; } void radeon_object_unpin(struct radeon_object *robj) { uint32_t flags; + void *fbptr; int r; spin_lock(&robj->tobj.lock); @@ -281,6 +297,10 @@ void radeon_object_unpin(struct radeon_object *robj) DRM_ERROR("radeon: failed to reserve object for unpinning it.\n"); return; } + if (robj->rdev->fbdev_robj == robj) { + mutex_lock(&robj->rdev->fbdev_info->lock); + radeon_object_kunmap(robj); + } flags = robj->tobj.mem.placement; robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT; r = ttm_buffer_object_validate(&robj->tobj, @@ -290,6 +310,16 @@ void radeon_object_unpin(struct radeon_object *robj) DRM_ERROR("radeon: failed to unpin buffer.\n"); } radeon_object_unreserve(robj); + if (robj->rdev->fbdev_robj == robj) { + if (!r) { + r = radeon_object_kmap(robj, &fbptr); + } + if (!r) { + robj->rdev->fbdev_info->screen_base = fbptr; + robj->rdev->fbdev_info->fix.smem_start = (unsigned long)fbptr; + } + mutex_unlock(&robj->rdev->fbdev_info->lock); + } } int radeon_object_wait(struct radeon_object *robj) diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c b/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c index bdec583901eb..517c84559633 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -34,6 +34,7 @@ #include #include #include +#include #include void ttm_bo_free_old_node(struct ttm_buffer_object *bo) diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c b/trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c index 40b75032ea47..27b146c54fbc 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/gpu/drm/ttm/ttm_tt.c b/trunk/drivers/gpu/drm/ttm/ttm_tt.c index 75dc8bd24592..0331fa74cd3f 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_tt.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_tt.c @@ -28,6 +28,7 @@ * Authors: Thomas Hellstrom */ +#include #include #include #include diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index 8206442fbabd..3c259ee7ddda 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -326,16 +326,6 @@ config I2C_DAVINCI devices such as DaVinci NIC. For details please see http://www.ti.com/davinci -config I2C_DESIGNWARE - tristate "Synopsys DesignWare" - depends on HAVE_CLK - help - If you say yes to this option, support will be included for the - Synopsys DesignWare I2C adapter. Only master mode is supported. - - This driver can also be built as a module. If so, the module - will be called i2c-designware. - config I2C_GPIO tristate "GPIO-based bitbanging I2C" depends on GENERIC_GPIO diff --git a/trunk/drivers/i2c/busses/Makefile b/trunk/drivers/i2c/busses/Makefile index e654263bfc01..edeabf003106 100644 --- a/trunk/drivers/i2c/busses/Makefile +++ b/trunk/drivers/i2c/busses/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o obj-$(CONFIG_I2C_CPM) += i2c-cpm.o obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o -obj-$(CONFIG_I2C_DESIGNWARE) += i2c-designware.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o diff --git a/trunk/drivers/i2c/busses/i2c-designware.c b/trunk/drivers/i2c/busses/i2c-designware.c deleted file mode 100644 index b444762e9b9f..000000000000 --- a/trunk/drivers/i2c/busses/i2c-designware.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Synopsys Designware I2C adapter driver (master only). - * - * Based on the TI DAVINCI I2C adapter driver. - * - * Copyright (C) 2006 Texas Instruments. - * Copyright (C) 2007 MontaVista Software Inc. - * Copyright (C) 2009 Provigent Ltd. - * - * ---------------------------------------------------------------------------- - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * ---------------------------------------------------------------------------- - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Registers offset - */ -#define DW_IC_CON 0x0 -#define DW_IC_TAR 0x4 -#define DW_IC_DATA_CMD 0x10 -#define DW_IC_SS_SCL_HCNT 0x14 -#define DW_IC_SS_SCL_LCNT 0x18 -#define DW_IC_FS_SCL_HCNT 0x1c -#define DW_IC_FS_SCL_LCNT 0x20 -#define DW_IC_INTR_STAT 0x2c -#define DW_IC_INTR_MASK 0x30 -#define DW_IC_CLR_INTR 0x40 -#define DW_IC_ENABLE 0x6c -#define DW_IC_STATUS 0x70 -#define DW_IC_TXFLR 0x74 -#define DW_IC_RXFLR 0x78 -#define DW_IC_COMP_PARAM_1 0xf4 -#define DW_IC_TX_ABRT_SOURCE 0x80 - -#define DW_IC_CON_MASTER 0x1 -#define DW_IC_CON_SPEED_STD 0x2 -#define DW_IC_CON_SPEED_FAST 0x4 -#define DW_IC_CON_10BITADDR_MASTER 0x10 -#define DW_IC_CON_RESTART_EN 0x20 -#define DW_IC_CON_SLAVE_DISABLE 0x40 - -#define DW_IC_INTR_TX_EMPTY 0x10 -#define DW_IC_INTR_TX_ABRT 0x40 -#define DW_IC_INTR_STOP_DET 0x200 - -#define DW_IC_STATUS_ACTIVITY 0x1 - -#define DW_IC_ERR_TX_ABRT 0x1 - -/* - * status codes - */ -#define STATUS_IDLE 0x0 -#define STATUS_WRITE_IN_PROGRESS 0x1 -#define STATUS_READ_IN_PROGRESS 0x2 - -#define TIMEOUT 20 /* ms */ - -/* - * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register - * - * only expected abort codes are listed here - * refer to the datasheet for the full list - */ -#define ABRT_7B_ADDR_NOACK 0 -#define ABRT_10ADDR1_NOACK 1 -#define ABRT_10ADDR2_NOACK 2 -#define ABRT_TXDATA_NOACK 3 -#define ABRT_GCALL_NOACK 4 -#define ABRT_GCALL_READ 5 -#define ABRT_SBYTE_ACKDET 7 -#define ABRT_SBYTE_NORSTRT 9 -#define ABRT_10B_RD_NORSTRT 10 -#define ARB_MASTER_DIS 11 -#define ARB_LOST 12 - -static char *abort_sources[] = { - [ABRT_7B_ADDR_NOACK] = - "slave address not acknowledged (7bit mode)", - [ABRT_10ADDR1_NOACK] = - "first address byte not acknowledged (10bit mode)", - [ABRT_10ADDR2_NOACK] = - "second address byte not acknowledged (10bit mode)", - [ABRT_TXDATA_NOACK] = - "data not acknowledged", - [ABRT_GCALL_NOACK] = - "no acknowledgement for a general call", - [ABRT_GCALL_READ] = - "read after general call", - [ABRT_SBYTE_ACKDET] = - "start byte acknowledged", - [ABRT_SBYTE_NORSTRT] = - "trying to send start byte when restart is disabled", - [ABRT_10B_RD_NORSTRT] = - "trying to read when restart is disabled (10bit mode)", - [ARB_MASTER_DIS] = - "trying to use disabled adapter", - [ARB_LOST] = - "lost arbitration", -}; - -/** - * struct dw_i2c_dev - private i2c-designware data - * @dev: driver model device node - * @base: IO registers pointer - * @cmd_complete: tx completion indicator - * @pump_msg: continue in progress transfers - * @lock: protect this struct and IO registers - * @clk: input reference clock - * @cmd_err: run time hadware error code - * @msgs: points to an array of messages currently being transfered - * @msgs_num: the number of elements in msgs - * @msg_write_idx: the element index of the current tx message in the msgs - * array - * @tx_buf_len: the length of the current tx buffer - * @tx_buf: the current tx buffer - * @msg_read_idx: the element index of the current rx message in the msgs - * array - * @rx_buf_len: the length of the current rx buffer - * @rx_buf: the current rx buffer - * @msg_err: error status of the current transfer - * @status: i2c master status, one of STATUS_* - * @abort_source: copy of the TX_ABRT_SOURCE register - * @irq: interrupt number for the i2c master - * @adapter: i2c subsystem adapter node - * @tx_fifo_depth: depth of the hardware tx fifo - * @rx_fifo_depth: depth of the hardware rx fifo - */ -struct dw_i2c_dev { - struct device *dev; - void __iomem *base; - struct completion cmd_complete; - struct tasklet_struct pump_msg; - struct mutex lock; - struct clk *clk; - int cmd_err; - struct i2c_msg *msgs; - int msgs_num; - int msg_write_idx; - u16 tx_buf_len; - u8 *tx_buf; - int msg_read_idx; - u16 rx_buf_len; - u8 *rx_buf; - int msg_err; - unsigned int status; - u16 abort_source; - int irq; - struct i2c_adapter adapter; - unsigned int tx_fifo_depth; - unsigned int rx_fifo_depth; -}; - -/** - * i2c_dw_init() - initialize the designware i2c master hardware - * @dev: device private data - * - * This functions configures and enables the I2C master. - * This function is called during I2C init function, and in case of timeout at - * run time. - */ -static void i2c_dw_init(struct dw_i2c_dev *dev) -{ - u32 input_clock_khz = clk_get_rate(dev->clk) / 1000; - u16 ic_con; - - /* Disable the adapter */ - writeb(0, dev->base + DW_IC_ENABLE); - - /* set standard and fast speed deviders for high/low periods */ - writew((input_clock_khz * 40 / 10000)+1, /* std speed high, 4us */ - dev->base + DW_IC_SS_SCL_HCNT); - writew((input_clock_khz * 47 / 10000)+1, /* std speed low, 4.7us */ - dev->base + DW_IC_SS_SCL_LCNT); - writew((input_clock_khz * 6 / 10000)+1, /* fast speed high, 0.6us */ - dev->base + DW_IC_FS_SCL_HCNT); - writew((input_clock_khz * 13 / 10000)+1, /* fast speed low, 1.3us */ - dev->base + DW_IC_FS_SCL_LCNT); - - /* configure the i2c master */ - ic_con = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | - DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; - writew(ic_con, dev->base + DW_IC_CON); -} - -/* - * Waiting for bus not busy - */ -static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) -{ - int timeout = TIMEOUT; - - while (readb(dev->base + DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { - if (timeout <= 0) { - dev_warn(dev->dev, "timeout waiting for bus ready\n"); - return -ETIMEDOUT; - } - timeout--; - mdelay(1); - } - - return 0; -} - -/* - * Initiate low level master read/write transaction. - * This function is called from i2c_dw_xfer when starting a transfer. - * This function is also called from dw_i2c_pump_msg to continue a transfer - * that is longer than the size of the TX FIFO. - */ -static void -i2c_dw_xfer_msg(struct i2c_adapter *adap) -{ - struct dw_i2c_dev *dev = i2c_get_adapdata(adap); - struct i2c_msg *msgs = dev->msgs; - int num = dev->msgs_num; - u16 ic_con, intr_mask; - int tx_limit = dev->tx_fifo_depth - readb(dev->base + DW_IC_TXFLR); - int rx_limit = dev->rx_fifo_depth - readb(dev->base + DW_IC_RXFLR); - u16 addr = msgs[dev->msg_write_idx].addr; - u16 buf_len = dev->tx_buf_len; - - if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { - /* Disable the adapter */ - writeb(0, dev->base + DW_IC_ENABLE); - - /* set the slave (target) address */ - writew(msgs[dev->msg_write_idx].addr, dev->base + DW_IC_TAR); - - /* if the slave address is ten bit address, enable 10BITADDR */ - ic_con = readw(dev->base + DW_IC_CON); - if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) - ic_con |= DW_IC_CON_10BITADDR_MASTER; - else - ic_con &= ~DW_IC_CON_10BITADDR_MASTER; - writew(ic_con, dev->base + DW_IC_CON); - - /* Enable the adapter */ - writeb(1, dev->base + DW_IC_ENABLE); - } - - for (; dev->msg_write_idx < num; dev->msg_write_idx++) { - /* if target address has changed, we need to - * reprogram the target address in the i2c - * adapter when we are done with this transfer - */ - if (msgs[dev->msg_write_idx].addr != addr) - return; - - if (msgs[dev->msg_write_idx].len == 0) { - dev_err(dev->dev, - "%s: invalid message length\n", __func__); - dev->msg_err = -EINVAL; - return; - } - - if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { - /* new i2c_msg */ - dev->tx_buf = msgs[dev->msg_write_idx].buf; - buf_len = msgs[dev->msg_write_idx].len; - } - - while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { - if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { - writew(0x100, dev->base + DW_IC_DATA_CMD); - rx_limit--; - } else - writew(*(dev->tx_buf++), - dev->base + DW_IC_DATA_CMD); - tx_limit--; buf_len--; - } - } - - intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT; - if (buf_len > 0) { /* more bytes to be written */ - intr_mask |= DW_IC_INTR_TX_EMPTY; - dev->status |= STATUS_WRITE_IN_PROGRESS; - } else - dev->status &= ~STATUS_WRITE_IN_PROGRESS; - writew(intr_mask, dev->base + DW_IC_INTR_MASK); - - dev->tx_buf_len = buf_len; -} - -static void -i2c_dw_read(struct i2c_adapter *adap) -{ - struct dw_i2c_dev *dev = i2c_get_adapdata(adap); - struct i2c_msg *msgs = dev->msgs; - int num = dev->msgs_num; - u16 addr = msgs[dev->msg_read_idx].addr; - int rx_valid = readw(dev->base + DW_IC_RXFLR); - - for (; dev->msg_read_idx < num; dev->msg_read_idx++) { - u16 len; - u8 *buf; - - if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) - continue; - - /* different i2c client, reprogram the i2c adapter */ - if (msgs[dev->msg_read_idx].addr != addr) - return; - - if (!(dev->status & STATUS_READ_IN_PROGRESS)) { - len = msgs[dev->msg_read_idx].len; - buf = msgs[dev->msg_read_idx].buf; - } else { - len = dev->rx_buf_len; - buf = dev->rx_buf; - } - - for (; len > 0 && rx_valid > 0; len--, rx_valid--) - *buf++ = readb(dev->base + DW_IC_DATA_CMD); - - if (len > 0) { - dev->status |= STATUS_READ_IN_PROGRESS; - dev->rx_buf_len = len; - dev->rx_buf = buf; - return; - } else - dev->status &= ~STATUS_READ_IN_PROGRESS; - } -} - -/* - * Prepare controller for a transaction and call i2c_dw_xfer_msg - */ -static int -i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) -{ - struct dw_i2c_dev *dev = i2c_get_adapdata(adap); - int ret; - - dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); - - mutex_lock(&dev->lock); - - INIT_COMPLETION(dev->cmd_complete); - dev->msgs = msgs; - dev->msgs_num = num; - dev->cmd_err = 0; - dev->msg_write_idx = 0; - dev->msg_read_idx = 0; - dev->msg_err = 0; - dev->status = STATUS_IDLE; - - ret = i2c_dw_wait_bus_not_busy(dev); - if (ret < 0) - goto done; - - /* start the transfers */ - i2c_dw_xfer_msg(adap); - - /* wait for tx to complete */ - ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ); - if (ret == 0) { - dev_err(dev->dev, "controller timed out\n"); - i2c_dw_init(dev); - ret = -ETIMEDOUT; - goto done; - } else if (ret < 0) - goto done; - - if (dev->msg_err) { - ret = dev->msg_err; - goto done; - } - - /* no error */ - if (likely(!dev->cmd_err)) { - /* read rx fifo, and disable the adapter */ - do { - i2c_dw_read(adap); - } while (dev->status & STATUS_READ_IN_PROGRESS); - writeb(0, dev->base + DW_IC_ENABLE); - ret = num; - goto done; - } - - /* We have an error */ - if (dev->cmd_err == DW_IC_ERR_TX_ABRT) { - unsigned long abort_source = dev->abort_source; - int i; - - for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) { - dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); - } - } - ret = -EIO; - -done: - mutex_unlock(&dev->lock); - - return ret; -} - -static u32 i2c_dw_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; -} - -static void dw_i2c_pump_msg(unsigned long data) -{ - struct dw_i2c_dev *dev = (struct dw_i2c_dev *) data; - u16 intr_mask; - - i2c_dw_read(&dev->adapter); - i2c_dw_xfer_msg(&dev->adapter); - - intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT; - if (dev->status & STATUS_WRITE_IN_PROGRESS) - intr_mask |= DW_IC_INTR_TX_EMPTY; - writew(intr_mask, dev->base + DW_IC_INTR_MASK); -} - -/* - * Interrupt service routine. This gets called whenever an I2C interrupt - * occurs. - */ -static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) -{ - struct dw_i2c_dev *dev = dev_id; - u16 stat; - - stat = readw(dev->base + DW_IC_INTR_STAT); - dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat); - if (stat & DW_IC_INTR_TX_ABRT) { - dev->abort_source = readw(dev->base + DW_IC_TX_ABRT_SOURCE); - dev->cmd_err |= DW_IC_ERR_TX_ABRT; - dev->status = STATUS_IDLE; - } else if (stat & DW_IC_INTR_TX_EMPTY) - tasklet_schedule(&dev->pump_msg); - - readb(dev->base + DW_IC_CLR_INTR); /* clear interrupts */ - writew(0, dev->base + DW_IC_INTR_MASK); /* disable interrupts */ - if (stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) - complete(&dev->cmd_complete); - - return IRQ_HANDLED; -} - -static struct i2c_algorithm i2c_dw_algo = { - .master_xfer = i2c_dw_xfer, - .functionality = i2c_dw_func, -}; - -static int __devinit dw_i2c_probe(struct platform_device *pdev) -{ - struct dw_i2c_dev *dev; - struct i2c_adapter *adap; - struct resource *mem, *irq, *ioarea; - int r; - - /* NOTE: driver uses the static register mapping */ - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - dev_err(&pdev->dev, "no mem resource?\n"); - return -EINVAL; - } - - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq) { - dev_err(&pdev->dev, "no irq resource?\n"); - return -EINVAL; - } - - ioarea = request_mem_region(mem->start, resource_size(mem), - pdev->name); - if (!ioarea) { - dev_err(&pdev->dev, "I2C region already claimed\n"); - return -EBUSY; - } - - dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL); - if (!dev) { - r = -ENOMEM; - goto err_release_region; - } - - init_completion(&dev->cmd_complete); - tasklet_init(&dev->pump_msg, dw_i2c_pump_msg, (unsigned long) dev); - mutex_init(&dev->lock); - dev->dev = get_device(&pdev->dev); - dev->irq = irq->start; - platform_set_drvdata(pdev, dev); - - dev->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(dev->clk)) { - r = -ENODEV; - goto err_free_mem; - } - clk_enable(dev->clk); - - dev->base = ioremap(mem->start, resource_size(mem)); - if (dev->base == NULL) { - dev_err(&pdev->dev, "failure mapping io resources\n"); - r = -EBUSY; - goto err_unuse_clocks; - } - { - u32 param1 = readl(dev->base + DW_IC_COMP_PARAM_1); - - dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1; - dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1; - } - i2c_dw_init(dev); - - writew(0, dev->base + DW_IC_INTR_MASK); /* disable IRQ */ - r = request_irq(dev->irq, i2c_dw_isr, 0, pdev->name, dev); - if (r) { - dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); - goto err_iounmap; - } - - adap = &dev->adapter; - i2c_set_adapdata(adap, dev); - adap->owner = THIS_MODULE; - adap->class = I2C_CLASS_HWMON; - strlcpy(adap->name, "Synopsys DesignWare I2C adapter", - sizeof(adap->name)); - adap->algo = &i2c_dw_algo; - adap->dev.parent = &pdev->dev; - - adap->nr = pdev->id; - r = i2c_add_numbered_adapter(adap); - if (r) { - dev_err(&pdev->dev, "failure adding adapter\n"); - goto err_free_irq; - } - - return 0; - -err_free_irq: - free_irq(dev->irq, dev); -err_iounmap: - iounmap(dev->base); -err_unuse_clocks: - clk_disable(dev->clk); - clk_put(dev->clk); - dev->clk = NULL; -err_free_mem: - platform_set_drvdata(pdev, NULL); - put_device(&pdev->dev); - kfree(dev); -err_release_region: - release_mem_region(mem->start, resource_size(mem)); - - return r; -} - -static int __devexit dw_i2c_remove(struct platform_device *pdev) -{ - struct dw_i2c_dev *dev = platform_get_drvdata(pdev); - struct resource *mem; - - platform_set_drvdata(pdev, NULL); - i2c_del_adapter(&dev->adapter); - put_device(&pdev->dev); - - clk_disable(dev->clk); - clk_put(dev->clk); - dev->clk = NULL; - - writeb(0, dev->base + DW_IC_ENABLE); - free_irq(dev->irq, dev); - kfree(dev); - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, resource_size(mem)); - return 0; -} - -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:i2c_designware"); - -static struct platform_driver dw_i2c_driver = { - .remove = __devexit_p(dw_i2c_remove), - .driver = { - .name = "i2c_designware", - .owner = THIS_MODULE, - }, -}; - -static int __init dw_i2c_init_driver(void) -{ - return platform_driver_probe(&dw_i2c_driver, dw_i2c_probe); -} -module_init(dw_i2c_init_driver); - -static void __exit dw_i2c_exit_driver(void) -{ - platform_driver_unregister(&dw_i2c_driver); -} -module_exit(dw_i2c_exit_driver); - -MODULE_AUTHOR("Baruch Siach "); -MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/ide/cmd64x.c b/trunk/drivers/ide/cmd64x.c index 680e5975217f..03c86209446f 100644 --- a/trunk/drivers/ide/cmd64x.c +++ b/trunk/drivers/ide/cmd64x.c @@ -389,7 +389,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { .init_chipset = init_chipset_cmd64x, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .port_ops = &cmd648_port_ops, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH, + .host_flags = IDE_HFLAG_SERIALIZE | + IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA2, diff --git a/trunk/drivers/ide/cs5520.c b/trunk/drivers/ide/cs5520.c index 09f98ed0731f..bd066bb9d611 100644 --- a/trunk/drivers/ide/cs5520.c +++ b/trunk/drivers/ide/cs5520.c @@ -135,7 +135,6 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); hw[0].irq = 14; - hw[1].irq = 15; return ide_host_add(d, hws, 2, NULL); } diff --git a/trunk/drivers/ide/ide-acpi.c b/trunk/drivers/ide/ide-acpi.c index c509c9916464..77f79d26b264 100644 --- a/trunk/drivers/ide/ide-acpi.c +++ b/trunk/drivers/ide/ide-acpi.c @@ -92,11 +92,6 @@ int ide_acpi_init(void) return 0; } -bool ide_port_acpi(ide_hwif_t *hwif) -{ - return ide_noacpi == 0 && hwif->acpidata; -} - /** * ide_get_dev_handle - finds acpi_handle and PCI device.function * @dev: device to locate @@ -357,6 +352,9 @@ int ide_acpi_exec_tfs(ide_drive_t *drive) unsigned long gtf_address; unsigned long obj_loc; + if (ide_noacpi) + return 0; + DEBPRINT("call get_GTF, drive=%s port=%d\n", drive->name, drive->dn); ret = do_drive_get_GTF(drive, >f_length, >f_address, &obj_loc); @@ -391,6 +389,16 @@ void ide_acpi_get_timing(ide_hwif_t *hwif) struct acpi_buffer output; union acpi_object *out_obj; + if (ide_noacpi) + return; + + DEBPRINT("ENTER:\n"); + + if (!hwif->acpidata) { + DEBPRINT("no ACPI data for %s\n", hwif->name); + return; + } + /* Setting up output buffer for _GTM */ output.length = ACPI_ALLOCATE_BUFFER; output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ @@ -471,6 +479,16 @@ void ide_acpi_push_timing(ide_hwif_t *hwif) struct ide_acpi_drive_link *master = &hwif->acpidata->master; struct ide_acpi_drive_link *slave = &hwif->acpidata->slave; + if (ide_noacpi) + return; + + DEBPRINT("ENTER:\n"); + + if (!hwif->acpidata) { + DEBPRINT("no ACPI data for %s\n", hwif->name); + return; + } + /* Give the GTM buffer + drive Identify data to the channel via the * _STM method: */ /* setup input parameters buffer for _STM */ @@ -509,11 +527,16 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) ide_drive_t *drive; int i; - if (ide_noacpi_psx) + if (ide_noacpi || ide_noacpi_psx) return; DEBPRINT("ENTER:\n"); + if (!hwif->acpidata) { + DEBPRINT("no ACPI data for %s\n", hwif->name); + return; + } + /* channel first and then drives for power on and verse versa for power off */ if (on) acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); @@ -593,7 +616,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) drive->name, err); } - if (ide_noacpi || ide_acpionboot == 0) { + if (!ide_acpionboot) { DEBPRINT("ACPI methods disabled on boot\n"); return; } diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index 6a9a769bffc1..4a19686fcfe9 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -592,19 +592,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) } } else if (!blk_pc_request(rq)) { ide_cd_request_sense_fixup(drive, cmd); - + /* complain if we still have data left to transfer */ uptodate = cmd->nleft ? 0 : 1; - - /* - * suck out the remaining bytes from the drive in an - * attempt to complete the data xfer. (see BZ#13399) - */ - if (!(stat & ATA_ERR) && !uptodate && thislen) { - ide_pio_bytes(drive, cmd, write, thislen); - uptodate = cmd->nleft ? 0 : 1; - } - - if (!uptodate) + if (uptodate == 0) rq->cmd_flags |= REQ_FAILED; } goto out_end; @@ -886,12 +876,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, return stat; /* - * Sanity check the given block size, in so far as making - * sure the sectors_per_frame we give to the caller won't - * end up being bogus. + * Sanity check the given block size */ blocklen = be32_to_cpu(capbuf.blocklen); - blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS; switch (blocklen) { case 512: case 1024: @@ -899,9 +886,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, case 4096: break; default: - printk_once(KERN_ERR PFX "%s: weird block size %u; " - "setting default block size to 2048\n", + printk(KERN_ERR PFX "%s: weird block size %u\n", drive->name, blocklen); + printk(KERN_ERR PFX "%s: default to 2kb block size\n", + drive->name); blocklen = 2048; break; } diff --git a/trunk/drivers/ide/ide-devsets.c b/trunk/drivers/ide/ide-devsets.c index 1099bf7cf968..5bf958e5b1d5 100644 --- a/trunk/drivers/ide/ide-devsets.c +++ b/trunk/drivers/ide/ide-devsets.c @@ -183,6 +183,6 @@ ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq) err = setfunc(drive, *(int *)&rq->cmd[1]); if (err) rq->errors = err; - ide_complete_rq(drive, err, blk_rq_bytes(rq)); + ide_complete_rq(drive, err, ide_rq_bytes(rq)); return ide_stopped; } diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index ee58c88dee5a..219e6fb78dc6 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -361,6 +361,9 @@ static int ide_tune_dma(ide_drive_t *drive) if (__ide_dma_bad_drive(drive)) return 0; + if (ide_id_dma_bug(drive)) + return 0; + if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) return config_drive_for_dma(drive); @@ -391,6 +394,24 @@ static int ide_dma_check(ide_drive_t *drive) return -1; } +int ide_id_dma_bug(ide_drive_t *drive) +{ + u16 *id = drive->id; + + if (id[ATA_ID_FIELD_VALID] & 4) { + if ((id[ATA_ID_UDMA_MODES] >> 8) && + (id[ATA_ID_MWDMA_MODES] >> 8)) + goto err_out; + } else if ((id[ATA_ID_MWDMA_MODES] >> 8) && + (id[ATA_ID_SWDMA_MODES] >> 8)) + goto err_out; + + return 0; +err_out: + printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name); + return 1; +} + int ide_set_dma(ide_drive_t *drive) { int rc; diff --git a/trunk/drivers/ide/ide-eh.c b/trunk/drivers/ide/ide-eh.c index e9abf2c3c335..2b9141979613 100644 --- a/trunk/drivers/ide/ide-eh.c +++ b/trunk/drivers/ide/ide-eh.c @@ -149,7 +149,7 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) { if (err <= 0 && rq->errors == 0) rq->errors = -EIO; - ide_complete_rq(drive, err ? err : 0, blk_rq_bytes(rq)); + ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq)); } } diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index fefbdfc8db06..8b3f204f7d73 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -293,7 +293,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, drive->failed_pc = NULL; if (blk_fs_request(rq) == 0 && rq->errors == 0) rq->errors = -EIO; - ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); + ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); return ide_stopped; } diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index d5f3c77beadd..1059f809b809 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -112,6 +112,16 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) } } +/* obsolete, blk_rq_bytes() should be used instead */ +unsigned int ide_rq_bytes(struct request *rq) +{ + if (blk_pc_request(rq)) + return blk_rq_bytes(rq); + else + return blk_rq_cur_sectors(rq) << 9; +} +EXPORT_SYMBOL_GPL(ide_rq_bytes); + int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes) { ide_hwif_t *hwif = drive->hwif; @@ -142,14 +152,14 @@ void ide_kill_rq(ide_drive_t *drive, struct request *rq) if ((media == ide_floppy || media == ide_tape) && drv_req) { rq->errors = 0; + ide_complete_rq(drive, 0, blk_rq_bytes(rq)); } else { if (media == ide_tape) rq->errors = IDE_DRV_ERROR_GENERAL; else if (blk_fs_request(rq) == 0 && rq->errors == 0) rq->errors = -EIO; + ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); } - - ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); } static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) @@ -466,14 +476,10 @@ void do_ide_request(struct request_queue *q) if (!ide_lock_port(hwif)) { ide_hwif_t *prev_port; + + WARN_ON_ONCE(hwif->rq); repeat: prev_port = hwif->host->cur_port; - - if (drive->dev_flags & IDE_DFLAG_BLOCKED) - rq = hwif->rq; - else - WARN_ON_ONCE(hwif->rq); - if (drive->dev_flags & IDE_DFLAG_SLEEPING && time_after(drive->sleep, jiffies)) { ide_unlock_port(hwif); @@ -500,29 +506,43 @@ void do_ide_request(struct request_queue *q) hwif->cur_dev = drive; drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); - if (rq == NULL) { - spin_unlock_irq(&hwif->lock); - spin_lock_irq(q->queue_lock); - /* - * we know that the queue isn't empty, but this can - * happen if ->prep_rq_fn() decides to kill a request - */ + spin_unlock_irq(&hwif->lock); + spin_lock_irq(q->queue_lock); + /* + * we know that the queue isn't empty, but this can happen + * if the q->prep_rq_fn() decides to kill a request + */ + if (!rq) rq = blk_fetch_request(drive->queue); - spin_unlock_irq(q->queue_lock); - spin_lock_irq(&hwif->lock); - if (rq == NULL) { - ide_unlock_port(hwif); - goto out; - } + spin_unlock_irq(q->queue_lock); + spin_lock_irq(&hwif->lock); + + if (!rq) { + ide_unlock_port(hwif); + goto out; } /* * Sanity: don't accept a request that isn't a PM request - * if we are currently power managed. + * if we are currently power managed. This is very important as + * blk_stop_queue() doesn't prevent the blk_fetch_request() + * above to return us whatever is in the queue. Since we call + * ide_do_request() ourselves, we end up taking requests while + * the queue is blocked... + * + * We let requests forced at head of queue with ide-preempt + * though. I hope that doesn't happen too much, hopefully not + * unless the subdriver triggers such a thing in its own PM + * state machine. */ - BUG_ON((drive->dev_flags & IDE_DFLAG_BLOCKED) && - blk_pm_request(rq) == 0); + if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && + blk_pm_request(rq) == 0 && + (rq->cmd_flags & REQ_PREEMPT) == 0) { + /* there should be no pending command at this point */ + ide_unlock_port(hwif); + goto plug_device; + } hwif->rq = rq; diff --git a/trunk/drivers/ide/ide-ioctls.c b/trunk/drivers/ide/ide-ioctls.c index e246d3d3fbcc..82f252c3ee6e 100644 --- a/trunk/drivers/ide/ide-ioctls.c +++ b/trunk/drivers/ide/ide-ioctls.c @@ -64,8 +64,7 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd, goto out; } - /* ata_id_to_hd_driveid() relies on 'id' to be fully allocated. */ - id = kmalloc(ATA_ID_WORDS * 2, GFP_KERNEL); + id = kmalloc(size, GFP_KERNEL); if (id == NULL) { rc = -ENOMEM; goto out; diff --git a/trunk/drivers/ide/ide-iops.c b/trunk/drivers/ide/ide-iops.c index 2892b242bbe1..fa047150a1c6 100644 --- a/trunk/drivers/ide/ide-iops.c +++ b/trunk/drivers/ide/ide-iops.c @@ -210,7 +210,6 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list); */ static const struct drive_list_entry ivb_list[] = { { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, - { "QUANTUM FIREBALLlct20 30" , "APL.0900" }, { "TSSTcorp CDDVDW SH-S202J" , "SB00" }, { "TSSTcorp CDDVDW SH-S202J" , "SB01" }, { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, @@ -330,6 +329,9 @@ int ide_driveid_update(ide_drive_t *drive) kfree(id); + if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive)) + ide_dma_off(drive); + return 1; out_err: if (rc == 2) diff --git a/trunk/drivers/ide/ide-pm.c b/trunk/drivers/ide/ide-pm.c index ad7be2669dcb..c14ca144cffe 100644 --- a/trunk/drivers/ide/ide-pm.c +++ b/trunk/drivers/ide/ide-pm.c @@ -10,11 +10,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) struct request_pm_state rqpm; int ret; - if (ide_port_acpi(hwif)) { - /* call ACPI _GTM only once */ - if ((drive->dn & 1) == 0 || pair == NULL) - ide_acpi_get_timing(hwif); - } + /* call ACPI _GTM only once */ + if ((drive->dn & 1) == 0 || pair == NULL) + ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); @@ -28,11 +26,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ret = blk_execute_rq(drive->queue, NULL, rq, 0); blk_put_request(rq); - if (ret == 0 && ide_port_acpi(hwif)) { - /* call ACPI _PS3 only after both devices are suspended */ - if ((drive->dn & 1) || pair == NULL) - ide_acpi_set_state(hwif, 0); - } + /* call ACPI _PS3 only after both devices are suspended */ + if (ret == 0 && ((drive->dn & 1) || pair == NULL)) + ide_acpi_set_state(hwif, 0); return ret; } @@ -46,16 +42,14 @@ int generic_ide_resume(struct device *dev) struct request_pm_state rqpm; int err; - if (ide_port_acpi(hwif)) { - /* call ACPI _PS0 / _STM only once */ - if ((drive->dn & 1) == 0 || pair == NULL) { - ide_acpi_set_state(hwif, 1); - ide_acpi_push_timing(hwif); - } - - ide_acpi_exec_tfs(drive); + /* call ACPI _PS0 / _STM only once */ + if ((drive->dn & 1) == 0 || pair == NULL) { + ide_acpi_set_state(hwif, 1); + ide_acpi_push_timing(hwif); } + ide_acpi_exec_tfs(drive); + memset(&rqpm, 0, sizeof(rqpm)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_RESUME; diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 1bb106f6221a..51af4eea0d36 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -818,24 +818,6 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) return j; } -static void ide_host_enable_irqs(struct ide_host *host) -{ - ide_hwif_t *hwif; - int i; - - ide_host_for_each_port(i, hwif, host) { - if (hwif == NULL) - continue; - - /* clear any pending IRQs */ - hwif->tp_ops->read_status(hwif); - - /* unmask IRQs */ - if (hwif->io_ports.ctl_addr) - hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); - } -} - /* * This routine sets up the IRQ for an IDE interface. */ @@ -849,6 +831,9 @@ static int init_irq (ide_hwif_t *hwif) if (irq_handler == NULL) irq_handler = ide_intr; + if (io_ports->ctl_addr) + hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); + if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) goto out_up; @@ -1419,8 +1404,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, ide_port_tune_devices(hwif); } - ide_host_enable_irqs(host); - ide_host_for_each_port(i, hwif, host) { if (hwif == NULL) continue; diff --git a/trunk/drivers/infiniband/core/addr.c b/trunk/drivers/infiniband/core/addr.c index 5be1bd4fc7ed..ce511d8748ce 100644 --- a/trunk/drivers/infiniband/core/addr.c +++ b/trunk/drivers/infiniband/core/addr.c @@ -514,7 +514,7 @@ static struct notifier_block nb = { .notifier_call = netevent_callback }; -static int __init addr_init(void) +static int addr_init(void) { addr_wq = create_singlethread_workqueue("ib_addr"); if (!addr_wq) @@ -524,7 +524,7 @@ static int __init addr_init(void) return 0; } -static void __exit addr_cleanup(void) +static void addr_cleanup(void) { unregister_netevent_notifier(&nb); destroy_workqueue(addr_wq); diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 075317884b53..851de83ff455 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -2960,7 +2960,7 @@ static void cma_remove_one(struct ib_device *device) kfree(cma_dev); } -static int __init cma_init(void) +static int cma_init(void) { int ret, low, high, remaining; @@ -2990,7 +2990,7 @@ static int __init cma_init(void) return ret; } -static void __exit cma_cleanup(void) +static void cma_cleanup(void) { ib_unregister_client(&cma_client); unregister_netdevice_notifier(&cma_nb); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_hca.c b/trunk/drivers/infiniband/hw/ehca/ehca_hca.c index 8b92f85d4dd0..9209c5332dfe 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_hca.c @@ -319,7 +319,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, ib_device); struct hipz_query_port *rblock; - if (index < 0 || index > 255) { + if (index > 255) { ehca_err(&shca->ib_device, "Invalid index: %x.", index); return -EINVAL; } diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_main.c b/trunk/drivers/infiniband/hw/ehca/ehca_main.c index fab18a2c74a8..ce4e6eff4792 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_main.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_main.c @@ -52,7 +52,7 @@ #include "ehca_tools.h" #include "hcp_if.h" -#define HCAD_VERSION "0028" +#define HCAD_VERSION "0027" MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Christoph Raisch "); @@ -506,7 +506,6 @@ static int ehca_init_device(struct ehca_shca *shca) shca->ib_device.detach_mcast = ehca_detach_mcast; shca->ib_device.process_mad = ehca_process_mad; shca->ib_device.mmap = ehca_mmap; - shca->ib_device.dma_ops = &ehca_dma_mapping_ops; if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) { shca->ib_device.uverbs_cmd_mask |= @@ -1029,23 +1028,17 @@ static int __init ehca_module_init(void) goto module_init1; } - ret = ehca_create_busmap(); - if (ret) { - ehca_gen_err("Cannot create busmap."); - goto module_init2; - } - ret = ibmebus_register_driver(&ehca_driver); if (ret) { ehca_gen_err("Cannot register eHCA device driver"); ret = -EINVAL; - goto module_init3; + goto module_init2; } ret = register_memory_notifier(&ehca_mem_nb); if (ret) { ehca_gen_err("Failed registering memory add/remove notifier"); - goto module_init4; + goto module_init3; } if (ehca_poll_all_eqs != 1) { @@ -1060,11 +1053,8 @@ static int __init ehca_module_init(void) return 0; -module_init4: - ibmebus_unregister_driver(&ehca_driver); - module_init3: - ehca_destroy_busmap(); + ibmebus_unregister_driver(&ehca_driver); module_init2: ehca_destroy_slab_caches(); @@ -1083,8 +1073,6 @@ static void __exit ehca_module_exit(void) unregister_memory_notifier(&ehca_mem_nb); - ehca_destroy_busmap(); - ehca_destroy_slab_caches(); ehca_destroy_comp_pool(); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c index 7663a2a9f130..72f83f7df614 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -53,38 +53,6 @@ /* max number of rpages (per hcall register_rpages) */ #define MAX_RPAGES 512 -/* DMEM toleration management */ -#define EHCA_SECTSHIFT SECTION_SIZE_BITS -#define EHCA_SECTSIZE (1UL << EHCA_SECTSHIFT) -#define EHCA_HUGEPAGESHIFT 34 -#define EHCA_HUGEPAGE_SIZE (1UL << EHCA_HUGEPAGESHIFT) -#define EHCA_HUGEPAGE_PFN_MASK ((EHCA_HUGEPAGE_SIZE - 1) >> PAGE_SHIFT) -#define EHCA_INVAL_ADDR 0xFFFFFFFFFFFFFFFFULL -#define EHCA_DIR_INDEX_SHIFT 13 /* 8k Entries in 64k block */ -#define EHCA_TOP_INDEX_SHIFT (EHCA_DIR_INDEX_SHIFT * 2) -#define EHCA_MAP_ENTRIES (1 << EHCA_DIR_INDEX_SHIFT) -#define EHCA_TOP_MAP_SIZE (0x10000) /* currently fixed map size */ -#define EHCA_DIR_MAP_SIZE (0x10000) -#define EHCA_ENT_MAP_SIZE (0x10000) -#define EHCA_INDEX_MASK (EHCA_MAP_ENTRIES - 1) - -static unsigned long ehca_mr_len; - -/* - * Memory map data structures - */ -struct ehca_dir_bmap { - u64 ent[EHCA_MAP_ENTRIES]; -}; -struct ehca_top_bmap { - struct ehca_dir_bmap *dir[EHCA_MAP_ENTRIES]; -}; -struct ehca_bmap { - struct ehca_top_bmap *top[EHCA_MAP_ENTRIES]; -}; - -static struct ehca_bmap *ehca_bmap; - static struct kmem_cache *mr_cache; static struct kmem_cache *mw_cache; @@ -100,8 +68,6 @@ enum ehca_mr_pgsize { #define EHCA_MR_PGSHIFT1M 20 #define EHCA_MR_PGSHIFT16M 24 -static u64 ehca_map_vaddr(void *caddr); - static u32 ehca_encode_hwpage_size(u32 pgsize) { int log = ilog2(pgsize); @@ -169,8 +135,7 @@ struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags) goto get_dma_mr_exit0; } - ret = ehca_reg_maxmr(shca, e_maxmr, - (void *)ehca_map_vaddr((void *)KERNELBASE), + ret = ehca_reg_maxmr(shca, e_maxmr, (u64 *)KERNELBASE, mr_access_flags, e_pd, &e_maxmr->ib.ib_mr.lkey, &e_maxmr->ib.ib_mr.rkey); @@ -286,7 +251,7 @@ struct ib_mr *ehca_reg_phys_mr(struct ib_pd *pd, ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags, e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, - &e_mr->ib.ib_mr.rkey, EHCA_REG_MR); + &e_mr->ib.ib_mr.rkey); if (ret) { ib_mr = ERR_PTR(ret); goto reg_phys_mr_exit1; @@ -405,7 +370,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags, e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, - &e_mr->ib.ib_mr.rkey, EHCA_REG_MR); + &e_mr->ib.ib_mr.rkey); if (ret == -EINVAL && pginfo.hwpage_size > PAGE_SIZE) { ehca_warn(pd->device, "failed to register mr " "with hwpage_size=%llx", hwpage_size); @@ -829,7 +794,7 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd, ret = ehca_reg_mr(shca, e_fmr, NULL, fmr_attr->max_pages * (1 << fmr_attr->page_shift), mr_access_flags, e_pd, &pginfo, - &tmp_lkey, &tmp_rkey, EHCA_REG_MR); + &tmp_lkey, &tmp_rkey); if (ret) { ib_fmr = ERR_PTR(ret); goto alloc_fmr_exit1; @@ -1018,10 +983,6 @@ int ehca_dealloc_fmr(struct ib_fmr *fmr) /*----------------------------------------------------------------------*/ -static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca, - struct ehca_mr *e_mr, - struct ehca_mr_pginfo *pginfo); - int ehca_reg_mr(struct ehca_shca *shca, struct ehca_mr *e_mr, u64 *iova_start, @@ -1030,8 +991,7 @@ int ehca_reg_mr(struct ehca_shca *shca, struct ehca_pd *e_pd, struct ehca_mr_pginfo *pginfo, u32 *lkey, /*OUT*/ - u32 *rkey, /*OUT*/ - enum ehca_reg_type reg_type) + u32 *rkey) /*OUT*/ { int ret; u64 h_ret; @@ -1055,13 +1015,7 @@ int ehca_reg_mr(struct ehca_shca *shca, e_mr->ipz_mr_handle = hipzout.handle; - if (reg_type == EHCA_REG_BUSMAP_MR) - ret = ehca_reg_bmap_mr_rpages(shca, e_mr, pginfo); - else if (reg_type == EHCA_REG_MR) - ret = ehca_reg_mr_rpages(shca, e_mr, pginfo); - else - ret = -EINVAL; - + ret = ehca_reg_mr_rpages(shca, e_mr, pginfo); if (ret) goto ehca_reg_mr_exit1; @@ -1362,7 +1316,7 @@ int ehca_rereg_mr(struct ehca_shca *shca, e_mr->fmr_map_cnt = save_mr.fmr_map_cnt; ret = ehca_reg_mr(shca, e_mr, iova_start, size, acl, - e_pd, pginfo, lkey, rkey, EHCA_REG_MR); + e_pd, pginfo, lkey, rkey); if (ret) { u32 offset = (u64)(&e_mr->flags) - (u64)e_mr; memcpy(&e_mr->flags, &(save_mr.flags), @@ -1455,7 +1409,7 @@ int ehca_unmap_one_fmr(struct ehca_shca *shca, ret = ehca_reg_mr(shca, e_fmr, NULL, (e_fmr->fmr_max_pages * e_fmr->fmr_page_size), e_fmr->acl, e_pd, &pginfo, &tmp_lkey, - &tmp_rkey, EHCA_REG_MR); + &tmp_rkey); if (ret) { u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr; memcpy(&e_fmr->flags, &(save_mr.flags), @@ -1524,90 +1478,6 @@ int ehca_reg_smr(struct ehca_shca *shca, } /* end ehca_reg_smr() */ /*----------------------------------------------------------------------*/ -static inline void *ehca_calc_sectbase(int top, int dir, int idx) -{ - unsigned long ret = idx; - ret |= dir << EHCA_DIR_INDEX_SHIFT; - ret |= top << EHCA_TOP_INDEX_SHIFT; - return abs_to_virt(ret << SECTION_SIZE_BITS); -} - -#define ehca_bmap_valid(entry) \ - ((u64)entry != (u64)EHCA_INVAL_ADDR) - -static u64 ehca_reg_mr_section(int top, int dir, int idx, u64 *kpage, - struct ehca_shca *shca, struct ehca_mr *mr, - struct ehca_mr_pginfo *pginfo) -{ - u64 h_ret = 0; - unsigned long page = 0; - u64 rpage = virt_to_abs(kpage); - int page_count; - - void *sectbase = ehca_calc_sectbase(top, dir, idx); - if ((unsigned long)sectbase & (pginfo->hwpage_size - 1)) { - ehca_err(&shca->ib_device, "reg_mr_section will probably fail:" - "hwpage_size does not fit to " - "section start address"); - } - page_count = EHCA_SECTSIZE / pginfo->hwpage_size; - - while (page < page_count) { - u64 rnum; - for (rnum = 0; (rnum < MAX_RPAGES) && (page < page_count); - rnum++) { - void *pg = sectbase + ((page++) * pginfo->hwpage_size); - kpage[rnum] = virt_to_abs(pg); - } - - h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, mr, - ehca_encode_hwpage_size(pginfo->hwpage_size), - 0, rpage, rnum); - - if ((h_ret != H_SUCCESS) && (h_ret != H_PAGE_REGISTERED)) { - ehca_err(&shca->ib_device, "register_rpage_mr failed"); - return h_ret; - } - } - return h_ret; -} - -static u64 ehca_reg_mr_sections(int top, int dir, u64 *kpage, - struct ehca_shca *shca, struct ehca_mr *mr, - struct ehca_mr_pginfo *pginfo) -{ - u64 hret = H_SUCCESS; - int idx; - - for (idx = 0; idx < EHCA_MAP_ENTRIES; idx++) { - if (!ehca_bmap_valid(ehca_bmap->top[top]->dir[dir]->ent[idx])) - continue; - - hret = ehca_reg_mr_section(top, dir, idx, kpage, shca, mr, - pginfo); - if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) - return hret; - } - return hret; -} - -static u64 ehca_reg_mr_dir_sections(int top, u64 *kpage, struct ehca_shca *shca, - struct ehca_mr *mr, - struct ehca_mr_pginfo *pginfo) -{ - u64 hret = H_SUCCESS; - int dir; - - for (dir = 0; dir < EHCA_MAP_ENTRIES; dir++) { - if (!ehca_bmap_valid(ehca_bmap->top[top]->dir[dir])) - continue; - - hret = ehca_reg_mr_sections(top, dir, kpage, shca, mr, pginfo); - if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) - return hret; - } - return hret; -} /* register internal max-MR to internal SHCA */ int ehca_reg_internal_maxmr( @@ -1625,11 +1495,6 @@ int ehca_reg_internal_maxmr( u32 num_hwpages; u64 hw_pgsize; - if (!ehca_bmap) { - ret = -EFAULT; - goto ehca_reg_internal_maxmr_exit0; - } - e_mr = ehca_mr_new(); if (!e_mr) { ehca_err(&shca->ib_device, "out of memory"); @@ -1639,8 +1504,8 @@ int ehca_reg_internal_maxmr( e_mr->flags |= EHCA_MR_FLAG_MAXMR; /* register internal max-MR on HCA */ - size_maxmr = ehca_mr_len; - iova_start = (u64 *)ehca_map_vaddr((void *)KERNELBASE); + size_maxmr = (u64)high_memory - PAGE_OFFSET; + iova_start = (u64 *)KERNELBASE; ib_pbuf.addr = 0; ib_pbuf.size = size_maxmr; num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr, @@ -1659,7 +1524,7 @@ int ehca_reg_internal_maxmr( ret = ehca_reg_mr(shca, e_mr, iova_start, size_maxmr, 0, e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, - &e_mr->ib.ib_mr.rkey, EHCA_REG_BUSMAP_MR); + &e_mr->ib.ib_mr.rkey); if (ret) { ehca_err(&shca->ib_device, "reg of internal max MR failed, " "e_mr=%p iova_start=%p size_maxmr=%llx num_kpages=%x " @@ -2212,8 +2077,8 @@ int ehca_mr_is_maxmr(u64 size, u64 *iova_start) { /* a MR is treated as max-MR only if it fits following: */ - if ((size == ehca_mr_len) && - (iova_start == (void *)ehca_map_vaddr((void *)KERNELBASE))) { + if ((size == ((u64)high_memory - PAGE_OFFSET)) && + (iova_start == (void *)KERNELBASE)) { ehca_gen_dbg("this is a max-MR"); return 1; } else @@ -2319,350 +2184,3 @@ void ehca_cleanup_mrmw_cache(void) if (mw_cache) kmem_cache_destroy(mw_cache); } - -static inline int ehca_init_top_bmap(struct ehca_top_bmap *ehca_top_bmap, - int dir) -{ - if (!ehca_bmap_valid(ehca_top_bmap->dir[dir])) { - ehca_top_bmap->dir[dir] = - kmalloc(sizeof(struct ehca_dir_bmap), GFP_KERNEL); - if (!ehca_top_bmap->dir[dir]) - return -ENOMEM; - /* Set map block to 0xFF according to EHCA_INVAL_ADDR */ - memset(ehca_top_bmap->dir[dir], 0xFF, EHCA_ENT_MAP_SIZE); - } - return 0; -} - -static inline int ehca_init_bmap(struct ehca_bmap *ehca_bmap, int top, int dir) -{ - if (!ehca_bmap_valid(ehca_bmap->top[top])) { - ehca_bmap->top[top] = - kmalloc(sizeof(struct ehca_top_bmap), GFP_KERNEL); - if (!ehca_bmap->top[top]) - return -ENOMEM; - /* Set map block to 0xFF according to EHCA_INVAL_ADDR */ - memset(ehca_bmap->top[top], 0xFF, EHCA_DIR_MAP_SIZE); - } - return ehca_init_top_bmap(ehca_bmap->top[top], dir); -} - -static inline int ehca_calc_index(unsigned long i, unsigned long s) -{ - return (i >> s) & EHCA_INDEX_MASK; -} - -void ehca_destroy_busmap(void) -{ - int top, dir; - - if (!ehca_bmap) - return; - - for (top = 0; top < EHCA_MAP_ENTRIES; top++) { - if (!ehca_bmap_valid(ehca_bmap->top[top])) - continue; - for (dir = 0; dir < EHCA_MAP_ENTRIES; dir++) { - if (!ehca_bmap_valid(ehca_bmap->top[top]->dir[dir])) - continue; - - kfree(ehca_bmap->top[top]->dir[dir]); - } - - kfree(ehca_bmap->top[top]); - } - - kfree(ehca_bmap); - ehca_bmap = NULL; -} - -static int ehca_update_busmap(unsigned long pfn, unsigned long nr_pages) -{ - unsigned long i, start_section, end_section; - int top, dir, idx; - - if (!nr_pages) - return 0; - - if (!ehca_bmap) { - ehca_bmap = kmalloc(sizeof(struct ehca_bmap), GFP_KERNEL); - if (!ehca_bmap) - return -ENOMEM; - /* Set map block to 0xFF according to EHCA_INVAL_ADDR */ - memset(ehca_bmap, 0xFF, EHCA_TOP_MAP_SIZE); - } - - start_section = phys_to_abs(pfn * PAGE_SIZE) / EHCA_SECTSIZE; - end_section = phys_to_abs((pfn + nr_pages) * PAGE_SIZE) / EHCA_SECTSIZE; - for (i = start_section; i < end_section; i++) { - int ret; - top = ehca_calc_index(i, EHCA_TOP_INDEX_SHIFT); - dir = ehca_calc_index(i, EHCA_DIR_INDEX_SHIFT); - idx = i & EHCA_INDEX_MASK; - - ret = ehca_init_bmap(ehca_bmap, top, dir); - if (ret) { - ehca_destroy_busmap(); - return ret; - } - ehca_bmap->top[top]->dir[dir]->ent[idx] = ehca_mr_len; - ehca_mr_len += EHCA_SECTSIZE; - } - return 0; -} - -static int ehca_is_hugepage(unsigned long pfn) -{ - int page_order; - - if (pfn & EHCA_HUGEPAGE_PFN_MASK) - return 0; - - page_order = compound_order(pfn_to_page(pfn)); - if (page_order + PAGE_SHIFT != EHCA_HUGEPAGESHIFT) - return 0; - - return 1; -} - -static int ehca_create_busmap_callback(unsigned long initial_pfn, - unsigned long total_nr_pages, void *arg) -{ - int ret; - unsigned long pfn, start_pfn, end_pfn, nr_pages; - - if ((total_nr_pages * PAGE_SIZE) < EHCA_HUGEPAGE_SIZE) - return ehca_update_busmap(initial_pfn, total_nr_pages); - - /* Given chunk is >= 16GB -> check for hugepages */ - start_pfn = initial_pfn; - end_pfn = initial_pfn + total_nr_pages; - pfn = start_pfn; - - while (pfn < end_pfn) { - if (ehca_is_hugepage(pfn)) { - /* Add mem found in front of the hugepage */ - nr_pages = pfn - start_pfn; - ret = ehca_update_busmap(start_pfn, nr_pages); - if (ret) - return ret; - /* Skip the hugepage */ - pfn += (EHCA_HUGEPAGE_SIZE / PAGE_SIZE); - start_pfn = pfn; - } else - pfn += (EHCA_SECTSIZE / PAGE_SIZE); - } - - /* Add mem found behind the hugepage(s) */ - nr_pages = pfn - start_pfn; - return ehca_update_busmap(start_pfn, nr_pages); -} - -int ehca_create_busmap(void) -{ - int ret; - - ehca_mr_len = 0; - ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL, - ehca_create_busmap_callback); - return ret; -} - -static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca, - struct ehca_mr *e_mr, - struct ehca_mr_pginfo *pginfo) -{ - int top; - u64 hret, *kpage; - - kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); - if (!kpage) { - ehca_err(&shca->ib_device, "kpage alloc failed"); - return -ENOMEM; - } - for (top = 0; top < EHCA_MAP_ENTRIES; top++) { - if (!ehca_bmap_valid(ehca_bmap->top[top])) - continue; - hret = ehca_reg_mr_dir_sections(top, kpage, shca, e_mr, pginfo); - if ((hret != H_PAGE_REGISTERED) && (hret != H_SUCCESS)) - break; - } - - ehca_free_fw_ctrlblock(kpage); - - if (hret == H_SUCCESS) - return 0; /* Everything is fine */ - else { - ehca_err(&shca->ib_device, "ehca_reg_bmap_mr_rpages failed, " - "h_ret=%lli e_mr=%p top=%x lkey=%x " - "hca_hndl=%llx mr_hndl=%llx", hret, e_mr, top, - e_mr->ib.ib_mr.lkey, - shca->ipz_hca_handle.handle, - e_mr->ipz_mr_handle.handle); - return ehca2ib_return_code(hret); - } -} - -static u64 ehca_map_vaddr(void *caddr) -{ - int top, dir, idx; - unsigned long abs_addr, offset; - u64 entry; - - if (!ehca_bmap) - return EHCA_INVAL_ADDR; - - abs_addr = virt_to_abs(caddr); - top = ehca_calc_index(abs_addr, EHCA_TOP_INDEX_SHIFT + EHCA_SECTSHIFT); - if (!ehca_bmap_valid(ehca_bmap->top[top])) - return EHCA_INVAL_ADDR; - - dir = ehca_calc_index(abs_addr, EHCA_DIR_INDEX_SHIFT + EHCA_SECTSHIFT); - if (!ehca_bmap_valid(ehca_bmap->top[top]->dir[dir])) - return EHCA_INVAL_ADDR; - - idx = ehca_calc_index(abs_addr, EHCA_SECTSHIFT); - - entry = ehca_bmap->top[top]->dir[dir]->ent[idx]; - if (ehca_bmap_valid(entry)) { - offset = (unsigned long)caddr & (EHCA_SECTSIZE - 1); - return entry | offset; - } else - return EHCA_INVAL_ADDR; -} - -static int ehca_dma_mapping_error(struct ib_device *dev, u64 dma_addr) -{ - return dma_addr == EHCA_INVAL_ADDR; -} - -static u64 ehca_dma_map_single(struct ib_device *dev, void *cpu_addr, - size_t size, enum dma_data_direction direction) -{ - if (cpu_addr) - return ehca_map_vaddr(cpu_addr); - else - return EHCA_INVAL_ADDR; -} - -static void ehca_dma_unmap_single(struct ib_device *dev, u64 addr, size_t size, - enum dma_data_direction direction) -{ - /* This is only a stub; nothing to be done here */ -} - -static u64 ehca_dma_map_page(struct ib_device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction) -{ - u64 addr; - - if (offset + size > PAGE_SIZE) - return EHCA_INVAL_ADDR; - - addr = ehca_map_vaddr(page_address(page)); - if (!ehca_dma_mapping_error(dev, addr)) - addr += offset; - - return addr; -} - -static void ehca_dma_unmap_page(struct ib_device *dev, u64 addr, size_t size, - enum dma_data_direction direction) -{ - /* This is only a stub; nothing to be done here */ -} - -static int ehca_dma_map_sg(struct ib_device *dev, struct scatterlist *sgl, - int nents, enum dma_data_direction direction) -{ - struct scatterlist *sg; - int i; - - for_each_sg(sgl, sg, nents, i) { - u64 addr; - addr = ehca_map_vaddr(sg_virt(sg)); - if (ehca_dma_mapping_error(dev, addr)) - return 0; - - sg->dma_address = addr; - sg->dma_length = sg->length; - } - return nents; -} - -static void ehca_dma_unmap_sg(struct ib_device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) -{ - /* This is only a stub; nothing to be done here */ -} - -static u64 ehca_dma_address(struct ib_device *dev, struct scatterlist *sg) -{ - return sg->dma_address; -} - -static unsigned int ehca_dma_len(struct ib_device *dev, struct scatterlist *sg) -{ - return sg->length; -} - -static void ehca_dma_sync_single_for_cpu(struct ib_device *dev, u64 addr, - size_t size, - enum dma_data_direction dir) -{ - dma_sync_single_for_cpu(dev->dma_device, addr, size, dir); -} - -static void ehca_dma_sync_single_for_device(struct ib_device *dev, u64 addr, - size_t size, - enum dma_data_direction dir) -{ - dma_sync_single_for_device(dev->dma_device, addr, size, dir); -} - -static void *ehca_dma_alloc_coherent(struct ib_device *dev, size_t size, - u64 *dma_handle, gfp_t flag) -{ - struct page *p; - void *addr = NULL; - u64 dma_addr; - - p = alloc_pages(flag, get_order(size)); - if (p) { - addr = page_address(p); - dma_addr = ehca_map_vaddr(addr); - if (ehca_dma_mapping_error(dev, dma_addr)) { - free_pages((unsigned long)addr, get_order(size)); - return NULL; - } - if (dma_handle) - *dma_handle = dma_addr; - return addr; - } - return NULL; -} - -static void ehca_dma_free_coherent(struct ib_device *dev, size_t size, - void *cpu_addr, u64 dma_handle) -{ - if (cpu_addr && size) - free_pages((unsigned long)cpu_addr, get_order(size)); -} - - -struct ib_dma_mapping_ops ehca_dma_mapping_ops = { - .mapping_error = ehca_dma_mapping_error, - .map_single = ehca_dma_map_single, - .unmap_single = ehca_dma_unmap_single, - .map_page = ehca_dma_map_page, - .unmap_page = ehca_dma_unmap_page, - .map_sg = ehca_dma_map_sg, - .unmap_sg = ehca_dma_unmap_sg, - .dma_address = ehca_dma_address, - .dma_len = ehca_dma_len, - .sync_single_for_cpu = ehca_dma_sync_single_for_cpu, - .sync_single_for_device = ehca_dma_sync_single_for_device, - .alloc_coherent = ehca_dma_alloc_coherent, - .free_coherent = ehca_dma_free_coherent, -}; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.h b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.h index 50d8b51306dd..bc8f4e31c123 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.h @@ -42,11 +42,6 @@ #ifndef _EHCA_MRMW_H_ #define _EHCA_MRMW_H_ -enum ehca_reg_type { - EHCA_REG_MR, - EHCA_REG_BUSMAP_MR -}; - int ehca_reg_mr(struct ehca_shca *shca, struct ehca_mr *e_mr, u64 *iova_start, @@ -55,8 +50,7 @@ int ehca_reg_mr(struct ehca_shca *shca, struct ehca_pd *e_pd, struct ehca_mr_pginfo *pginfo, u32 *lkey, - u32 *rkey, - enum ehca_reg_type reg_type); + u32 *rkey); int ehca_reg_mr_rpages(struct ehca_shca *shca, struct ehca_mr *e_mr, @@ -124,9 +118,4 @@ void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl, void ehca_mr_deletenew(struct ehca_mr *mr); -int ehca_create_busmap(void); - -void ehca_destroy_busmap(void); - -extern struct ib_dma_mapping_ops ehca_dma_mapping_ops; #endif /*_EHCA_MRMW_H_*/ diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mr.c b/trunk/drivers/infiniband/hw/mthca/mthca_mr.c index 065b20899876..d606edf10858 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mr.c @@ -352,14 +352,10 @@ static void mthca_arbel_write_mtt_seg(struct mthca_dev *dev, BUG_ON(!mtts); - dma_sync_single_for_cpu(&dev->pdev->dev, dma_handle, - list_len * sizeof (u64), DMA_TO_DEVICE); - for (i = 0; i < list_len; ++i) mtts[i] = cpu_to_be64(buffer_list[i] | MTHCA_MTT_FLAG_PRESENT); - dma_sync_single_for_device(&dev->pdev->dev, dma_handle, - list_len * sizeof (u64), DMA_TO_DEVICE); + dma_sync_single(&dev->pdev->dev, dma_handle, list_len * sizeof (u64), DMA_TO_DEVICE); } int mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt, @@ -807,15 +803,12 @@ int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, wmb(); - dma_sync_single_for_cpu(&dev->pdev->dev, fmr->mem.arbel.dma_handle, - list_len * sizeof(u64), DMA_TO_DEVICE); - for (i = 0; i < list_len; ++i) fmr->mem.arbel.mtts[i] = cpu_to_be64(page_list[i] | MTHCA_MTT_FLAG_PRESENT); - dma_sync_single_for_device(&dev->pdev->dev, fmr->mem.arbel.dma_handle, - list_len * sizeof(u64), DMA_TO_DEVICE); + dma_sync_single(&dev->pdev->dev, fmr->mem.arbel.dma_handle, + list_len * sizeof(u64), DMA_TO_DEVICE); fmr->mem.arbel.mpt->key = cpu_to_be32(key); fmr->mem.arbel.mpt->lkey = cpu_to_be32(key); diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.c b/trunk/drivers/infiniband/hw/nes/nes_cm.c index 114b802771ad..11c7d6642014 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.c +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.c @@ -472,7 +472,6 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, static void nes_retrans_expired(struct nes_cm_node *cm_node) { - struct iw_cm_id *cm_id = cm_node->cm_id; switch (cm_node->state) { case NES_CM_STATE_SYN_RCVD: case NES_CM_STATE_CLOSING: @@ -480,9 +479,7 @@ static void nes_retrans_expired(struct nes_cm_node *cm_node) break; case NES_CM_STATE_LAST_ACK: case NES_CM_STATE_FIN_WAIT1: - if (cm_node->cm_id) - cm_id->rem_ref(cm_id); - cm_node->state = NES_CM_STATE_CLOSED; + case NES_CM_STATE_MPAREJ_RCVD: send_reset(cm_node, NULL); break; default: @@ -1409,7 +1406,6 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, case NES_CM_STATE_CLOSED: drop_packet(skb); break; - case NES_CM_STATE_FIN_WAIT1: case NES_CM_STATE_LAST_ACK: cm_node->cm_id->rem_ref(cm_node->cm_id); case NES_CM_STATE_TIME_WAIT: @@ -1417,6 +1413,8 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, rem_ref_cm_node(cm_node->cm_core, cm_node); drop_packet(skb); break; + case NES_CM_STATE_FIN_WAIT1: + nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__); default: drop_packet(skb); break; diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.c b/trunk/drivers/infiniband/hw/nes/nes_verbs.c index 21e0fd336cf7..64d5cfd8f380 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_verbs.c +++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.c @@ -654,7 +654,7 @@ static int nes_query_device(struct ib_device *ibdev, struct ib_device_attr *prop default: props->max_qp_rd_atom = 0; } - props->max_qp_init_rd_atom = props->max_qp_rd_atom; + props->max_qp_init_rd_atom = props->max_qp_wr; props->atomic_cap = IB_ATOMIC_NONE; props->max_map_per_fmr = 1; diff --git a/trunk/drivers/input/misc/cobalt_btns.c b/trunk/drivers/input/misc/cobalt_btns.c index d114d3a9e1e9..2adf9cb265da 100644 --- a/trunk/drivers/input/misc/cobalt_btns.c +++ b/trunk/drivers/input/misc/cobalt_btns.c @@ -1,7 +1,7 @@ /* * Cobalt button interface driver. * - * Copyright (C) 2007-2008 Yoichi Yuasa + * Copyright (C) 2007-2008 Yoichi Yuasa * * 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 @@ -148,7 +148,7 @@ static int __devexit cobalt_buttons_remove(struct platform_device *pdev) return 0; } -MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_AUTHOR("Yoichi Yuasa "); MODULE_DESCRIPTION("Cobalt button interface driver"); MODULE_LICENSE("GPL"); /* work with hotplug and coldplug */ diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 7c8e7122aaa9..9b60b6b684d9 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -75,7 +75,6 @@ config LEDS_ALIX2 depends on LEDS_CLASS && X86 && EXPERIMENTAL help This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. - You have to set leds-alix2.force=1 for boards with Award BIOS. config LEDS_H1940 tristate "LED Support for iPAQ H1940 device" @@ -146,16 +145,15 @@ config LEDS_GPIO_OF of_platform devices. For instance, LEDs which are listed in a "dts" file. -config LEDS_LP3944 - tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" +config LEDS_LP5521 + tristate "LED Support for the LP5521 LEDs" depends on LEDS_CLASS && I2C help - This option enables support for LEDs connected to the National - Semiconductor LP3944 Lighting Management Unit (LMU) also known as - Fun Light Chip. + If you say 'Y' here you get support for the National Semiconductor + LP5521 LED driver used in n8x0 boards. - To compile this driver as a module, choose M here: the - module will be called leds-lp3944. + This driver can be built as a module by choosing 'M'. The module + will be called leds-lp5521. config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" diff --git a/trunk/drivers/leds/Makefile b/trunk/drivers/leds/Makefile index e8cdcf77a4c3..2d41c4dcf92f 100644 --- a/trunk/drivers/leds/Makefile +++ b/trunk/drivers/leds/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o -obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o obj-$(CONFIG_LEDS_FSG) += leds-fsg.o diff --git a/trunk/drivers/leds/leds-alix2.c b/trunk/drivers/leds/leds-alix2.c index 731d4eef3425..ddbd7730dfc8 100644 --- a/trunk/drivers/leds/leds-alix2.c +++ b/trunk/drivers/leds/leds-alix2.c @@ -14,7 +14,7 @@ static int force = 0; module_param(force, bool, 0444); -MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs"); +MODULE_PARM_DESC(force, "Assume system has ALIX.2 style LEDs"); struct alix_led { struct led_classdev cdev; @@ -155,11 +155,6 @@ static int __init alix_led_init(void) goto out; } - /* enable output on GPIO for LED 1,2,3 */ - outl(1 << 6, 0x6104); - outl(1 << 9, 0x6184); - outl(1 << 11, 0x6184); - pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); if (!IS_ERR(pdev)) { ret = platform_driver_probe(&alix_led_driver, alix_led_probe); diff --git a/trunk/drivers/leds/leds-bd2802.c b/trunk/drivers/leds/leds-bd2802.c index 779d7f262c04..4149ecb3a9b2 100644 --- a/trunk/drivers/leds/leds-bd2802.c +++ b/trunk/drivers/leds/leds-bd2802.c @@ -97,10 +97,6 @@ struct bd2802_led { enum led_ids led_id; enum led_colors color; enum led_bits state; - - /* General attributes of RGB LEDs */ - int wave_pattern; - int rgb_current; }; @@ -258,7 +254,7 @@ static void bd2802_set_on(struct bd2802_led *led, enum led_ids id, bd2802_reset_cancel(led); reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); - bd2802_write_byte(led->client, reg, led->rgb_current); + bd2802_write_byte(led->client, reg, BD2802_CURRENT_032); reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); @@ -279,9 +275,9 @@ static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id, reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); - bd2802_write_byte(led->client, reg, led->rgb_current); + bd2802_write_byte(led->client, reg, BD2802_CURRENT_032); reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); - bd2802_write_byte(led->client, reg, led->wave_pattern); + bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF); bd2802_enable(led, id); bd2802_update_state(led, id, color, BD2802_BLINK); @@ -410,7 +406,7 @@ static void bd2802_enable_adv_conf(struct bd2802_led *led) ret = device_create_file(&led->client->dev, bd2802_addr_attributes[i]); if (ret) { - dev_err(&led->client->dev, "failed: sysfs file %s\n", + dev_err(&led->client->dev, "failed to sysfs file %s\n", bd2802_addr_attributes[i]->attr.name); goto failed_remove_files; } @@ -487,52 +483,6 @@ static struct device_attribute bd2802_adv_conf_attr = { .store = bd2802_store_adv_conf, }; -#define BD2802_CONTROL_ATTR(attr_name, name_str) \ -static ssize_t bd2802_show_##attr_name(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ - ssize_t ret; \ - down_read(&led->rwsem); \ - ret = sprintf(buf, "0x%02x\n", led->attr_name); \ - up_read(&led->rwsem); \ - return ret; \ -} \ -static ssize_t bd2802_store_##attr_name(struct device *dev, \ - struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ - unsigned long val; \ - int ret; \ - if (!count) \ - return -EINVAL; \ - ret = strict_strtoul(buf, 16, &val); \ - if (ret) \ - return ret; \ - down_write(&led->rwsem); \ - led->attr_name = val; \ - up_write(&led->rwsem); \ - return count; \ -} \ -static struct device_attribute bd2802_##attr_name##_attr = { \ - .attr = { \ - .name = name_str, \ - .mode = 0644, \ - .owner = THIS_MODULE \ - }, \ - .show = bd2802_show_##attr_name, \ - .store = bd2802_store_##attr_name, \ -}; - -BD2802_CONTROL_ATTR(wave_pattern, "wave_pattern"); -BD2802_CONTROL_ATTR(rgb_current, "rgb_current"); - -static struct device_attribute *bd2802_attributes[] = { - &bd2802_adv_conf_attr, - &bd2802_wave_pattern_attr, - &bd2802_rgb_current_attr, -}; - static void bd2802_led_work(struct work_struct *work) { struct bd2802_led *led = container_of(work, struct bd2802_led, work); @@ -588,6 +538,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led1r.brightness = LED_OFF; led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness; led->cdev_led1r.blink_set = bd2802_set_led1r_blink; + led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led1r); if (ret < 0) { @@ -600,6 +551,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led1g.brightness = LED_OFF; led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness; led->cdev_led1g.blink_set = bd2802_set_led1g_blink; + led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led1g); if (ret < 0) { @@ -612,6 +564,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led1b.brightness = LED_OFF; led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness; led->cdev_led1b.blink_set = bd2802_set_led1b_blink; + led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led1b); if (ret < 0) { @@ -624,6 +577,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led2r.brightness = LED_OFF; led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness; led->cdev_led2r.blink_set = bd2802_set_led2r_blink; + led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led2r); if (ret < 0) { @@ -636,6 +590,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) led->cdev_led2g.brightness = LED_OFF; led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness; led->cdev_led2g.blink_set = bd2802_set_led2g_blink; + led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&led->client->dev, &led->cdev_led2g); if (ret < 0) { @@ -685,7 +640,7 @@ static int __devinit bd2802_probe(struct i2c_client *client, { struct bd2802_led *led; struct bd2802_led_platform_data *pdata; - int ret, i; + int ret; led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL); if (!led) { @@ -715,20 +670,13 @@ static int __devinit bd2802_probe(struct i2c_client *client, /* To save the power, reset BD2802 after detecting */ gpio_set_value(led->pdata->reset_gpio, 0); - /* Default attributes */ - led->wave_pattern = BD2802_PATTERN_HALF; - led->rgb_current = BD2802_CURRENT_032; - init_rwsem(&led->rwsem); - for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) { - ret = device_create_file(&led->client->dev, - bd2802_attributes[i]); - if (ret) { - dev_err(&led->client->dev, "failed: sysfs file %s\n", - bd2802_attributes[i]->attr.name); - goto failed_unregister_dev_file; - } + ret = device_create_file(&client->dev, &bd2802_adv_conf_attr); + if (ret) { + dev_err(&client->dev, "failed to create sysfs file %s\n", + bd2802_adv_conf_attr.attr.name); + goto failed_free; } ret = bd2802_register_led_classdev(led); @@ -738,8 +686,7 @@ static int __devinit bd2802_probe(struct i2c_client *client, return 0; failed_unregister_dev_file: - for (i--; i >= 0; i--) - device_remove_file(&led->client->dev, bd2802_attributes[i]); + device_remove_file(&client->dev, &bd2802_adv_conf_attr); failed_free: i2c_set_clientdata(client, NULL); kfree(led); @@ -750,14 +697,12 @@ static int __devinit bd2802_probe(struct i2c_client *client, static int __exit bd2802_remove(struct i2c_client *client) { struct bd2802_led *led = i2c_get_clientdata(client); - int i; - gpio_set_value(led->pdata->reset_gpio, 0); bd2802_unregister_led_classdev(led); + gpio_set_value(led->pdata->reset_gpio, 0); if (led->adf_on) bd2802_disable_adv_conf(led); - for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) - device_remove_file(&led->client->dev, bd2802_attributes[i]); + device_remove_file(&client->dev, &bd2802_adv_conf_attr); i2c_set_clientdata(client, NULL); kfree(led); @@ -778,7 +723,8 @@ static int bd2802_resume(struct i2c_client *client) struct bd2802_led *led = i2c_get_clientdata(client); if (!bd2802_is_all_off(led) || led->adf_on) { - bd2802_reset_cancel(led); + gpio_set_value(led->pdata->reset_gpio, 1); + udelay(100); bd2802_restore_state(led); } @@ -816,4 +762,4 @@ module_exit(bd2802_exit); MODULE_AUTHOR("Kim Kyuwon "); MODULE_DESCRIPTION("BD2802 LED driver"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-cobalt-raq.c b/trunk/drivers/leds/leds-cobalt-raq.c index 5f1ce810815f..ff0e8c3fbf9b 100644 --- a/trunk/drivers/leds/leds-cobalt-raq.c +++ b/trunk/drivers/leds/leds-cobalt-raq.c @@ -1,7 +1,7 @@ /* * LEDs driver for the Cobalt Raq series. * - * Copyright (C) 2007 Yoichi Yuasa + * Copyright (C) 2007 Yoichi Yuasa * * 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 diff --git a/trunk/drivers/leds/leds-gpio.c b/trunk/drivers/leds/leds-gpio.c index 6b06638eb5b4..d2109054de85 100644 --- a/trunk/drivers/leds/leds-gpio.c +++ b/trunk/drivers/leds/leds-gpio.c @@ -76,7 +76,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, struct gpio_led_data *led_dat, struct device *parent, int (*blink_set)(unsigned, unsigned long *, unsigned long *)) { - int ret, state; + int ret; /* skip leds that aren't available */ if (!gpio_is_valid(template->gpio)) { @@ -99,15 +99,11 @@ static int __devinit create_gpio_led(const struct gpio_led *template, led_dat->cdev.blink_set = gpio_blink_set; } led_dat->cdev.brightness_set = gpio_led_set; - if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) - state = !!gpio_get_value(led_dat->gpio) ^ led_dat->active_low; - else - state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); - led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; + led_dat->cdev.brightness = LED_OFF; if (!template->retain_state_suspended) led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; - ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); + ret = gpio_direction_output(led_dat->gpio, led_dat->active_low); if (ret < 0) goto err; @@ -133,7 +129,7 @@ static void delete_gpio_led(struct gpio_led_data *led) } #ifdef CONFIG_LEDS_GPIO_PLATFORM -static int __devinit gpio_led_probe(struct platform_device *pdev) +static int gpio_led_probe(struct platform_device *pdev) { struct gpio_led_platform_data *pdata = pdev->dev.platform_data; struct gpio_led_data *leds_data; @@ -227,22 +223,12 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, memset(&led, 0, sizeof(led)); for_each_child_of_node(np, child) { enum of_gpio_flags flags; - const char *state; led.gpio = of_get_gpio_flags(child, 0, &flags); led.active_low = flags & OF_GPIO_ACTIVE_LOW; led.name = of_get_property(child, "label", NULL) ? : child->name; led.default_trigger = of_get_property(child, "linux,default-trigger", NULL); - state = of_get_property(child, "default-state", NULL); - if (state) { - if (!strcmp(state, "keep")) - led.default_state = LEDS_GPIO_DEFSTATE_KEEP; - else if(!strcmp(state, "on")) - led.default_state = LEDS_GPIO_DEFSTATE_ON; - else - led.default_state = LEDS_GPIO_DEFSTATE_OFF; - } ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++], &ofdev->dev, NULL); diff --git a/trunk/drivers/leds/leds-lp3944.c b/trunk/drivers/leds/leds-lp3944.c deleted file mode 100644 index 5946208ba26e..000000000000 --- a/trunk/drivers/leds/leds-lp3944.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * leds-lp3944.c - driver for National Semiconductor LP3944 Funlight Chip - * - * Copyright (C) 2009 Antonio Ospite - * - * 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. - * - */ - -/* - * I2C driver for National Semiconductor LP3944 Funlight Chip - * http://www.national.com/pf/LP/LP3944.html - * - * This helper chip can drive up to 8 leds, with two programmable DIM modes; - * it could even be used as a gpio expander but this driver assumes it is used - * as a led controller. - * - * The DIM modes are used to set _blink_ patterns for leds, the pattern is - * specified supplying two parameters: - * - period: from 0s to 1.6s - * - duty cycle: percentage of the period the led is on, from 0 to 100 - * - * LP3944 can be found on Motorola A910 smartphone, where it drives the rgb - * leds, the camera flash light and the displays backlights. - */ - -#include -#include -#include -#include -#include -#include - -/* Read Only Registers */ -#define LP3944_REG_INPUT1 0x00 /* LEDs 0-7 InputRegister (Read Only) */ -#define LP3944_REG_REGISTER1 0x01 /* None (Read Only) */ - -#define LP3944_REG_PSC0 0x02 /* Frequency Prescaler 0 (R/W) */ -#define LP3944_REG_PWM0 0x03 /* PWM Register 0 (R/W) */ -#define LP3944_REG_PSC1 0x04 /* Frequency Prescaler 1 (R/W) */ -#define LP3944_REG_PWM1 0x05 /* PWM Register 1 (R/W) */ -#define LP3944_REG_LS0 0x06 /* LEDs 0-3 Selector (R/W) */ -#define LP3944_REG_LS1 0x07 /* LEDs 4-7 Selector (R/W) */ - -/* These registers are not used to control leds in LP3944, they can store - * arbitrary values which the chip will ignore. - */ -#define LP3944_REG_REGISTER8 0x08 -#define LP3944_REG_REGISTER9 0x09 - -#define LP3944_DIM0 0 -#define LP3944_DIM1 1 - -/* period in ms */ -#define LP3944_PERIOD_MIN 0 -#define LP3944_PERIOD_MAX 1600 - -/* duty cycle is a percentage */ -#define LP3944_DUTY_CYCLE_MIN 0 -#define LP3944_DUTY_CYCLE_MAX 100 - -#define ldev_to_led(c) container_of(c, struct lp3944_led_data, ldev) - -/* Saved data */ -struct lp3944_led_data { - u8 id; - enum lp3944_type type; - enum lp3944_status status; - struct led_classdev ldev; - struct i2c_client *client; - struct work_struct work; -}; - -struct lp3944_data { - struct mutex lock; - struct i2c_client *client; - struct lp3944_led_data leds[LP3944_LEDS_MAX]; -}; - -static int lp3944_reg_read(struct i2c_client *client, u8 reg, u8 *value) -{ - int tmp; - - tmp = i2c_smbus_read_byte_data(client, reg); - if (tmp < 0) - return -EINVAL; - - *value = tmp; - - return 0; -} - -static int lp3944_reg_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -/** - * Set the period for DIM status - * - * @client: the i2c client - * @dim: either LP3944_DIM0 or LP3944_DIM1 - * @period: period of a blink, that is a on/off cycle, expressed in ms. - */ -static int lp3944_dim_set_period(struct i2c_client *client, u8 dim, u16 period) -{ - u8 psc_reg; - u8 psc_value; - int err; - - if (dim == LP3944_DIM0) - psc_reg = LP3944_REG_PSC0; - else if (dim == LP3944_DIM1) - psc_reg = LP3944_REG_PSC1; - else - return -EINVAL; - - /* Convert period to Prescaler value */ - if (period > LP3944_PERIOD_MAX) - return -EINVAL; - - psc_value = (period * 255) / LP3944_PERIOD_MAX; - - err = lp3944_reg_write(client, psc_reg, psc_value); - - return err; -} - -/** - * Set the duty cycle for DIM status - * - * @client: the i2c client - * @dim: either LP3944_DIM0 or LP3944_DIM1 - * @duty_cycle: percentage of a period during which a led is ON - */ -static int lp3944_dim_set_dutycycle(struct i2c_client *client, u8 dim, - u8 duty_cycle) -{ - u8 pwm_reg; - u8 pwm_value; - int err; - - if (dim == LP3944_DIM0) - pwm_reg = LP3944_REG_PWM0; - else if (dim == LP3944_DIM1) - pwm_reg = LP3944_REG_PWM1; - else - return -EINVAL; - - /* Convert duty cycle to PWM value */ - if (duty_cycle > LP3944_DUTY_CYCLE_MAX) - return -EINVAL; - - pwm_value = (duty_cycle * 255) / LP3944_DUTY_CYCLE_MAX; - - err = lp3944_reg_write(client, pwm_reg, pwm_value); - - return err; -} - -/** - * Set the led status - * - * @led: a lp3944_led_data structure - * @status: one of LP3944_LED_STATUS_OFF - * LP3944_LED_STATUS_ON - * LP3944_LED_STATUS_DIM0 - * LP3944_LED_STATUS_DIM1 - */ -static int lp3944_led_set(struct lp3944_led_data *led, u8 status) -{ - struct lp3944_data *data = i2c_get_clientdata(led->client); - u8 id = led->id; - u8 reg; - u8 val = 0; - int err; - - dev_dbg(&led->client->dev, "%s: %s, status before normalization:%d\n", - __func__, led->ldev.name, status); - - switch (id) { - case LP3944_LED0: - case LP3944_LED1: - case LP3944_LED2: - case LP3944_LED3: - reg = LP3944_REG_LS0; - break; - case LP3944_LED4: - case LP3944_LED5: - case LP3944_LED6: - case LP3944_LED7: - id -= LP3944_LED4; - reg = LP3944_REG_LS1; - break; - default: - return -EINVAL; - } - - if (status > LP3944_LED_STATUS_DIM1) - return -EINVAL; - - /* invert only 0 and 1, leave unchanged the other values, - * remember we are abusing status to set blink patterns - */ - if (led->type == LP3944_LED_TYPE_LED_INVERTED && status < 2) - status = 1 - status; - - mutex_lock(&data->lock); - lp3944_reg_read(led->client, reg, &val); - - val &= ~(LP3944_LED_STATUS_MASK << (id << 1)); - val |= (status << (id << 1)); - - dev_dbg(&led->client->dev, "%s: %s, reg:%d id:%d status:%d val:%#x\n", - __func__, led->ldev.name, reg, id, status, val); - - /* set led status */ - err = lp3944_reg_write(led->client, reg, val); - mutex_unlock(&data->lock); - - return err; -} - -static int lp3944_led_set_blink(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) -{ - struct lp3944_led_data *led = ldev_to_led(led_cdev); - u16 period; - u8 duty_cycle; - int err; - - /* units are in ms */ - if (*delay_on + *delay_off > LP3944_PERIOD_MAX) - return -EINVAL; - - if (*delay_on == 0 && *delay_off == 0) { - /* Special case: the leds subsystem requires a default user - * friendly blink pattern for the LED. Let's blink the led - * slowly (1Hz). - */ - *delay_on = 500; - *delay_off = 500; - } - - period = (*delay_on) + (*delay_off); - - /* duty_cycle is the percentage of period during which the led is ON */ - duty_cycle = 100 * (*delay_on) / period; - - /* invert duty cycle for inverted leds, this has the same effect of - * swapping delay_on and delay_off - */ - if (led->type == LP3944_LED_TYPE_LED_INVERTED) - duty_cycle = 100 - duty_cycle; - - /* NOTE: using always the first DIM mode, this means that all leds - * will have the same blinking pattern. - * - * We could find a way later to have two leds blinking in hardware - * with different patterns at the same time, falling back to software - * control for the other ones. - */ - err = lp3944_dim_set_period(led->client, LP3944_DIM0, period); - if (err) - return err; - - err = lp3944_dim_set_dutycycle(led->client, LP3944_DIM0, duty_cycle); - if (err) - return err; - - dev_dbg(&led->client->dev, "%s: OK hardware accelerated blink!\n", - __func__); - - led->status = LP3944_LED_STATUS_DIM0; - schedule_work(&led->work); - - return 0; -} - -static void lp3944_led_set_brightness(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - struct lp3944_led_data *led = ldev_to_led(led_cdev); - - dev_dbg(&led->client->dev, "%s: %s, %d\n", - __func__, led_cdev->name, brightness); - - led->status = brightness; - schedule_work(&led->work); -} - -static void lp3944_led_work(struct work_struct *work) -{ - struct lp3944_led_data *led; - - led = container_of(work, struct lp3944_led_data, work); - lp3944_led_set(led, led->status); -} - -static int lp3944_configure(struct i2c_client *client, - struct lp3944_data *data, - struct lp3944_platform_data *pdata) -{ - int i, err = 0; - - for (i = 0; i < pdata->leds_size; i++) { - struct lp3944_led *pled = &pdata->leds[i]; - struct lp3944_led_data *led = &data->leds[i]; - led->client = client; - led->id = i; - - switch (pled->type) { - - case LP3944_LED_TYPE_LED: - case LP3944_LED_TYPE_LED_INVERTED: - led->type = pled->type; - led->status = pled->status; - led->ldev.name = pled->name; - led->ldev.max_brightness = 1; - led->ldev.brightness_set = lp3944_led_set_brightness; - led->ldev.blink_set = lp3944_led_set_blink; - led->ldev.flags = LED_CORE_SUSPENDRESUME; - - INIT_WORK(&led->work, lp3944_led_work); - err = led_classdev_register(&client->dev, &led->ldev); - if (err < 0) { - dev_err(&client->dev, - "couldn't register LED %s\n", - led->ldev.name); - goto exit; - } - - /* to expose the default value to userspace */ - led->ldev.brightness = led->status; - - /* Set the default led status */ - err = lp3944_led_set(led, led->status); - if (err < 0) { - dev_err(&client->dev, - "%s couldn't set STATUS %d\n", - led->ldev.name, led->status); - goto exit; - } - break; - - case LP3944_LED_TYPE_NONE: - default: - break; - - } - } - return 0; - -exit: - if (i > 0) - for (i = i - 1; i >= 0; i--) - switch (pdata->leds[i].type) { - - case LP3944_LED_TYPE_LED: - case LP3944_LED_TYPE_LED_INVERTED: - led_classdev_unregister(&data->leds[i].ldev); - cancel_work_sync(&data->leds[i].work); - break; - - case LP3944_LED_TYPE_NONE: - default: - break; - } - - return err; -} - -static int __devinit lp3944_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; - struct lp3944_data *data; - - if (lp3944_pdata == NULL) { - dev_err(&client->dev, "no platform data\n"); - return -EINVAL; - } - - /* Let's see whether this adapter can support what we need. */ - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, "insufficient functionality!\n"); - return -ENODEV; - } - - data = kzalloc(sizeof(struct lp3944_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->client = client; - i2c_set_clientdata(client, data); - - mutex_init(&data->lock); - - dev_info(&client->dev, "lp3944 enabled\n"); - - lp3944_configure(client, data, lp3944_pdata); - return 0; -} - -static int __devexit lp3944_remove(struct i2c_client *client) -{ - struct lp3944_platform_data *pdata = client->dev.platform_data; - struct lp3944_data *data = i2c_get_clientdata(client); - int i; - - for (i = 0; i < pdata->leds_size; i++) - switch (data->leds[i].type) { - case LP3944_LED_TYPE_LED: - case LP3944_LED_TYPE_LED_INVERTED: - led_classdev_unregister(&data->leds[i].ldev); - cancel_work_sync(&data->leds[i].work); - break; - - case LP3944_LED_TYPE_NONE: - default: - break; - } - - kfree(data); - i2c_set_clientdata(client, NULL); - - return 0; -} - -/* lp3944 i2c driver struct */ -static const struct i2c_device_id lp3944_id[] = { - {"lp3944", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, lp3944_id); - -static struct i2c_driver lp3944_driver = { - .driver = { - .name = "lp3944", - }, - .probe = lp3944_probe, - .remove = __devexit_p(lp3944_remove), - .id_table = lp3944_id, -}; - -static int __init lp3944_module_init(void) -{ - return i2c_add_driver(&lp3944_driver); -} - -static void __exit lp3944_module_exit(void) -{ - i2c_del_driver(&lp3944_driver); -} - -module_init(lp3944_module_init); -module_exit(lp3944_module_exit); - -MODULE_AUTHOR("Antonio Ospite "); -MODULE_DESCRIPTION("LP3944 Fun Light Chip"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-pca9532.c b/trunk/drivers/leds/leds-pca9532.c index dba8921240f2..3937244fdcab 100644 --- a/trunk/drivers/leds/leds-pca9532.c +++ b/trunk/drivers/leds/leds-pca9532.c @@ -35,7 +35,7 @@ struct pca9532_data { struct pca9532_led leds[16]; struct mutex update_lock; struct input_dev *idev; - struct work_struct work; + struct work_struct work; u8 pwm[2]; u8 psc[2]; }; @@ -87,14 +87,14 @@ static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink, if (b > 0xFF) return -EINVAL; data->pwm[pwm] = b; - data->psc[pwm] = blink; - return 0; + data->psc[pwm] = blink; + return 0; } static int pca9532_setpwm(struct i2c_client *client, int pwm) { - struct pca9532_data *data = i2c_get_clientdata(client); - mutex_lock(&data->update_lock); + struct pca9532_data *data = i2c_get_clientdata(client); + mutex_lock(&data->update_lock); i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm), data->pwm[pwm]); i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm), @@ -132,11 +132,11 @@ static void pca9532_set_brightness(struct led_classdev *led_cdev, led->state = PCA9532_ON; else { led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ - err = pca9532_calcpwm(led->client, 0, 0, value); + err = pca9532_calcpwm(led->client, 0, 0, value); if (err) return; /* XXX: led api doesn't allow error code? */ } - schedule_work(&led->work); + schedule_work(&led->work); } static int pca9532_set_blink(struct led_classdev *led_cdev, @@ -145,7 +145,7 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, struct pca9532_led *led = ldev_to_led(led_cdev); struct i2c_client *client = led->client; int psc; - int err = 0; + int err = 0; if (*delay_on == 0 && *delay_off == 0) { /* led subsystem ask us for a blink rate */ @@ -157,11 +157,11 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, /* Thecus specific: only use PSC/PWM 0 */ psc = (*delay_on * 152-1)/1000; - err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); - if (err) - return err; - schedule_work(&led->work); - return 0; + err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); + if (err) + return err; + schedule_work(&led->work); + return 0; } static int pca9532_event(struct input_dev *dev, unsigned int type, @@ -178,15 +178,15 @@ static int pca9532_event(struct input_dev *dev, unsigned int type, else data->pwm[1] = 0; - schedule_work(&data->work); + schedule_work(&data->work); - return 0; + return 0; } static void pca9532_input_work(struct work_struct *work) { - struct pca9532_data *data; - data = container_of(work, struct pca9532_data, work); + struct pca9532_data *data; + data = container_of(work, struct pca9532_data, work); mutex_lock(&data->update_lock); i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1), data->pwm[1]); @@ -195,11 +195,11 @@ static void pca9532_input_work(struct work_struct *work) static void pca9532_led_work(struct work_struct *work) { - struct pca9532_led *led; - led = container_of(work, struct pca9532_led, work); - if (led->state == PCA9532_PWM0) - pca9532_setpwm(led->client, 0); - pca9532_setled(led); + struct pca9532_led *led; + led = container_of(work, struct pca9532_led, work); + if (led->state == PCA9532_PWM0) + pca9532_setpwm(led->client, 0); + pca9532_setled(led); } static int pca9532_configure(struct i2c_client *client, @@ -232,7 +232,7 @@ static int pca9532_configure(struct i2c_client *client, led->ldev.brightness = LED_OFF; led->ldev.brightness_set = pca9532_set_brightness; led->ldev.blink_set = pca9532_set_blink; - INIT_WORK(&led->work, pca9532_led_work); + INIT_WORK(&led->work, pca9532_led_work); err = led_classdev_register(&client->dev, &led->ldev); if (err < 0) { dev_err(&client->dev, @@ -262,11 +262,11 @@ static int pca9532_configure(struct i2c_client *client, BIT_MASK(SND_TONE); data->idev->event = pca9532_event; input_set_drvdata(data->idev, data); - INIT_WORK(&data->work, pca9532_input_work); + INIT_WORK(&data->work, pca9532_input_work); err = input_register_device(data->idev); if (err) { input_free_device(data->idev); - cancel_work_sync(&data->work); + cancel_work_sync(&data->work); data->idev = NULL; goto exit; } @@ -283,13 +283,13 @@ static int pca9532_configure(struct i2c_client *client, break; case PCA9532_TYPE_LED: led_classdev_unregister(&data->leds[i].ldev); - cancel_work_sync(&data->leds[i].work); + cancel_work_sync(&data->leds[i].work); break; case PCA9532_TYPE_N2100_BEEP: if (data->idev != NULL) { input_unregister_device(data->idev); input_free_device(data->idev); - cancel_work_sync(&data->work); + cancel_work_sync(&data->work); data->idev = NULL; } break; @@ -340,13 +340,13 @@ static int pca9532_remove(struct i2c_client *client) break; case PCA9532_TYPE_LED: led_classdev_unregister(&data->leds[i].ldev); - cancel_work_sync(&data->leds[i].work); + cancel_work_sync(&data->leds[i].work); break; case PCA9532_TYPE_N2100_BEEP: if (data->idev != NULL) { input_unregister_device(data->idev); input_free_device(data->idev); - cancel_work_sync(&data->work); + cancel_work_sync(&data->work); data->idev = NULL; } break; diff --git a/trunk/drivers/lguest/lg.h b/trunk/drivers/lguest/lg.h index 9c3138265f8e..d4e8979735cb 100644 --- a/trunk/drivers/lguest/lg.h +++ b/trunk/drivers/lguest/lg.h @@ -82,7 +82,7 @@ struct lg_cpu { struct lg_eventfd { unsigned long addr; - struct eventfd_ctx *event; + struct file *event; }; struct lg_eventfd_map { diff --git a/trunk/drivers/lguest/lguest_user.c b/trunk/drivers/lguest/lguest_user.c index 9f9a2953b383..32e297121058 100644 --- a/trunk/drivers/lguest/lguest_user.c +++ b/trunk/drivers/lguest/lguest_user.c @@ -50,7 +50,7 @@ static int add_eventfd(struct lguest *lg, unsigned long addr, int fd) /* Now append new entry. */ new->map[new->num].addr = addr; - new->map[new->num].event = eventfd_ctx_fdget(fd); + new->map[new->num].event = eventfd_fget(fd); if (IS_ERR(new->map[new->num].event)) { kfree(new); return PTR_ERR(new->map[new->num].event); @@ -357,7 +357,7 @@ static int close(struct inode *inode, struct file *file) /* Release any eventfds they registered. */ for (i = 0; i < lg->eventfds->num; i++) - eventfd_ctx_put(lg->eventfds->map[i].event); + fput(lg->eventfds->map[i].event); kfree(lg->eventfds); /* If lg->dead doesn't contain an error code it will be NULL or a diff --git a/trunk/drivers/macintosh/macio_asic.c b/trunk/drivers/macintosh/macio_asic.c index a0f68386c12f..6e149f4a1fff 100644 --- a/trunk/drivers/macintosh/macio_asic.c +++ b/trunk/drivers/macintosh/macio_asic.c @@ -378,17 +378,6 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, dev->ofdev.dev.bus = &macio_bus_type; dev->ofdev.dev.release = macio_release_dev; -#ifdef CONFIG_PCI - /* Set the DMA ops to the ones from the PCI device, this could be - * fishy if we didn't know that on PowerMac it's always direct ops - * or iommu ops that will work fine - */ - dev->ofdev.dev.archdata.dma_ops = - chip->lbus.pdev->dev.archdata.dma_ops; - dev->ofdev.dev.archdata.dma_data = - chip->lbus.pdev->dev.archdata.dma_data; -#endif /* CONFIG_PCI */ - #ifdef DEBUG printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n", dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj); diff --git a/trunk/drivers/md/Kconfig b/trunk/drivers/md/Kconfig index 020f9573fd82..36e0675be9f7 100644 --- a/trunk/drivers/md/Kconfig +++ b/trunk/drivers/md/Kconfig @@ -231,17 +231,6 @@ config DM_MIRROR Allow volume managers to mirror logical volumes, also needed for live data migration tools such as 'pvmove'. -config DM_LOG_USERSPACE - tristate "Mirror userspace logging (EXPERIMENTAL)" - depends on DM_MIRROR && EXPERIMENTAL && NET - select CONNECTOR - ---help--- - The userspace logging module provides a mechanism for - relaying the dm-dirty-log API to userspace. Log designs - which are more suited to userspace implementation (e.g. - shared storage logs) or experimental logs can be implemented - by leveraging this framework. - config DM_ZERO tristate "Zero target" depends on BLK_DEV_DM @@ -260,25 +249,6 @@ config DM_MULTIPATH ---help--- Allow volume managers to support multipath hardware. -config DM_MULTIPATH_QL - tristate "I/O Path Selector based on the number of in-flight I/Os" - depends on DM_MULTIPATH - ---help--- - This path selector is a dynamic load balancer which selects - the path with the least number of in-flight I/Os. - - If unsure, say N. - -config DM_MULTIPATH_ST - tristate "I/O Path Selector based on the service time" - depends on DM_MULTIPATH - ---help--- - This path selector is a dynamic load balancer which selects - the path expected to complete the incoming I/O in the shortest - time. - - If unsure, say N. - config DM_DELAY tristate "I/O delaying target (EXPERIMENTAL)" depends on BLK_DEV_DM && EXPERIMENTAL diff --git a/trunk/drivers/md/Makefile b/trunk/drivers/md/Makefile index 1dc4185bd781..45cc5951d928 100644 --- a/trunk/drivers/md/Makefile +++ b/trunk/drivers/md/Makefile @@ -8,8 +8,6 @@ dm-multipath-y += dm-path-selector.o dm-mpath.o dm-snapshot-y += dm-snap.o dm-exception-store.o dm-snap-transient.o \ dm-snap-persistent.o dm-mirror-y += dm-raid1.o -dm-log-userspace-y \ - += dm-log-userspace-base.o dm-log-userspace-transfer.o md-mod-y += md.o bitmap.o raid456-y += raid5.o raid6_pq-y += raid6algos.o raid6recov.o raid6tables.o \ @@ -38,11 +36,8 @@ obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o obj-$(CONFIG_DM_CRYPT) += dm-crypt.o obj-$(CONFIG_DM_DELAY) += dm-delay.o obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o -obj-$(CONFIG_DM_MULTIPATH_QL) += dm-queue-length.o -obj-$(CONFIG_DM_MULTIPATH_ST) += dm-service-time.o obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o obj-$(CONFIG_DM_MIRROR) += dm-mirror.o dm-log.o dm-region-hash.o -obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o obj-$(CONFIG_DM_ZERO) += dm-zero.o quiet_cmd_unroll = UNROLL $@ diff --git a/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index 9933eb861c71..53394e863c74 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/drivers/md/dm-crypt.c @@ -1132,7 +1132,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad_crypt_queue; } - ti->num_flush_requests = 1; ti->private = cc; return 0; @@ -1190,13 +1189,6 @@ static int crypt_map(struct dm_target *ti, struct bio *bio, union map_info *map_context) { struct dm_crypt_io *io; - struct crypt_config *cc; - - if (unlikely(bio_empty_barrier(bio))) { - cc = ti->private; - bio->bi_bdev = cc->dev->bdev; - return DM_MAPIO_REMAPPED; - } io = crypt_io_alloc(ti, bio, bio->bi_sector - ti->begin); @@ -1313,17 +1305,9 @@ static int crypt_merge(struct dm_target *ti, struct bvec_merge_data *bvm, return min(max_size, q->merge_bvec_fn(q, bvm, biovec)); } -static int crypt_iterate_devices(struct dm_target *ti, - iterate_devices_callout_fn fn, void *data) -{ - struct crypt_config *cc = ti->private; - - return fn(ti, cc->dev, cc->start, data); -} - static struct target_type crypt_target = { .name = "crypt", - .version = {1, 7, 0}, + .version= {1, 6, 0}, .module = THIS_MODULE, .ctr = crypt_ctr, .dtr = crypt_dtr, @@ -1334,7 +1318,6 @@ static struct target_type crypt_target = { .resume = crypt_resume, .message = crypt_message, .merge = crypt_merge, - .iterate_devices = crypt_iterate_devices, }; static int __init dm_crypt_init(void) diff --git a/trunk/drivers/md/dm-delay.c b/trunk/drivers/md/dm-delay.c index 4e5b843cd4d7..559dbb52bc85 100644 --- a/trunk/drivers/md/dm-delay.c +++ b/trunk/drivers/md/dm-delay.c @@ -197,7 +197,6 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) mutex_init(&dc->timer_lock); atomic_set(&dc->may_delay, 1); - ti->num_flush_requests = 1; ti->private = dc; return 0; @@ -279,9 +278,8 @@ static int delay_map(struct dm_target *ti, struct bio *bio, if ((bio_data_dir(bio) == WRITE) && (dc->dev_write)) { bio->bi_bdev = dc->dev_write->bdev; - if (bio_sectors(bio)) - bio->bi_sector = dc->start_write + - (bio->bi_sector - ti->begin); + bio->bi_sector = dc->start_write + + (bio->bi_sector - ti->begin); return delay_bio(dc, dc->write_delay, bio); } @@ -318,26 +316,9 @@ static int delay_status(struct dm_target *ti, status_type_t type, return 0; } -static int delay_iterate_devices(struct dm_target *ti, - iterate_devices_callout_fn fn, void *data) -{ - struct delay_c *dc = ti->private; - int ret = 0; - - ret = fn(ti, dc->dev_read, dc->start_read, data); - if (ret) - goto out; - - if (dc->dev_write) - ret = fn(ti, dc->dev_write, dc->start_write, data); - -out: - return ret; -} - static struct target_type delay_target = { .name = "delay", - .version = {1, 1, 0}, + .version = {1, 0, 2}, .module = THIS_MODULE, .ctr = delay_ctr, .dtr = delay_dtr, @@ -345,7 +326,6 @@ static struct target_type delay_target = { .presuspend = delay_presuspend, .resume = delay_resume, .status = delay_status, - .iterate_devices = delay_iterate_devices, }; static int __init dm_delay_init(void) diff --git a/trunk/drivers/md/dm-exception-store.c b/trunk/drivers/md/dm-exception-store.c index 3710ff88fc10..75d8081a9041 100644 --- a/trunk/drivers/md/dm-exception-store.c +++ b/trunk/drivers/md/dm-exception-store.c @@ -195,7 +195,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, struct dm_exception_store **store) { int r = 0; - struct dm_exception_store_type *type = NULL; + struct dm_exception_store_type *type; struct dm_exception_store *tmp_store; char persistent; @@ -211,15 +211,12 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, } persistent = toupper(*argv[1]); - if (persistent == 'P') - type = get_type("P"); - else if (persistent == 'N') - type = get_type("N"); - else { + if (persistent != 'P' && persistent != 'N') { ti->error = "Persistent flag is not P or N"; return -EINVAL; } + type = get_type(argv[1]); if (!type) { ti->error = "Exception store type not recognised"; r = -EINVAL; diff --git a/trunk/drivers/md/dm-exception-store.h b/trunk/drivers/md/dm-exception-store.h index 2442c8c07898..c92701dc5001 100644 --- a/trunk/drivers/md/dm-exception-store.h +++ b/trunk/drivers/md/dm-exception-store.h @@ -156,7 +156,7 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) */ static inline sector_t get_dev_size(struct block_device *bdev) { - return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; + return bdev->bd_inode->i_size >> SECTOR_SHIFT; } static inline chunk_t sector_to_chunk(struct dm_exception_store *store, diff --git a/trunk/drivers/md/dm-io.c b/trunk/drivers/md/dm-io.c index 3a2e6a2f8bdd..e73aabd61cd7 100644 --- a/trunk/drivers/md/dm-io.c +++ b/trunk/drivers/md/dm-io.c @@ -22,7 +22,6 @@ struct dm_io_client { /* FIXME: can we shrink this ? */ struct io { unsigned long error_bits; - unsigned long eopnotsupp_bits; atomic_t count; struct task_struct *sleeper; struct dm_io_client *client; @@ -108,11 +107,8 @@ static inline unsigned bio_get_region(struct bio *bio) *---------------------------------------------------------------*/ static void dec_count(struct io *io, unsigned int region, int error) { - if (error) { + if (error) set_bit(region, &io->error_bits); - if (error == -EOPNOTSUPP) - set_bit(region, &io->eopnotsupp_bits); - } if (atomic_dec_and_test(&io->count)) { if (io->sleeper) @@ -364,9 +360,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, return -EIO; } -retry: io.error_bits = 0; - io.eopnotsupp_bits = 0; atomic_set(&io.count, 1); /* see dispatch_io() */ io.sleeper = current; io.client = client; @@ -383,11 +377,6 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, } set_current_state(TASK_RUNNING); - if (io.eopnotsupp_bits && (rw & (1 << BIO_RW_BARRIER))) { - rw &= ~(1 << BIO_RW_BARRIER); - goto retry; - } - if (error_bits) *error_bits = io.error_bits; @@ -408,7 +397,6 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, io = mempool_alloc(client->pool, GFP_NOIO); io->error_bits = 0; - io->eopnotsupp_bits = 0; atomic_set(&io->count, 1); /* see dispatch_io() */ io->sleeper = NULL; io->client = client; diff --git a/trunk/drivers/md/dm-ioctl.c b/trunk/drivers/md/dm-ioctl.c index 7f77f18fcafa..1128d3fba797 100644 --- a/trunk/drivers/md/dm-ioctl.c +++ b/trunk/drivers/md/dm-ioctl.c @@ -276,7 +276,7 @@ static void dm_hash_remove_all(int keep_open_devices) up_write(&_hash_lock); } -static int dm_hash_rename(uint32_t cookie, const char *old, const char *new) +static int dm_hash_rename(const char *old, const char *new) { char *new_name, *old_name; struct hash_cell *hc; @@ -333,7 +333,7 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new) dm_table_put(table); } - dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie); + dm_kobject_uevent(hc->md); dm_put(hc->md); up_write(&_hash_lock); @@ -680,9 +680,6 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size) __hash_remove(hc); up_write(&_hash_lock); - - dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr); - dm_put(md); param->data_size = 0; return 0; @@ -718,7 +715,7 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size) return r; param->data_size = 0; - return dm_hash_rename(param->event_nr, param->name, new_name); + return dm_hash_rename(param->name, new_name); } static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) @@ -845,11 +842,8 @@ static int do_resume(struct dm_ioctl *param) if (dm_suspended(md)) r = dm_resume(md); - - if (!r) { - dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr); + if (!r) r = __dev_status(md, param); - } dm_put(md); return r; @@ -1050,12 +1044,6 @@ static int populate_table(struct dm_table *table, next = spec->next; } - r = dm_table_set_type(table); - if (r) { - DMWARN("unable to set table type"); - return r; - } - return dm_table_complete(table); } @@ -1101,13 +1089,6 @@ static int table_load(struct dm_ioctl *param, size_t param_size) goto out; } - r = dm_table_alloc_md_mempools(t); - if (r) { - DMWARN("unable to allocate mempools for this table"); - dm_table_destroy(t); - goto out; - } - down_write(&_hash_lock); hc = dm_get_mdptr(md); if (!hc || hc->md != md) { diff --git a/trunk/drivers/md/dm-linear.c b/trunk/drivers/md/dm-linear.c index 9184b6deb868..79fb53e51c70 100644 --- a/trunk/drivers/md/dm-linear.c +++ b/trunk/drivers/md/dm-linear.c @@ -53,7 +53,6 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad; } - ti->num_flush_requests = 1; ti->private = lc; return 0; @@ -82,8 +81,7 @@ static void linear_map_bio(struct dm_target *ti, struct bio *bio) struct linear_c *lc = ti->private; bio->bi_bdev = lc->dev->bdev; - if (bio_sectors(bio)) - bio->bi_sector = linear_map_sector(ti, bio->bi_sector); + bio->bi_sector = linear_map_sector(ti, bio->bi_sector); } static int linear_map(struct dm_target *ti, struct bio *bio, @@ -134,17 +132,9 @@ static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm, return min(max_size, q->merge_bvec_fn(q, bvm, biovec)); } -static int linear_iterate_devices(struct dm_target *ti, - iterate_devices_callout_fn fn, void *data) -{ - struct linear_c *lc = ti->private; - - return fn(ti, lc->dev, lc->start, data); -} - static struct target_type linear_target = { .name = "linear", - .version = {1, 1, 0}, + .version= {1, 0, 3}, .module = THIS_MODULE, .ctr = linear_ctr, .dtr = linear_dtr, @@ -152,7 +142,6 @@ static struct target_type linear_target = { .status = linear_status, .ioctl = linear_ioctl, .merge = linear_merge, - .iterate_devices = linear_iterate_devices, }; int __init dm_linear_init(void) diff --git a/trunk/drivers/md/dm-log-userspace-base.c b/trunk/drivers/md/dm-log-userspace-base.c deleted file mode 100644 index e69b96560997..000000000000 --- a/trunk/drivers/md/dm-log-userspace-base.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * Copyright (C) 2006-2009 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#include -#include -#include -#include - -#include "dm-log-userspace-transfer.h" - -struct flush_entry { - int type; - region_t region; - struct list_head list; -}; - -struct log_c { - struct dm_target *ti; - uint32_t region_size; - region_t region_count; - char uuid[DM_UUID_LEN]; - - char *usr_argv_str; - uint32_t usr_argc; - - /* - * in_sync_hint gets set when doing is_remote_recovering. It - * represents the first region that needs recovery. IOW, the - * first zero bit of sync_bits. This can be useful for to limit - * traffic for calls like is_remote_recovering and get_resync_work, - * but be take care in its use for anything else. - */ - uint64_t in_sync_hint; - - spinlock_t flush_lock; - struct list_head flush_list; /* only for clear and mark requests */ -}; - -static mempool_t *flush_entry_pool; - -static void *flush_entry_alloc(gfp_t gfp_mask, void *pool_data) -{ - return kmalloc(sizeof(struct flush_entry), gfp_mask); -} - -static void flush_entry_free(void *element, void *pool_data) -{ - kfree(element); -} - -static int userspace_do_request(struct log_c *lc, const char *uuid, - int request_type, char *data, size_t data_size, - char *rdata, size_t *rdata_size) -{ - int r; - - /* - * If the server isn't there, -ESRCH is returned, - * and we must keep trying until the server is - * restored. - */ -retry: - r = dm_consult_userspace(uuid, request_type, data, - data_size, rdata, rdata_size); - - if (r != -ESRCH) - return r; - - DMERR(" Userspace log server not found."); - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(2*HZ); - DMWARN("Attempting to contact userspace log server..."); - r = dm_consult_userspace(uuid, DM_ULOG_CTR, lc->usr_argv_str, - strlen(lc->usr_argv_str) + 1, - NULL, NULL); - if (!r) - break; - } - DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete"); - r = dm_consult_userspace(uuid, DM_ULOG_RESUME, NULL, - 0, NULL, NULL); - if (!r) - goto retry; - - DMERR("Error trying to resume userspace log: %d", r); - - return -ESRCH; -} - -static int build_constructor_string(struct dm_target *ti, - unsigned argc, char **argv, - char **ctr_str) -{ - int i, str_size; - char *str = NULL; - - *ctr_str = NULL; - - for (i = 0, str_size = 0; i < argc; i++) - str_size += strlen(argv[i]) + 1; /* +1 for space between args */ - - str_size += 20; /* Max number of chars in a printed u64 number */ - - str = kzalloc(str_size, GFP_KERNEL); - if (!str) { - DMWARN("Unable to allocate memory for constructor string"); - return -ENOMEM; - } - - for (i = 0, str_size = 0; i < argc; i++) - str_size += sprintf(str + str_size, "%s ", argv[i]); - str_size += sprintf(str + str_size, "%llu", - (unsigned long long)ti->len); - - *ctr_str = str; - return str_size; -} - -/* - * userspace_ctr - * - * argv contains: - * - * Where 'other args' is the userspace implementation specific log - * arguments. An example might be: - * clustered_disk [[no]sync] - * - * So, this module will strip off the for identification purposes - * when communicating with userspace about a log; but will pass on everything - * else. - */ -static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti, - unsigned argc, char **argv) -{ - int r = 0; - int str_size; - char *ctr_str = NULL; - struct log_c *lc = NULL; - uint64_t rdata; - size_t rdata_size = sizeof(rdata); - - if (argc < 3) { - DMWARN("Too few arguments to userspace dirty log"); - return -EINVAL; - } - - lc = kmalloc(sizeof(*lc), GFP_KERNEL); - if (!lc) { - DMWARN("Unable to allocate userspace log context."); - return -ENOMEM; - } - - lc->ti = ti; - - if (strlen(argv[0]) > (DM_UUID_LEN - 1)) { - DMWARN("UUID argument too long."); - kfree(lc); - return -EINVAL; - } - - strncpy(lc->uuid, argv[0], DM_UUID_LEN); - spin_lock_init(&lc->flush_lock); - INIT_LIST_HEAD(&lc->flush_list); - - str_size = build_constructor_string(ti, argc - 1, argv + 1, &ctr_str); - if (str_size < 0) { - kfree(lc); - return str_size; - } - - /* Send table string */ - r = dm_consult_userspace(lc->uuid, DM_ULOG_CTR, - ctr_str, str_size, NULL, NULL); - - if (r == -ESRCH) { - DMERR("Userspace log server not found"); - goto out; - } - - /* Since the region size does not change, get it now */ - rdata_size = sizeof(rdata); - r = dm_consult_userspace(lc->uuid, DM_ULOG_GET_REGION_SIZE, - NULL, 0, (char *)&rdata, &rdata_size); - - if (r) { - DMERR("Failed to get region size of dirty log"); - goto out; - } - - lc->region_size = (uint32_t)rdata; - lc->region_count = dm_sector_div_up(ti->len, lc->region_size); - -out: - if (r) { - kfree(lc); - kfree(ctr_str); - } else { - lc->usr_argv_str = ctr_str; - lc->usr_argc = argc; - log->context = lc; - } - - return r; -} - -static void userspace_dtr(struct dm_dirty_log *log) -{ - int r; - struct log_c *lc = log->context; - - r = dm_consult_userspace(lc->uuid, DM_ULOG_DTR, - NULL, 0, - NULL, NULL); - - kfree(lc->usr_argv_str); - kfree(lc); - - return; -} - -static int userspace_presuspend(struct dm_dirty_log *log) -{ - int r; - struct log_c *lc = log->context; - - r = dm_consult_userspace(lc->uuid, DM_ULOG_PRESUSPEND, - NULL, 0, - NULL, NULL); - - return r; -} - -static int userspace_postsuspend(struct dm_dirty_log *log) -{ - int r; - struct log_c *lc = log->context; - - r = dm_consult_userspace(lc->uuid, DM_ULOG_POSTSUSPEND, - NULL, 0, - NULL, NULL); - - return r; -} - -static int userspace_resume(struct dm_dirty_log *log) -{ - int r; - struct log_c *lc = log->context; - - lc->in_sync_hint = 0; - r = dm_consult_userspace(lc->uuid, DM_ULOG_RESUME, - NULL, 0, - NULL, NULL); - - return r; -} - -static uint32_t userspace_get_region_size(struct dm_dirty_log *log) -{ - struct log_c *lc = log->context; - - return lc->region_size; -} - -/* - * userspace_is_clean - * - * Check whether a region is clean. If there is any sort of - * failure when consulting the server, we return not clean. - * - * Returns: 1 if clean, 0 otherwise - */ -static int userspace_is_clean(struct dm_dirty_log *log, region_t region) -{ - int r; - uint64_t region64 = (uint64_t)region; - int64_t is_clean; - size_t rdata_size; - struct log_c *lc = log->context; - - rdata_size = sizeof(is_clean); - r = userspace_do_request(lc, lc->uuid, DM_ULOG_IS_CLEAN, - (char *)®ion64, sizeof(region64), - (char *)&is_clean, &rdata_size); - - return (r) ? 0 : (int)is_clean; -} - -/* - * userspace_in_sync - * - * Check if the region is in-sync. If there is any sort - * of failure when consulting the server, we assume that - * the region is not in sync. - * - * If 'can_block' is set, return immediately - * - * Returns: 1 if in-sync, 0 if not-in-sync, -EWOULDBLOCK - */ -static int userspace_in_sync(struct dm_dirty_log *log, region_t region, - int can_block) -{ - int r; - uint64_t region64 = region; - int64_t in_sync; - size_t rdata_size; - struct log_c *lc = log->context; - - /* - * We can never respond directly - even if in_sync_hint is - * set. This is because another machine could see a device - * failure and mark the region out-of-sync. If we don't go - * to userspace to ask, we might think the region is in-sync - * and allow a read to pick up data that is stale. (This is - * very unlikely if a device actually fails; but it is very - * likely if a connection to one device from one machine fails.) - * - * There still might be a problem if the mirror caches the region - * state as in-sync... but then this call would not be made. So, - * that is a mirror problem. - */ - if (!can_block) - return -EWOULDBLOCK; - - rdata_size = sizeof(in_sync); - r = userspace_do_request(lc, lc->uuid, DM_ULOG_IN_SYNC, - (char *)®ion64, sizeof(region64), - (char *)&in_sync, &rdata_size); - return (r) ? 0 : (int)in_sync; -} - -/* - * userspace_flush - * - * This function is ok to block. - * The flush happens in two stages. First, it sends all - * clear/mark requests that are on the list. Then it - * tells the server to commit them. This gives the - * server a chance to optimise the commit, instead of - * doing it for every request. - * - * Additionally, we could implement another thread that - * sends the requests up to the server - reducing the - * load on flush. Then the flush would have less in - * the list and be responsible for the finishing commit. - * - * Returns: 0 on success, < 0 on failure - */ -static int userspace_flush(struct dm_dirty_log *log) -{ - int r = 0; - unsigned long flags; - struct log_c *lc = log->context; - LIST_HEAD(flush_list); - struct flush_entry *fe, *tmp_fe; - - spin_lock_irqsave(&lc->flush_lock, flags); - list_splice_init(&lc->flush_list, &flush_list); - spin_unlock_irqrestore(&lc->flush_lock, flags); - - if (list_empty(&flush_list)) - return 0; - - /* - * FIXME: Count up requests, group request types, - * allocate memory to stick all requests in and - * send to server in one go. Failing the allocation, - * do it one by one. - */ - - list_for_each_entry(fe, &flush_list, list) { - r = userspace_do_request(lc, lc->uuid, fe->type, - (char *)&fe->region, - sizeof(fe->region), - NULL, NULL); - if (r) - goto fail; - } - - r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH, - NULL, 0, NULL, NULL); - -fail: - /* - * We can safely remove these entries, even if failure. - * Calling code will receive an error and will know that - * the log facility has failed. - */ - list_for_each_entry_safe(fe, tmp_fe, &flush_list, list) { - list_del(&fe->list); - mempool_free(fe, flush_entry_pool); - } - - if (r) - dm_table_event(lc->ti->table); - - return r; -} - -/* - * userspace_mark_region - * - * This function should avoid blocking unless absolutely required. - * (Memory allocation is valid for blocking.) - */ -static void userspace_mark_region(struct dm_dirty_log *log, region_t region) -{ - unsigned long flags; - struct log_c *lc = log->context; - struct flush_entry *fe; - - /* Wait for an allocation, but _never_ fail */ - fe = mempool_alloc(flush_entry_pool, GFP_NOIO); - BUG_ON(!fe); - - spin_lock_irqsave(&lc->flush_lock, flags); - fe->type = DM_ULOG_MARK_REGION; - fe->region = region; - list_add(&fe->list, &lc->flush_list); - spin_unlock_irqrestore(&lc->flush_lock, flags); - - return; -} - -/* - * userspace_clear_region - * - * This function must not block. - * So, the alloc can't block. In the worst case, it is ok to - * fail. It would simply mean we can't clear the region. - * Does nothing to current sync context, but does mean - * the region will be re-sync'ed on a reload of the mirror - * even though it is in-sync. - */ -static void userspace_clear_region(struct dm_dirty_log *log, region_t region) -{ - unsigned long flags; - struct log_c *lc = log->context; - struct flush_entry *fe; - - /* - * If we fail to allocate, we skip the clearing of - * the region. This doesn't hurt us in any way, except - * to cause the region to be resync'ed when the - * device is activated next time. - */ - fe = mempool_alloc(flush_entry_pool, GFP_ATOMIC); - if (!fe) { - DMERR("Failed to allocate memory to clear region."); - return; - } - - spin_lock_irqsave(&lc->flush_lock, flags); - fe->type = DM_ULOG_CLEAR_REGION; - fe->region = region; - list_add(&fe->list, &lc->flush_list); - spin_unlock_irqrestore(&lc->flush_lock, flags); - - return; -} - -/* - * userspace_get_resync_work - * - * Get a region that needs recovery. It is valid to return - * an error for this function. - * - * Returns: 1 if region filled, 0 if no work, <0 on error - */ -static int userspace_get_resync_work(struct dm_dirty_log *log, region_t *region) -{ - int r; - size_t rdata_size; - struct log_c *lc = log->context; - struct { - int64_t i; /* 64-bit for mix arch compatibility */ - region_t r; - } pkg; - - if (lc->in_sync_hint >= lc->region_count) - return 0; - - rdata_size = sizeof(pkg); - r = userspace_do_request(lc, lc->uuid, DM_ULOG_GET_RESYNC_WORK, - NULL, 0, - (char *)&pkg, &rdata_size); - - *region = pkg.r; - return (r) ? r : (int)pkg.i; -} - -/* - * userspace_set_region_sync - * - * Set the sync status of a given region. This function - * must not fail. - */ -static void userspace_set_region_sync(struct dm_dirty_log *log, - region_t region, int in_sync) -{ - int r; - struct log_c *lc = log->context; - struct { - region_t r; - int64_t i; - } pkg; - - pkg.r = region; - pkg.i = (int64_t)in_sync; - - r = userspace_do_request(lc, lc->uuid, DM_ULOG_SET_REGION_SYNC, - (char *)&pkg, sizeof(pkg), - NULL, NULL); - - /* - * It would be nice to be able to report failures. - * However, it is easy emough to detect and resolve. - */ - return; -} - -/* - * userspace_get_sync_count - * - * If there is any sort of failure when consulting the server, - * we assume that the sync count is zero. - * - * Returns: sync count on success, 0 on failure - */ -static region_t userspace_get_sync_count(struct dm_dirty_log *log) -{ - int r; - size_t rdata_size; - uint64_t sync_count; - struct log_c *lc = log->context; - - rdata_size = sizeof(sync_count); - r = userspace_do_request(lc, lc->uuid, DM_ULOG_GET_SYNC_COUNT, - NULL, 0, - (char *)&sync_count, &rdata_size); - - if (r) - return 0; - - if (sync_count >= lc->region_count) - lc->in_sync_hint = lc->region_count; - - return (region_t)sync_count; -} - -/* - * userspace_status - * - * Returns: amount of space consumed - */ -static int userspace_status(struct dm_dirty_log *log, status_type_t status_type, - char *result, unsigned maxlen) -{ - int r = 0; - size_t sz = (size_t)maxlen; - struct log_c *lc = log->context; - - switch (status_type) { - case STATUSTYPE_INFO: - r = userspace_do_request(lc, lc->uuid, DM_ULOG_STATUS_INFO, - NULL, 0, - result, &sz); - - if (r) { - sz = 0; - DMEMIT("%s 1 COM_FAILURE", log->type->name); - } - break; - case STATUSTYPE_TABLE: - sz = 0; - DMEMIT("%s %u %s %s", log->type->name, lc->usr_argc + 1, - lc->uuid, lc->usr_argv_str); - break; - } - return (r) ? 0 : (int)sz; -} - -/* - * userspace_is_remote_recovering - * - * Returns: 1 if region recovering, 0 otherwise - */ -static int userspace_is_remote_recovering(struct dm_dirty_log *log, - region_t region) -{ - int r; - uint64_t region64 = region; - struct log_c *lc = log->context; - static unsigned long long limit; - struct { - int64_t is_recovering; - uint64_t in_sync_hint; - } pkg; - size_t rdata_size = sizeof(pkg); - - /* - * Once the mirror has been reported to be in-sync, - * it will never again ask for recovery work. So, - * we can safely say there is not a remote machine - * recovering if the device is in-sync. (in_sync_hint - * must be reset at resume time.) - */ - if (region < lc->in_sync_hint) - return 0; - else if (jiffies < limit) - return 1; - - limit = jiffies + (HZ / 4); - r = userspace_do_request(lc, lc->uuid, DM_ULOG_IS_REMOTE_RECOVERING, - (char *)®ion64, sizeof(region64), - (char *)&pkg, &rdata_size); - if (r) - return 1; - - lc->in_sync_hint = pkg.in_sync_hint; - - return (int)pkg.is_recovering; -} - -static struct dm_dirty_log_type _userspace_type = { - .name = "userspace", - .module = THIS_MODULE, - .ctr = userspace_ctr, - .dtr = userspace_dtr, - .presuspend = userspace_presuspend, - .postsuspend = userspace_postsuspend, - .resume = userspace_resume, - .get_region_size = userspace_get_region_size, - .is_clean = userspace_is_clean, - .in_sync = userspace_in_sync, - .flush = userspace_flush, - .mark_region = userspace_mark_region, - .clear_region = userspace_clear_region, - .get_resync_work = userspace_get_resync_work, - .set_region_sync = userspace_set_region_sync, - .get_sync_count = userspace_get_sync_count, - .status = userspace_status, - .is_remote_recovering = userspace_is_remote_recovering, -}; - -static int __init userspace_dirty_log_init(void) -{ - int r = 0; - - flush_entry_pool = mempool_create(100, flush_entry_alloc, - flush_entry_free, NULL); - - if (!flush_entry_pool) { - DMWARN("Unable to create flush_entry_pool: No memory."); - return -ENOMEM; - } - - r = dm_ulog_tfr_init(); - if (r) { - DMWARN("Unable to initialize userspace log communications"); - mempool_destroy(flush_entry_pool); - return r; - } - - r = dm_dirty_log_type_register(&_userspace_type); - if (r) { - DMWARN("Couldn't register userspace dirty log type"); - dm_ulog_tfr_exit(); - mempool_destroy(flush_entry_pool); - return r; - } - - DMINFO("version 1.0.0 loaded"); - return 0; -} - -static void __exit userspace_dirty_log_exit(void) -{ - dm_dirty_log_type_unregister(&_userspace_type); - dm_ulog_tfr_exit(); - mempool_destroy(flush_entry_pool); - - DMINFO("version 1.0.0 unloaded"); - return; -} - -module_init(userspace_dirty_log_init); -module_exit(userspace_dirty_log_exit); - -MODULE_DESCRIPTION(DM_NAME " userspace dirty log link"); -MODULE_AUTHOR("Jonathan Brassow "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/md/dm-log-userspace-transfer.c b/trunk/drivers/md/dm-log-userspace-transfer.c deleted file mode 100644 index 0ca1ee768a1f..000000000000 --- a/trunk/drivers/md/dm-log-userspace-transfer.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2006-2009 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "dm-log-userspace-transfer.h" - -static uint32_t dm_ulog_seq; - -/* - * Netlink/Connector is an unreliable protocol. How long should - * we wait for a response before assuming it was lost and retrying? - * (If we do receive a response after this time, it will be discarded - * and the response to the resent request will be waited for. - */ -#define DM_ULOG_RETRY_TIMEOUT (15 * HZ) - -/* - * Pre-allocated space for speed - */ -#define DM_ULOG_PREALLOCED_SIZE 512 -static struct cn_msg *prealloced_cn_msg; -static struct dm_ulog_request *prealloced_ulog_tfr; - -static struct cb_id ulog_cn_id = { - .idx = CN_IDX_DM, - .val = CN_VAL_DM_USERSPACE_LOG -}; - -static DEFINE_MUTEX(dm_ulog_lock); - -struct receiving_pkg { - struct list_head list; - struct completion complete; - - uint32_t seq; - - int error; - size_t *data_size; - char *data; -}; - -static DEFINE_SPINLOCK(receiving_list_lock); -static struct list_head receiving_list; - -static int dm_ulog_sendto_server(struct dm_ulog_request *tfr) -{ - int r; - struct cn_msg *msg = prealloced_cn_msg; - - memset(msg, 0, sizeof(struct cn_msg)); - - msg->id.idx = ulog_cn_id.idx; - msg->id.val = ulog_cn_id.val; - msg->ack = 0; - msg->seq = tfr->seq; - msg->len = sizeof(struct dm_ulog_request) + tfr->data_size; - - r = cn_netlink_send(msg, 0, gfp_any()); - - return r; -} - -/* - * Parameters for this function can be either msg or tfr, but not - * both. This function fills in the reply for a waiting request. - * If just msg is given, then the reply is simply an ACK from userspace - * that the request was received. - * - * Returns: 0 on success, -ENOENT on failure - */ -static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr) -{ - uint32_t rtn_seq = (msg) ? msg->seq : (tfr) ? tfr->seq : 0; - struct receiving_pkg *pkg; - - /* - * The 'receiving_pkg' entries in this list are statically - * allocated on the stack in 'dm_consult_userspace'. - * Each process that is waiting for a reply from the user - * space server will have an entry in this list. - * - * We are safe to do it this way because the stack space - * is unique to each process, but still addressable by - * other processes. - */ - list_for_each_entry(pkg, &receiving_list, list) { - if (rtn_seq != pkg->seq) - continue; - - if (msg) { - pkg->error = -msg->ack; - /* - * If we are trying again, we will need to know our - * storage capacity. Otherwise, along with the - * error code, we make explicit that we have no data. - */ - if (pkg->error != -EAGAIN) - *(pkg->data_size) = 0; - } else if (tfr->data_size > *(pkg->data_size)) { - DMERR("Insufficient space to receive package [%u] " - "(%u vs %lu)", tfr->request_type, - tfr->data_size, *(pkg->data_size)); - - *(pkg->data_size) = 0; - pkg->error = -ENOSPC; - } else { - pkg->error = tfr->error; - memcpy(pkg->data, tfr->data, tfr->data_size); - *(pkg->data_size) = tfr->data_size; - } - complete(&pkg->complete); - return 0; - } - - return -ENOENT; -} - -/* - * This is the connector callback that delivers data - * that was sent from userspace. - */ -static void cn_ulog_callback(void *data) -{ - struct cn_msg *msg = (struct cn_msg *)data; - struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1); - - spin_lock(&receiving_list_lock); - if (msg->len == 0) - fill_pkg(msg, NULL); - else if (msg->len < sizeof(*tfr)) - DMERR("Incomplete message received (expected %u, got %u): [%u]", - (unsigned)sizeof(*tfr), msg->len, msg->seq); - else - fill_pkg(NULL, tfr); - spin_unlock(&receiving_list_lock); -} - -/** - * dm_consult_userspace - * @uuid: log's uuid (must be DM_UUID_LEN in size) - * @request_type: found in include/linux/dm-log-userspace.h - * @data: data to tx to the server - * @data_size: size of data in bytes - * @rdata: place to put return data from server - * @rdata_size: value-result (amount of space given/amount of space used) - * - * rdata_size is undefined on failure. - * - * Memory used to communicate with userspace is zero'ed - * before populating to ensure that no unwanted bits leak - * from kernel space to user-space. All userspace log communications - * between kernel and user space go through this function. - * - * Returns: 0 on success, -EXXX on failure - **/ -int dm_consult_userspace(const char *uuid, int request_type, - char *data, size_t data_size, - char *rdata, size_t *rdata_size) -{ - int r = 0; - size_t dummy = 0; - int overhead_size = - sizeof(struct dm_ulog_request *) + sizeof(struct cn_msg); - struct dm_ulog_request *tfr = prealloced_ulog_tfr; - struct receiving_pkg pkg; - - if (data_size > (DM_ULOG_PREALLOCED_SIZE - overhead_size)) { - DMINFO("Size of tfr exceeds preallocated size"); - return -EINVAL; - } - - if (!rdata_size) - rdata_size = &dummy; -resend: - /* - * We serialize the sending of requests so we can - * use the preallocated space. - */ - mutex_lock(&dm_ulog_lock); - - memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size); - memcpy(tfr->uuid, uuid, DM_UUID_LEN); - tfr->seq = dm_ulog_seq++; - - /* - * Must be valid request type (all other bits set to - * zero). This reserves other bits for possible future - * use. - */ - tfr->request_type = request_type & DM_ULOG_REQUEST_MASK; - - tfr->data_size = data_size; - if (data && data_size) - memcpy(tfr->data, data, data_size); - - memset(&pkg, 0, sizeof(pkg)); - init_completion(&pkg.complete); - pkg.seq = tfr->seq; - pkg.data_size = rdata_size; - pkg.data = rdata; - spin_lock(&receiving_list_lock); - list_add(&(pkg.list), &receiving_list); - spin_unlock(&receiving_list_lock); - - r = dm_ulog_sendto_server(tfr); - - mutex_unlock(&dm_ulog_lock); - - if (r) { - DMERR("Unable to send log request [%u] to userspace: %d", - request_type, r); - spin_lock(&receiving_list_lock); - list_del_init(&(pkg.list)); - spin_unlock(&receiving_list_lock); - - goto out; - } - - r = wait_for_completion_timeout(&(pkg.complete), DM_ULOG_RETRY_TIMEOUT); - spin_lock(&receiving_list_lock); - list_del_init(&(pkg.list)); - spin_unlock(&receiving_list_lock); - if (!r) { - DMWARN("[%s] Request timed out: [%u/%u] - retrying", - (strlen(uuid) > 8) ? - (uuid + (strlen(uuid) - 8)) : (uuid), - request_type, pkg.seq); - goto resend; - } - - r = pkg.error; - if (r == -EAGAIN) - goto resend; - -out: - return r; -} - -int dm_ulog_tfr_init(void) -{ - int r; - void *prealloced; - - INIT_LIST_HEAD(&receiving_list); - - prealloced = kmalloc(DM_ULOG_PREALLOCED_SIZE, GFP_KERNEL); - if (!prealloced) - return -ENOMEM; - - prealloced_cn_msg = prealloced; - prealloced_ulog_tfr = prealloced + sizeof(struct cn_msg); - - r = cn_add_callback(&ulog_cn_id, "dmlogusr", cn_ulog_callback); - if (r) { - cn_del_callback(&ulog_cn_id); - return r; - } - - return 0; -} - -void dm_ulog_tfr_exit(void) -{ - cn_del_callback(&ulog_cn_id); - kfree(prealloced_cn_msg); -} diff --git a/trunk/drivers/md/dm-log-userspace-transfer.h b/trunk/drivers/md/dm-log-userspace-transfer.h deleted file mode 100644 index c26d8e4e2710..000000000000 --- a/trunk/drivers/md/dm-log-userspace-transfer.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2006-2009 Red Hat, Inc. - * - * This file is released under the LGPL. - */ - -#ifndef __DM_LOG_USERSPACE_TRANSFER_H__ -#define __DM_LOG_USERSPACE_TRANSFER_H__ - -#define DM_MSG_PREFIX "dm-log-userspace" - -int dm_ulog_tfr_init(void); -void dm_ulog_tfr_exit(void); -int dm_consult_userspace(const char *uuid, int request_type, - char *data, size_t data_size, - char *rdata, size_t *rdata_size); - -#endif /* __DM_LOG_USERSPACE_TRANSFER_H__ */ diff --git a/trunk/drivers/md/dm-log.c b/trunk/drivers/md/dm-log.c index 9443896ede07..6fa8ccf91c70 100644 --- a/trunk/drivers/md/dm-log.c +++ b/trunk/drivers/md/dm-log.c @@ -412,12 +412,11 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, /* * Buffer holds both header and bitset. */ - buf_size = - dm_round_up((LOG_OFFSET << SECTOR_SHIFT) + bitset_size, - bdev_logical_block_size(lc->header_location. - bdev)); + buf_size = dm_round_up((LOG_OFFSET << SECTOR_SHIFT) + + bitset_size, + ti->limits.logical_block_size); - if (buf_size > i_size_read(dev->bdev->bd_inode)) { + if (buf_size > dev->bdev->bd_inode->i_size) { DMWARN("log device %s too small: need %llu bytes", dev->name, (unsigned long long)buf_size); kfree(lc); diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index c70604a20897..6a386ab4f7eb 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -8,6 +8,7 @@ #include #include "dm-path-selector.h" +#include "dm-bio-record.h" #include "dm-uevent.h" #include @@ -34,7 +35,6 @@ struct pgpath { struct dm_path path; struct work_struct deactivate_path; - struct work_struct activate_path; }; #define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path) @@ -64,6 +64,8 @@ struct multipath { spinlock_t lock; const char *hw_handler_name; + struct work_struct activate_path; + struct pgpath *pgpath_to_activate; unsigned nr_priority_groups; struct list_head priority_groups; unsigned pg_init_required; /* pg_init needs calling? */ @@ -82,7 +84,7 @@ struct multipath { unsigned pg_init_count; /* Number of times pg_init called */ struct work_struct process_queued_ios; - struct list_head queued_ios; + struct bio_list queued_ios; unsigned queue_size; struct work_struct trigger_event; @@ -99,7 +101,7 @@ struct multipath { */ struct dm_mpath_io { struct pgpath *pgpath; - size_t nr_bytes; + struct dm_bio_details details; }; typedef int (*action_fn) (struct pgpath *pgpath); @@ -126,7 +128,6 @@ static struct pgpath *alloc_pgpath(void) if (pgpath) { pgpath->is_active = 1; INIT_WORK(&pgpath->deactivate_path, deactivate_path); - INIT_WORK(&pgpath->activate_path, activate_path); } return pgpath; @@ -159,6 +160,7 @@ static struct priority_group *alloc_priority_group(void) static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) { + unsigned long flags; struct pgpath *pgpath, *tmp; struct multipath *m = ti->private; @@ -167,6 +169,10 @@ static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) if (m->hw_handler_name) scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev)); dm_put_device(ti, pgpath->path.dev); + spin_lock_irqsave(&m->lock, flags); + if (m->pgpath_to_activate == pgpath) + m->pgpath_to_activate = NULL; + spin_unlock_irqrestore(&m->lock, flags); free_pgpath(pgpath); } } @@ -192,11 +198,11 @@ static struct multipath *alloc_multipath(struct dm_target *ti) m = kzalloc(sizeof(*m), GFP_KERNEL); if (m) { INIT_LIST_HEAD(&m->priority_groups); - INIT_LIST_HEAD(&m->queued_ios); spin_lock_init(&m->lock); m->queue_io = 1; INIT_WORK(&m->process_queued_ios, process_queued_ios); INIT_WORK(&m->trigger_event, trigger_event); + INIT_WORK(&m->activate_path, activate_path); m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); if (!m->mpio_pool) { kfree(m); @@ -244,12 +250,11 @@ static void __switch_pg(struct multipath *m, struct pgpath *pgpath) m->pg_init_count = 0; } -static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg, - size_t nr_bytes) +static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg) { struct dm_path *path; - path = pg->ps.type->select_path(&pg->ps, &m->repeat_count, nr_bytes); + path = pg->ps.type->select_path(&pg->ps, &m->repeat_count); if (!path) return -ENXIO; @@ -261,7 +266,7 @@ static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg, return 0; } -static void __choose_pgpath(struct multipath *m, size_t nr_bytes) +static void __choose_pgpath(struct multipath *m) { struct priority_group *pg; unsigned bypassed = 1; @@ -273,12 +278,12 @@ static void __choose_pgpath(struct multipath *m, size_t nr_bytes) if (m->next_pg) { pg = m->next_pg; m->next_pg = NULL; - if (!__choose_path_in_pg(m, pg, nr_bytes)) + if (!__choose_path_in_pg(m, pg)) return; } /* Don't change PG until it has no remaining paths */ - if (m->current_pg && !__choose_path_in_pg(m, m->current_pg, nr_bytes)) + if (m->current_pg && !__choose_path_in_pg(m, m->current_pg)) return; /* @@ -290,7 +295,7 @@ static void __choose_pgpath(struct multipath *m, size_t nr_bytes) list_for_each_entry(pg, &m->priority_groups, list) { if (pg->bypassed == bypassed) continue; - if (!__choose_path_in_pg(m, pg, nr_bytes)) + if (!__choose_path_in_pg(m, pg)) return; } } while (bypassed--); @@ -317,21 +322,19 @@ static int __must_push_back(struct multipath *m) dm_noflush_suspending(m->ti)); } -static int map_io(struct multipath *m, struct request *clone, +static int map_io(struct multipath *m, struct bio *bio, struct dm_mpath_io *mpio, unsigned was_queued) { int r = DM_MAPIO_REMAPPED; - size_t nr_bytes = blk_rq_bytes(clone); unsigned long flags; struct pgpath *pgpath; - struct block_device *bdev; spin_lock_irqsave(&m->lock, flags); /* Do we need to select a new pgpath? */ if (!m->current_pgpath || (!m->queue_io && (m->repeat_count && --m->repeat_count == 0))) - __choose_pgpath(m, nr_bytes); + __choose_pgpath(m); pgpath = m->current_pgpath; @@ -341,28 +344,21 @@ static int map_io(struct multipath *m, struct request *clone, if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path)) { /* Queue for the daemon to resubmit */ - list_add_tail(&clone->queuelist, &m->queued_ios); + bio_list_add(&m->queued_ios, bio); m->queue_size++; if ((m->pg_init_required && !m->pg_init_in_progress) || !m->queue_io) queue_work(kmultipathd, &m->process_queued_ios); pgpath = NULL; r = DM_MAPIO_SUBMITTED; - } else if (pgpath) { - bdev = pgpath->path.dev->bdev; - clone->q = bdev_get_queue(bdev); - clone->rq_disk = bdev->bd_disk; - } else if (__must_push_back(m)) + } else if (pgpath) + bio->bi_bdev = pgpath->path.dev->bdev; + else if (__must_push_back(m)) r = DM_MAPIO_REQUEUE; else r = -EIO; /* Failed */ mpio->pgpath = pgpath; - mpio->nr_bytes = nr_bytes; - - if (r == DM_MAPIO_REMAPPED && pgpath->pg->ps.type->start_io) - pgpath->pg->ps.type->start_io(&pgpath->pg->ps, &pgpath->path, - nr_bytes); spin_unlock_irqrestore(&m->lock, flags); @@ -400,31 +396,30 @@ static void dispatch_queued_ios(struct multipath *m) { int r; unsigned long flags; + struct bio *bio = NULL, *next; struct dm_mpath_io *mpio; union map_info *info; - struct request *clone, *n; - LIST_HEAD(cl); spin_lock_irqsave(&m->lock, flags); - list_splice_init(&m->queued_ios, &cl); + bio = bio_list_get(&m->queued_ios); spin_unlock_irqrestore(&m->lock, flags); - list_for_each_entry_safe(clone, n, &cl, queuelist) { - list_del_init(&clone->queuelist); + while (bio) { + next = bio->bi_next; + bio->bi_next = NULL; - info = dm_get_rq_mapinfo(clone); + info = dm_get_mapinfo(bio); mpio = info->ptr; - r = map_io(m, clone, mpio, 1); - if (r < 0) { - mempool_free(mpio, m->mpio_pool); - dm_kill_unmapped_request(clone, r); - } else if (r == DM_MAPIO_REMAPPED) - dm_dispatch_request(clone); - else if (r == DM_MAPIO_REQUEUE) { - mempool_free(mpio, m->mpio_pool); - dm_requeue_unmapped_request(clone); - } + r = map_io(m, bio, mpio, 1); + if (r < 0) + bio_endio(bio, r); + else if (r == DM_MAPIO_REMAPPED) + generic_make_request(bio); + else if (r == DM_MAPIO_REQUEUE) + bio_endio(bio, -EIO); + + bio = next; } } @@ -432,8 +427,8 @@ static void process_queued_ios(struct work_struct *work) { struct multipath *m = container_of(work, struct multipath, process_queued_ios); - struct pgpath *pgpath = NULL, *tmp; - unsigned must_queue = 1; + struct pgpath *pgpath = NULL; + unsigned init_required = 0, must_queue = 1; unsigned long flags; spin_lock_irqsave(&m->lock, flags); @@ -442,7 +437,7 @@ static void process_queued_ios(struct work_struct *work) goto out; if (!m->current_pgpath) - __choose_pgpath(m, 0); + __choose_pgpath(m); pgpath = m->current_pgpath; @@ -451,15 +446,19 @@ static void process_queued_ios(struct work_struct *work) must_queue = 0; if (m->pg_init_required && !m->pg_init_in_progress && pgpath) { + m->pgpath_to_activate = pgpath; m->pg_init_count++; m->pg_init_required = 0; - list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) { - if (queue_work(kmpath_handlerd, &tmp->activate_path)) - m->pg_init_in_progress++; - } + m->pg_init_in_progress = 1; + init_required = 1; } + out: spin_unlock_irqrestore(&m->lock, flags); + + if (init_required) + queue_work(kmpath_handlerd, &m->activate_path); + if (!must_queue) dispatch_queued_ios(m); } @@ -554,12 +553,6 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg, return -EINVAL; } - if (ps_argc > as->argc) { - dm_put_path_selector(pst); - ti->error = "not enough arguments for path selector"; - return -EINVAL; - } - r = pst->create(&pg->ps, ps_argc, as->argv); if (r) { dm_put_path_selector(pst); @@ -598,20 +591,9 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, } if (m->hw_handler_name) { - struct request_queue *q = bdev_get_queue(p->path.dev->bdev); - - r = scsi_dh_attach(q, m->hw_handler_name); - if (r == -EBUSY) { - /* - * Already attached to different hw_handler, - * try to reattach with correct one. - */ - scsi_dh_detach(q); - r = scsi_dh_attach(q, m->hw_handler_name); - } - + r = scsi_dh_attach(bdev_get_queue(p->path.dev->bdev), + m->hw_handler_name); if (r < 0) { - ti->error = "error attaching hardware handler"; dm_put_device(ti, p->path.dev); goto bad; } @@ -717,11 +699,6 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m) if (!hw_argc) return 0; - if (hw_argc > as->argc) { - ti->error = "not enough arguments for hardware handler"; - return -EINVAL; - } - m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL); request_module("scsi_dh_%s", m->hw_handler_name); if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { @@ -846,8 +823,6 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, goto bad; } - ti->num_flush_requests = 1; - return 0; bad: @@ -861,29 +836,25 @@ static void multipath_dtr(struct dm_target *ti) flush_workqueue(kmpath_handlerd); flush_workqueue(kmultipathd); - flush_scheduled_work(); free_multipath(m); } /* - * Map cloned requests + * Map bios, recording original fields for later in case we have to resubmit */ -static int multipath_map(struct dm_target *ti, struct request *clone, +static int multipath_map(struct dm_target *ti, struct bio *bio, union map_info *map_context) { int r; struct dm_mpath_io *mpio; struct multipath *m = (struct multipath *) ti->private; - mpio = mempool_alloc(m->mpio_pool, GFP_ATOMIC); - if (!mpio) - /* ENOMEM, requeue */ - return DM_MAPIO_REQUEUE; - memset(mpio, 0, sizeof(*mpio)); + mpio = mempool_alloc(m->mpio_pool, GFP_NOIO); + dm_bio_record(&mpio->details, bio); map_context->ptr = mpio; - clone->cmd_flags |= REQ_FAILFAST_TRANSPORT; - r = map_io(m, clone, mpio, 0); + bio->bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT); + r = map_io(m, bio, mpio, 0); if (r < 0 || r == DM_MAPIO_REQUEUE) mempool_free(mpio, m->mpio_pool); @@ -953,13 +924,9 @@ static int reinstate_path(struct pgpath *pgpath) pgpath->is_active = 1; - if (!m->nr_valid_paths++ && m->queue_size) { - m->current_pgpath = NULL; + m->current_pgpath = NULL; + if (!m->nr_valid_paths++ && m->queue_size) queue_work(kmultipathd, &m->process_queued_ios); - } else if (m->hw_handler_name && (m->current_pg == pgpath->pg)) { - if (queue_work(kmpath_handlerd, &pgpath->activate_path)) - m->pg_init_in_progress++; - } dm_path_uevent(DM_UEVENT_PATH_REINSTATED, m->ti, pgpath->path.dev->name, m->nr_valid_paths); @@ -1135,70 +1102,87 @@ static void pg_init_done(struct dm_path *path, int errors) spin_lock_irqsave(&m->lock, flags); if (errors) { - if (pgpath == m->current_pgpath) { - DMERR("Could not failover device. Error %d.", errors); - m->current_pgpath = NULL; - m->current_pg = NULL; - } + DMERR("Could not failover device. Error %d.", errors); + m->current_pgpath = NULL; + m->current_pg = NULL; } else if (!m->pg_init_required) { m->queue_io = 0; pg->bypassed = 0; } - m->pg_init_in_progress--; - if (!m->pg_init_in_progress) - queue_work(kmultipathd, &m->process_queued_ios); + m->pg_init_in_progress = 0; + queue_work(kmultipathd, &m->process_queued_ios); spin_unlock_irqrestore(&m->lock, flags); } static void activate_path(struct work_struct *work) { int ret; - struct pgpath *pgpath = - container_of(work, struct pgpath, activate_path); + struct multipath *m = + container_of(work, struct multipath, activate_path); + struct dm_path *path; + unsigned long flags; - ret = scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev)); - pg_init_done(&pgpath->path, ret); + spin_lock_irqsave(&m->lock, flags); + path = &m->pgpath_to_activate->path; + m->pgpath_to_activate = NULL; + spin_unlock_irqrestore(&m->lock, flags); + if (!path) + return; + ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev)); + pg_init_done(path, ret); } /* * end_io handling */ -static int do_end_io(struct multipath *m, struct request *clone, +static int do_end_io(struct multipath *m, struct bio *bio, int error, struct dm_mpath_io *mpio) { - /* - * We don't queue any clone request inside the multipath target - * during end I/O handling, since those clone requests don't have - * bio clones. If we queue them inside the multipath target, - * we need to make bio clones, that requires memory allocation. - * (See drivers/md/dm.c:end_clone_bio() about why the clone requests - * don't have bio clones.) - * Instead of queueing the clone request here, we queue the original - * request into dm core, which will remake a clone request and - * clone bios for it and resubmit it later. - */ - int r = DM_ENDIO_REQUEUE; unsigned long flags; - if (!error && !clone->errors) + if (!error) return 0; /* I/O complete */ + if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) + return error; + if (error == -EOPNOTSUPP) return error; + spin_lock_irqsave(&m->lock, flags); + if (!m->nr_valid_paths) { + if (__must_push_back(m)) { + spin_unlock_irqrestore(&m->lock, flags); + return DM_ENDIO_REQUEUE; + } else if (!m->queue_if_no_path) { + spin_unlock_irqrestore(&m->lock, flags); + return -EIO; + } else { + spin_unlock_irqrestore(&m->lock, flags); + goto requeue; + } + } + spin_unlock_irqrestore(&m->lock, flags); + if (mpio->pgpath) fail_path(mpio->pgpath); + requeue: + dm_bio_restore(&mpio->details, bio); + + /* queue for the daemon to resubmit or fail */ spin_lock_irqsave(&m->lock, flags); - if (!m->nr_valid_paths && !m->queue_if_no_path && !__must_push_back(m)) - r = -EIO; + bio_list_add(&m->queued_ios, bio); + m->queue_size++; + if (!m->queue_io) + queue_work(kmultipathd, &m->process_queued_ios); spin_unlock_irqrestore(&m->lock, flags); - return r; + return DM_ENDIO_INCOMPLETE; /* io not complete */ } -static int multipath_end_io(struct dm_target *ti, struct request *clone, +static int multipath_end_io(struct dm_target *ti, struct bio *bio, int error, union map_info *map_context) { struct multipath *m = ti->private; @@ -1207,13 +1191,14 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, struct path_selector *ps; int r; - r = do_end_io(m, clone, error, mpio); + r = do_end_io(m, bio, error, mpio); if (pgpath) { ps = &pgpath->pg->ps; if (ps->type->end_io) - ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes); + ps->type->end_io(ps, &pgpath->path); } - mempool_free(mpio, m->mpio_pool); + if (r != DM_ENDIO_INCOMPLETE) + mempool_free(mpio, m->mpio_pool); return r; } @@ -1426,7 +1411,7 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, spin_lock_irqsave(&m->lock, flags); if (!m->current_pgpath) - __choose_pgpath(m, 0); + __choose_pgpath(m); if (m->current_pgpath) { bdev = m->current_pgpath->path.dev->bdev; @@ -1443,113 +1428,22 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); } -static int multipath_iterate_devices(struct dm_target *ti, - iterate_devices_callout_fn fn, void *data) -{ - struct multipath *m = ti->private; - struct priority_group *pg; - struct pgpath *p; - int ret = 0; - - list_for_each_entry(pg, &m->priority_groups, list) { - list_for_each_entry(p, &pg->pgpaths, list) { - ret = fn(ti, p->path.dev, ti->begin, data); - if (ret) - goto out; - } - } - -out: - return ret; -} - -static int __pgpath_busy(struct pgpath *pgpath) -{ - struct request_queue *q = bdev_get_queue(pgpath->path.dev->bdev); - - return dm_underlying_device_busy(q); -} - -/* - * We return "busy", only when we can map I/Os but underlying devices - * are busy (so even if we map I/Os now, the I/Os will wait on - * the underlying queue). - * In other words, if we want to kill I/Os or queue them inside us - * due to map unavailability, we don't return "busy". Otherwise, - * dm core won't give us the I/Os and we can't do what we want. - */ -static int multipath_busy(struct dm_target *ti) -{ - int busy = 0, has_active = 0; - struct multipath *m = ti->private; - struct priority_group *pg; - struct pgpath *pgpath; - unsigned long flags; - - spin_lock_irqsave(&m->lock, flags); - - /* Guess which priority_group will be used at next mapping time */ - if (unlikely(!m->current_pgpath && m->next_pg)) - pg = m->next_pg; - else if (likely(m->current_pg)) - pg = m->current_pg; - else - /* - * We don't know which pg will be used at next mapping time. - * We don't call __choose_pgpath() here to avoid to trigger - * pg_init just by busy checking. - * So we don't know whether underlying devices we will be using - * at next mapping time are busy or not. Just try mapping. - */ - goto out; - - /* - * If there is one non-busy active path at least, the path selector - * will be able to select it. So we consider such a pg as not busy. - */ - busy = 1; - list_for_each_entry(pgpath, &pg->pgpaths, list) - if (pgpath->is_active) { - has_active = 1; - - if (!__pgpath_busy(pgpath)) { - busy = 0; - break; - } - } - - if (!has_active) - /* - * No active path in this pg, so this pg won't be used and - * the current_pg will be changed at next mapping time. - * We need to try mapping to determine it. - */ - busy = 0; - -out: - spin_unlock_irqrestore(&m->lock, flags); - - return busy; -} - /*----------------------------------------------------------------- * Module setup *---------------------------------------------------------------*/ static struct target_type multipath_target = { .name = "multipath", - .version = {1, 1, 0}, + .version = {1, 0, 5}, .module = THIS_MODULE, .ctr = multipath_ctr, .dtr = multipath_dtr, - .map_rq = multipath_map, - .rq_end_io = multipath_end_io, + .map = multipath_map, + .end_io = multipath_end_io, .presuspend = multipath_presuspend, .resume = multipath_resume, .status = multipath_status, .message = multipath_message, .ioctl = multipath_ioctl, - .iterate_devices = multipath_iterate_devices, - .busy = multipath_busy, }; static int __init dm_multipath_init(void) diff --git a/trunk/drivers/md/dm-path-selector.h b/trunk/drivers/md/dm-path-selector.h index e7d1fa8b0459..27357b85d73d 100644 --- a/trunk/drivers/md/dm-path-selector.h +++ b/trunk/drivers/md/dm-path-selector.h @@ -56,8 +56,7 @@ struct path_selector_type { * the path fails. */ struct dm_path *(*select_path) (struct path_selector *ps, - unsigned *repeat_count, - size_t nr_bytes); + unsigned *repeat_count); /* * Notify the selector that a path has failed. @@ -76,10 +75,7 @@ struct path_selector_type { int (*status) (struct path_selector *ps, struct dm_path *path, status_type_t type, char *result, unsigned int maxlen); - int (*start_io) (struct path_selector *ps, struct dm_path *path, - size_t nr_bytes); - int (*end_io) (struct path_selector *ps, struct dm_path *path, - size_t nr_bytes); + int (*end_io) (struct path_selector *ps, struct dm_path *path); }; /* Register a path selector */ diff --git a/trunk/drivers/md/dm-queue-length.c b/trunk/drivers/md/dm-queue-length.c deleted file mode 100644 index f92b6cea9d9c..000000000000 --- a/trunk/drivers/md/dm-queue-length.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2004-2005 IBM Corp. All Rights Reserved. - * Copyright (C) 2006-2009 NEC Corporation. - * - * dm-queue-length.c - * - * Module Author: Stefan Bader, IBM - * Modified by: Kiyoshi Ueda, NEC - * - * This file is released under the GPL. - * - * queue-length path selector - choose a path with the least number of - * in-flight I/Os. - */ - -#include "dm.h" -#include "dm-path-selector.h" - -#include -#include -#include -#include -#include - -#define DM_MSG_PREFIX "multipath queue-length" -#define QL_MIN_IO 128 -#define QL_VERSION "0.1.0" - -struct selector { - struct list_head valid_paths; - struct list_head failed_paths; -}; - -struct path_info { - struct list_head list; - struct dm_path *path; - unsigned repeat_count; - atomic_t qlen; /* the number of in-flight I/Os */ -}; - -static struct selector *alloc_selector(void) -{ - struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); - - if (s) { - INIT_LIST_HEAD(&s->valid_paths); - INIT_LIST_HEAD(&s->failed_paths); - } - - return s; -} - -static int ql_create(struct path_selector *ps, unsigned argc, char **argv) -{ - struct selector *s = alloc_selector(); - - if (!s) - return -ENOMEM; - - ps->context = s; - return 0; -} - -static void ql_free_paths(struct list_head *paths) -{ - struct path_info *pi, *next; - - list_for_each_entry_safe(pi, next, paths, list) { - list_del(&pi->list); - kfree(pi); - } -} - -static void ql_destroy(struct path_selector *ps) -{ - struct selector *s = ps->context; - - ql_free_paths(&s->valid_paths); - ql_free_paths(&s->failed_paths); - kfree(s); - ps->context = NULL; -} - -static int ql_status(struct path_selector *ps, struct dm_path *path, - status_type_t type, char *result, unsigned maxlen) -{ - unsigned sz = 0; - struct path_info *pi; - - /* When called with NULL path, return selector status/args. */ - if (!path) - DMEMIT("0 "); - else { - pi = path->pscontext; - - switch (type) { - case STATUSTYPE_INFO: - DMEMIT("%d ", atomic_read(&pi->qlen)); - break; - case STATUSTYPE_TABLE: - DMEMIT("%u ", pi->repeat_count); - break; - } - } - - return sz; -} - -static int ql_add_path(struct path_selector *ps, struct dm_path *path, - int argc, char **argv, char **error) -{ - struct selector *s = ps->context; - struct path_info *pi; - unsigned repeat_count = QL_MIN_IO; - - /* - * Arguments: [] - * : The number of I/Os before switching path. - * If not given, default (QL_MIN_IO) is used. - */ - if (argc > 1) { - *error = "queue-length ps: incorrect number of arguments"; - return -EINVAL; - } - - if ((argc == 1) && (sscanf(argv[0], "%u", &repeat_count) != 1)) { - *error = "queue-length ps: invalid repeat count"; - return -EINVAL; - } - - /* Allocate the path information structure */ - pi = kmalloc(sizeof(*pi), GFP_KERNEL); - if (!pi) { - *error = "queue-length ps: Error allocating path information"; - return -ENOMEM; - } - - pi->path = path; - pi->repeat_count = repeat_count; - atomic_set(&pi->qlen, 0); - - path->pscontext = pi; - - list_add_tail(&pi->list, &s->valid_paths); - - return 0; -} - -static void ql_fail_path(struct path_selector *ps, struct dm_path *path) -{ - struct selector *s = ps->context; - struct path_info *pi = path->pscontext; - - list_move(&pi->list, &s->failed_paths); -} - -static int ql_reinstate_path(struct path_selector *ps, struct dm_path *path) -{ - struct selector *s = ps->context; - struct path_info *pi = path->pscontext; - - list_move_tail(&pi->list, &s->valid_paths); - - return 0; -} - -/* - * Select a path having the minimum number of in-flight I/Os - */ -static struct dm_path *ql_select_path(struct path_selector *ps, - unsigned *repeat_count, size_t nr_bytes) -{ - struct selector *s = ps->context; - struct path_info *pi = NULL, *best = NULL; - - if (list_empty(&s->valid_paths)) - return NULL; - - /* Change preferred (first in list) path to evenly balance. */ - list_move_tail(s->valid_paths.next, &s->valid_paths); - - list_for_each_entry(pi, &s->valid_paths, list) { - if (!best || - (atomic_read(&pi->qlen) < atomic_read(&best->qlen))) - best = pi; - - if (!atomic_read(&best->qlen)) - break; - } - - if (!best) - return NULL; - - *repeat_count = best->repeat_count; - - return best->path; -} - -static int ql_start_io(struct path_selector *ps, struct dm_path *path, - size_t nr_bytes) -{ - struct path_info *pi = path->pscontext; - - atomic_inc(&pi->qlen); - - return 0; -} - -static int ql_end_io(struct path_selector *ps, struct dm_path *path, - size_t nr_bytes) -{ - struct path_info *pi = path->pscontext; - - atomic_dec(&pi->qlen); - - return 0; -} - -static struct path_selector_type ql_ps = { - .name = "queue-length", - .module = THIS_MODULE, - .table_args = 1, - .info_args = 1, - .create = ql_create, - .destroy = ql_destroy, - .status = ql_status, - .add_path = ql_add_path, - .fail_path = ql_fail_path, - .reinstate_path = ql_reinstate_path, - .select_path = ql_select_path, - .start_io = ql_start_io, - .end_io = ql_end_io, -}; - -static int __init dm_ql_init(void) -{ - int r = dm_register_path_selector(&ql_ps); - - if (r < 0) - DMERR("register failed %d", r); - - DMINFO("version " QL_VERSION " loaded"); - - return r; -} - -static void __exit dm_ql_exit(void) -{ - int r = dm_unregister_path_selector(&ql_ps); - - if (r < 0) - DMERR("unregister failed %d", r); -} - -module_init(dm_ql_init); -module_exit(dm_ql_exit); - -MODULE_AUTHOR("Stefan Bader "); -MODULE_DESCRIPTION( - "(C) Copyright IBM Corp. 2004,2005 All Rights Reserved.\n" - DM_NAME " path selector to balance the number of in-flight I/Os" -); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/md/dm-raid1.c b/trunk/drivers/md/dm-raid1.c index ce8868c768cc..076fbb4e967a 100644 --- a/trunk/drivers/md/dm-raid1.c +++ b/trunk/drivers/md/dm-raid1.c @@ -1283,23 +1283,9 @@ static int mirror_status(struct dm_target *ti, status_type_t type, return 0; } -static int mirror_iterate_devices(struct dm_target *ti, - iterate_devices_callout_fn fn, void *data) -{ - struct mirror_set *ms = ti->private; - int ret = 0; - unsigned i; - - for (i = 0; !ret && i < ms->nr_mirrors; i++) - ret = fn(ti, ms->mirror[i].dev, - ms->mirror[i].offset, data); - - return ret; -} - static struct target_type mirror_target = { .name = "mirror", - .version = {1, 12, 0}, + .version = {1, 0, 20}, .module = THIS_MODULE, .ctr = mirror_ctr, .dtr = mirror_dtr, @@ -1309,7 +1295,6 @@ static struct target_type mirror_target = { .postsuspend = mirror_postsuspend, .resume = mirror_resume, .status = mirror_status, - .iterate_devices = mirror_iterate_devices, }; static int __init dm_mirror_init(void) diff --git a/trunk/drivers/md/dm-region-hash.c b/trunk/drivers/md/dm-region-hash.c index 36dbe29f2fd6..7b899be0b087 100644 --- a/trunk/drivers/md/dm-region-hash.c +++ b/trunk/drivers/md/dm-region-hash.c @@ -283,7 +283,7 @@ static struct dm_region *__rh_alloc(struct dm_region_hash *rh, region_t region) nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC); if (unlikely(!nreg)) - nreg = kmalloc(sizeof(*nreg), GFP_NOIO | __GFP_NOFAIL); + nreg = kmalloc(sizeof(*nreg), GFP_NOIO); nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? DM_RH_CLEAN : DM_RH_NOSYNC; diff --git a/trunk/drivers/md/dm-round-robin.c b/trunk/drivers/md/dm-round-robin.c index 24752f449bef..cdfbf65b28cb 100644 --- a/trunk/drivers/md/dm-round-robin.c +++ b/trunk/drivers/md/dm-round-robin.c @@ -161,7 +161,7 @@ static int rr_reinstate_path(struct path_selector *ps, struct dm_path *p) } static struct dm_path *rr_select_path(struct path_selector *ps, - unsigned *repeat_count, size_t nr_bytes) + unsigned *repeat_count) { struct selector *s = (struct selector *) ps->context; struct path_info *pi = NULL; diff --git a/trunk/drivers/md/dm-service-time.c b/trunk/drivers/md/dm-service-time.c deleted file mode 100644 index cfa668f46c40..000000000000 --- a/trunk/drivers/md/dm-service-time.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (C) 2007-2009 NEC Corporation. All Rights Reserved. - * - * Module Author: Kiyoshi Ueda - * - * This file is released under the GPL. - * - * Throughput oriented path selector. - */ - -#include "dm.h" -#include "dm-path-selector.h" - -#define DM_MSG_PREFIX "multipath service-time" -#define ST_MIN_IO 1 -#define ST_MAX_RELATIVE_THROUGHPUT 100 -#define ST_MAX_RELATIVE_THROUGHPUT_SHIFT 7 -#define ST_MAX_INFLIGHT_SIZE ((size_t)-1 >> ST_MAX_RELATIVE_THROUGHPUT_SHIFT) -#define ST_VERSION "0.2.0" - -struct selector { - struct list_head valid_paths; - struct list_head failed_paths; -}; - -struct path_info { - struct list_head list; - struct dm_path *path; - unsigned repeat_count; - unsigned relative_throughput; - atomic_t in_flight_size; /* Total size of in-flight I/Os */ -}; - -static struct selector *alloc_selector(void) -{ - struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); - - if (s) { - INIT_LIST_HEAD(&s->valid_paths); - INIT_LIST_HEAD(&s->failed_paths); - } - - return s; -} - -static int st_create(struct path_selector *ps, unsigned argc, char **argv) -{ - struct selector *s = alloc_selector(); - - if (!s) - return -ENOMEM; - - ps->context = s; - return 0; -} - -static void free_paths(struct list_head *paths) -{ - struct path_info *pi, *next; - - list_for_each_entry_safe(pi, next, paths, list) { - list_del(&pi->list); - kfree(pi); - } -} - -static void st_destroy(struct path_selector *ps) -{ - struct selector *s = ps->context; - - free_paths(&s->valid_paths); - free_paths(&s->failed_paths); - kfree(s); - ps->context = NULL; -} - -static int st_status(struct path_selector *ps, struct dm_path *path, - status_type_t type, char *result, unsigned maxlen) -{ - unsigned sz = 0; - struct path_info *pi; - - if (!path) - DMEMIT("0 "); - else { - pi = path->pscontext; - - switch (type) { - case STATUSTYPE_INFO: - DMEMIT("%d %u ", atomic_read(&pi->in_flight_size), - pi->relative_throughput); - break; - case STATUSTYPE_TABLE: - DMEMIT("%u %u ", pi->repeat_count, - pi->relative_throughput); - break; - } - } - - return sz; -} - -static int st_add_path(struct path_selector *ps, struct dm_path *path, - int argc, char **argv, char **error) -{ - struct selector *s = ps->context; - struct path_info *pi; - unsigned repeat_count = ST_MIN_IO; - unsigned relative_throughput = 1; - - /* - * Arguments: [ []] - * : The number of I/Os before switching path. - * If not given, default (ST_MIN_IO) is used. - * : The relative throughput value of - * the path among all paths in the path-group. - * The valid range: 0- - * If not given, minimum value '1' is used. - * If '0' is given, the path isn't selected while - * other paths having a positive value are - * available. - */ - if (argc > 2) { - *error = "service-time ps: incorrect number of arguments"; - return -EINVAL; - } - - if (argc && (sscanf(argv[0], "%u", &repeat_count) != 1)) { - *error = "service-time ps: invalid repeat count"; - return -EINVAL; - } - - if ((argc == 2) && - (sscanf(argv[1], "%u", &relative_throughput) != 1 || - relative_throughput > ST_MAX_RELATIVE_THROUGHPUT)) { - *error = "service-time ps: invalid relative_throughput value"; - return -EINVAL; - } - - /* allocate the path */ - pi = kmalloc(sizeof(*pi), GFP_KERNEL); - if (!pi) { - *error = "service-time ps: Error allocating path context"; - return -ENOMEM; - } - - pi->path = path; - pi->repeat_count = repeat_count; - pi->relative_throughput = relative_throughput; - atomic_set(&pi->in_flight_size, 0); - - path->pscontext = pi; - - list_add_tail(&pi->list, &s->valid_paths); - - return 0; -} - -static void st_fail_path(struct path_selector *ps, struct dm_path *path) -{ - struct selector *s = ps->context; - struct path_info *pi = path->pscontext; - - list_move(&pi->list, &s->failed_paths); -} - -static int st_reinstate_path(struct path_selector *ps, struct dm_path *path) -{ - struct selector *s = ps->context; - struct path_info *pi = path->pscontext; - - list_move_tail(&pi->list, &s->valid_paths); - - return 0; -} - -/* - * Compare the estimated service time of 2 paths, pi1 and pi2, - * for the incoming I/O. - * - * Returns: - * < 0 : pi1 is better - * 0 : no difference between pi1 and pi2 - * > 0 : pi2 is better - * - * Description: - * Basically, the service time is estimated by: - * ('pi->in-flight-size' + 'incoming') / 'pi->relative_throughput' - * To reduce the calculation, some optimizations are made. - * (See comments inline) - */ -static int st_compare_load(struct path_info *pi1, struct path_info *pi2, - size_t incoming) -{ - size_t sz1, sz2, st1, st2; - - sz1 = atomic_read(&pi1->in_flight_size); - sz2 = atomic_read(&pi2->in_flight_size); - - /* - * Case 1: Both have same throughput value. Choose less loaded path. - */ - if (pi1->relative_throughput == pi2->relative_throughput) - return sz1 - sz2; - - /* - * Case 2a: Both have same load. Choose higher throughput path. - * Case 2b: One path has no throughput value. Choose the other one. - */ - if (sz1 == sz2 || - !pi1->relative_throughput || !pi2->relative_throughput) - return pi2->relative_throughput - pi1->relative_throughput; - - /* - * Case 3: Calculate service time. Choose faster path. - * Service time using pi1: - * st1 = (sz1 + incoming) / pi1->relative_throughput - * Service time using pi2: - * st2 = (sz2 + incoming) / pi2->relative_throughput - * - * To avoid the division, transform the expression to use - * multiplication. - * Because ->relative_throughput > 0 here, if st1 < st2, - * the expressions below are the same meaning: - * (sz1 + incoming) / pi1->relative_throughput < - * (sz2 + incoming) / pi2->relative_throughput - * (sz1 + incoming) * pi2->relative_throughput < - * (sz2 + incoming) * pi1->relative_throughput - * So use the later one. - */ - sz1 += incoming; - sz2 += incoming; - if (unlikely(sz1 >= ST_MAX_INFLIGHT_SIZE || - sz2 >= ST_MAX_INFLIGHT_SIZE)) { - /* - * Size may be too big for multiplying pi->relative_throughput - * and overflow. - * To avoid the overflow and mis-selection, shift down both. - */ - sz1 >>= ST_MAX_RELATIVE_THROUGHPUT_SHIFT; - sz2 >>= ST_MAX_RELATIVE_THROUGHPUT_SHIFT; - } - st1 = sz1 * pi2->relative_throughput; - st2 = sz2 * pi1->relative_throughput; - if (st1 != st2) - return st1 - st2; - - /* - * Case 4: Service time is equal. Choose higher throughput path. - */ - return pi2->relative_throughput - pi1->relative_throughput; -} - -static struct dm_path *st_select_path(struct path_selector *ps, - unsigned *repeat_count, size_t nr_bytes) -{ - struct selector *s = ps->context; - struct path_info *pi = NULL, *best = NULL; - - if (list_empty(&s->valid_paths)) - return NULL; - - /* Change preferred (first in list) path to evenly balance. */ - list_move_tail(s->valid_paths.next, &s->valid_paths); - - list_for_each_entry(pi, &s->valid_paths, list) - if (!best || (st_compare_load(pi, best, nr_bytes) < 0)) - best = pi; - - if (!best) - return NULL; - - *repeat_count = best->repeat_count; - - return best->path; -} - -static int st_start_io(struct path_selector *ps, struct dm_path *path, - size_t nr_bytes) -{ - struct path_info *pi = path->pscontext; - - atomic_add(nr_bytes, &pi->in_flight_size); - - return 0; -} - -static int st_end_io(struct path_selector *ps, struct dm_path *path, - size_t nr_bytes) -{ - struct path_info *pi = path->pscontext; - - atomic_sub(nr_bytes, &pi->in_flight_size); - - return 0; -} - -static struct path_selector_type st_ps = { - .name = "service-time", - .module = THIS_MODULE, - .table_args = 2, - .info_args = 2, - .create = st_create, - .destroy = st_destroy, - .status = st_status, - .add_path = st_add_path, - .fail_path = st_fail_path, - .reinstate_path = st_reinstate_path, - .select_path = st_select_path, - .start_io = st_start_io, - .end_io = st_end_io, -}; - -static int __init dm_st_init(void) -{ - int r = dm_register_path_selector(&st_ps); - - if (r < 0) - DMERR("register failed %d", r); - - DMINFO("version " ST_VERSION " loaded"); - - return r; -} - -static void __exit dm_st_exit(void) -{ - int r = dm_unregister_path_selector(&st_ps); - - if (r < 0) - DMERR("unregister failed %d", r); -} - -module_init(dm_st_init); -module_exit(dm_st_exit); - -MODULE_DESCRIPTION(DM_NAME " throughput oriented path selector"); -MODULE_AUTHOR("Kiyoshi Ueda "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/md/dm-snap-persistent.c b/trunk/drivers/md/dm-snap-persistent.c index 6e3fe4f14934..2662a41337e7 100644 --- a/trunk/drivers/md/dm-snap-persistent.c +++ b/trunk/drivers/md/dm-snap-persistent.c @@ -636,7 +636,7 @@ static void persistent_commit_exception(struct dm_exception_store *store, /* * Commit exceptions to disk. */ - if (ps->valid && area_io(ps, WRITE_BARRIER)) + if (ps->valid && area_io(ps, WRITE)) ps->valid = 0; /* diff --git a/trunk/drivers/md/dm-snap.c b/trunk/drivers/md/dm-snap.c index d573165cd2b7..d73f17fc7778 100644 --- a/trunk/drivers/md/dm-snap.c +++ b/trunk/drivers/md/dm-snap.c @@ -678,7 +678,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) ti->private = s; ti->split_io = s->store->chunk_size; - ti->num_flush_requests = 1; return 0; @@ -1031,11 +1030,6 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, chunk_t chunk; struct dm_snap_pending_exception *pe = NULL; - if (unlikely(bio_empty_barrier(bio))) { - bio->bi_bdev = s->store->cow->bdev; - return DM_MAPIO_REMAPPED; - } - chunk = sector_to_chunk(s->store, bio->bi_sector); /* Full snapshots are not usable */ @@ -1344,8 +1338,6 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv) } ti->private = dev; - ti->num_flush_requests = 1; - return 0; } @@ -1361,9 +1353,6 @@ static int origin_map(struct dm_target *ti, struct bio *bio, struct dm_dev *dev = ti->private; bio->bi_bdev = dev->bdev; - if (unlikely(bio_empty_barrier(bio))) - return DM_MAPIO_REMAPPED; - /* Only tell snapshots if this is a write */ return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED; } diff --git a/trunk/drivers/md/dm-stripe.c b/trunk/drivers/md/dm-stripe.c index b240e85ae39a..41569bc60abc 100644 --- a/trunk/drivers/md/dm-stripe.c +++ b/trunk/drivers/md/dm-stripe.c @@ -167,7 +167,6 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) sc->stripes = stripes; sc->stripe_width = width; ti->split_io = chunk_size; - ti->num_flush_requests = stripes; sc->chunk_mask = ((sector_t) chunk_size) - 1; for (sc->chunk_shift = 0; chunk_size; sc->chunk_shift++) @@ -212,18 +211,10 @@ static int stripe_map(struct dm_target *ti, struct bio *bio, union map_info *map_context) { struct stripe_c *sc = (struct stripe_c *) ti->private; - sector_t offset, chunk; - uint32_t stripe; - if (unlikely(bio_empty_barrier(bio))) { - BUG_ON(map_context->flush_request >= sc->stripes); - bio->bi_bdev = sc->stripe[map_context->flush_request].dev->bdev; - return DM_MAPIO_REMAPPED; - } - - offset = bio->bi_sector - ti->begin; - chunk = offset >> sc->chunk_shift; - stripe = sector_div(chunk, sc->stripes); + sector_t offset = bio->bi_sector - ti->begin; + sector_t chunk = offset >> sc->chunk_shift; + uint32_t stripe = sector_div(chunk, sc->stripes); bio->bi_bdev = sc->stripe[stripe].dev->bdev; bio->bi_sector = sc->stripe[stripe].physical_start + @@ -313,31 +304,15 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio, return error; } -static int stripe_iterate_devices(struct dm_target *ti, - iterate_devices_callout_fn fn, void *data) -{ - struct stripe_c *sc = ti->private; - int ret = 0; - unsigned i = 0; - - do - ret = fn(ti, sc->stripe[i].dev, - sc->stripe[i].physical_start, data); - while (!ret && ++i < sc->stripes); - - return ret; -} - static struct target_type stripe_target = { .name = "striped", - .version = {1, 2, 0}, + .version = {1, 1, 0}, .module = THIS_MODULE, .ctr = stripe_ctr, .dtr = stripe_dtr, .map = stripe_map, .end_io = stripe_end_io, .status = stripe_status, - .iterate_devices = stripe_iterate_devices, }; int __init dm_stripe_init(void) diff --git a/trunk/drivers/md/dm-sysfs.c b/trunk/drivers/md/dm-sysfs.c index 4b045903a4e2..a2a45e6c7c8b 100644 --- a/trunk/drivers/md/dm-sysfs.c +++ b/trunk/drivers/md/dm-sysfs.c @@ -57,21 +57,12 @@ static ssize_t dm_attr_uuid_show(struct mapped_device *md, char *buf) return strlen(buf); } -static ssize_t dm_attr_suspended_show(struct mapped_device *md, char *buf) -{ - sprintf(buf, "%d\n", dm_suspended(md)); - - return strlen(buf); -} - static DM_ATTR_RO(name); static DM_ATTR_RO(uuid); -static DM_ATTR_RO(suspended); static struct attribute *dm_attrs[] = { &dm_attr_name.attr, &dm_attr_uuid.attr, - &dm_attr_suspended.attr, NULL, }; diff --git a/trunk/drivers/md/dm-table.c b/trunk/drivers/md/dm-table.c index 2cba557d9e61..e9a73bb242b0 100644 --- a/trunk/drivers/md/dm-table.c +++ b/trunk/drivers/md/dm-table.c @@ -41,7 +41,6 @@ struct dm_table { struct mapped_device *md; atomic_t holders; - unsigned type; /* btree table */ unsigned int depth; @@ -63,11 +62,15 @@ struct dm_table { /* a list of devices used by this table */ struct list_head devices; + /* + * These are optimistic limits taken from all the + * targets, some targets will need smaller limits. + */ + struct io_restrictions limits; + /* events get handed up using this callback */ void (*event_fn)(void *); void *event_context; - - struct dm_md_mempools *mempools; }; /* @@ -85,6 +88,43 @@ static unsigned int int_log(unsigned int n, unsigned int base) return result; } +/* + * Returns the minimum that is _not_ zero, unless both are zero. + */ +#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) + +/* + * Combine two io_restrictions, always taking the lower value. + */ +static void combine_restrictions_low(struct io_restrictions *lhs, + struct io_restrictions *rhs) +{ + lhs->max_sectors = + min_not_zero(lhs->max_sectors, rhs->max_sectors); + + lhs->max_phys_segments = + min_not_zero(lhs->max_phys_segments, rhs->max_phys_segments); + + lhs->max_hw_segments = + min_not_zero(lhs->max_hw_segments, rhs->max_hw_segments); + + lhs->logical_block_size = max(lhs->logical_block_size, + rhs->logical_block_size); + + lhs->max_segment_size = + min_not_zero(lhs->max_segment_size, rhs->max_segment_size); + + lhs->max_hw_sectors = + min_not_zero(lhs->max_hw_sectors, rhs->max_hw_sectors); + + lhs->seg_boundary_mask = + min_not_zero(lhs->seg_boundary_mask, rhs->seg_boundary_mask); + + lhs->bounce_pfn = min_not_zero(lhs->bounce_pfn, rhs->bounce_pfn); + + lhs->no_cluster |= rhs->no_cluster; +} + /* * Calculate the index of the child node of the n'th node k'th key. */ @@ -227,8 +267,6 @@ static void free_devices(struct list_head *devices) list_for_each_safe(tmp, next, devices) { struct dm_dev_internal *dd = list_entry(tmp, struct dm_dev_internal, list); - DMWARN("dm_table_destroy: dm_put_device call missing for %s", - dd->dm_dev.name); kfree(dd); } } @@ -258,10 +296,12 @@ void dm_table_destroy(struct dm_table *t) vfree(t->highs); /* free the device list */ - if (t->devices.next != &t->devices) - free_devices(&t->devices); + if (t->devices.next != &t->devices) { + DMWARN("devices still present during destroy: " + "dm_table_remove_device calls missing"); - dm_free_md_mempools(t->mempools); + free_devices(&t->devices); + } kfree(t); } @@ -345,48 +385,15 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) /* * If possible, this checks an area of a destination device is valid. */ -static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, - sector_t start, void *data) +static int check_device_area(struct dm_dev_internal *dd, sector_t start, + sector_t len) { - struct queue_limits *limits = data; - struct block_device *bdev = dev->bdev; - sector_t dev_size = - i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; - unsigned short logical_block_size_sectors = - limits->logical_block_size >> SECTOR_SHIFT; - char b[BDEVNAME_SIZE]; + sector_t dev_size = dd->dm_dev.bdev->bd_inode->i_size >> SECTOR_SHIFT; if (!dev_size) return 1; - if ((start >= dev_size) || (start + ti->len > dev_size)) { - DMWARN("%s: %s too small for target", - dm_device_name(ti->table->md), bdevname(bdev, b)); - return 0; - } - - if (logical_block_size_sectors <= 1) - return 1; - - if (start & (logical_block_size_sectors - 1)) { - DMWARN("%s: start=%llu not aligned to h/w " - "logical block size %hu of %s", - dm_device_name(ti->table->md), - (unsigned long long)start, - limits->logical_block_size, bdevname(bdev, b)); - return 0; - } - - if (ti->len & (logical_block_size_sectors - 1)) { - DMWARN("%s: len=%llu not aligned to h/w " - "logical block size %hu of %s", - dm_device_name(ti->table->md), - (unsigned long long)ti->len, - limits->logical_block_size, bdevname(bdev, b)); - return 0; - } - - return 1; + return ((start < dev_size) && (len <= (dev_size - start))); } /* @@ -472,32 +479,38 @@ static int __table_get_device(struct dm_table *t, struct dm_target *ti, } atomic_inc(&dd->count); + if (!check_device_area(dd, start, len)) { + DMWARN("device %s too small for target", path); + dm_put_device(ti, &dd->dm_dev); + return -EINVAL; + } + *result = &dd->dm_dev; + return 0; } -/* - * Returns the minimum that is _not_ zero, unless both are zero. - */ -#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) - -int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, - sector_t start, void *data) +void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) { - struct queue_limits *limits = data; - struct block_device *bdev = dev->bdev; struct request_queue *q = bdev_get_queue(bdev); + struct io_restrictions *rs = &ti->limits; char b[BDEVNAME_SIZE]; if (unlikely(!q)) { DMWARN("%s: Cannot set limits for nonexistent device %s", dm_device_name(ti->table->md), bdevname(bdev, b)); - return 0; + return; } - if (blk_stack_limits(limits, &q->limits, start << 9) < 0) - DMWARN("%s: target device %s is misaligned", - dm_device_name(ti->table->md), bdevname(bdev, b)); + /* + * Combine the device limits low. + * + * FIXME: if we move an io_restriction struct + * into q this would just be a call to + * combine_restrictions_low() + */ + rs->max_sectors = + min_not_zero(rs->max_sectors, queue_max_sectors(q)); /* * Check if merge fn is supported. @@ -506,20 +519,47 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, */ if (q->merge_bvec_fn && !ti->type->merge) - limits->max_sectors = - min_not_zero(limits->max_sectors, + rs->max_sectors = + min_not_zero(rs->max_sectors, (unsigned int) (PAGE_SIZE >> 9)); - return 0; + + rs->max_phys_segments = + min_not_zero(rs->max_phys_segments, + queue_max_phys_segments(q)); + + rs->max_hw_segments = + min_not_zero(rs->max_hw_segments, queue_max_hw_segments(q)); + + rs->logical_block_size = max(rs->logical_block_size, + queue_logical_block_size(q)); + + rs->max_segment_size = + min_not_zero(rs->max_segment_size, queue_max_segment_size(q)); + + rs->max_hw_sectors = + min_not_zero(rs->max_hw_sectors, queue_max_hw_sectors(q)); + + rs->seg_boundary_mask = + min_not_zero(rs->seg_boundary_mask, + queue_segment_boundary(q)); + + rs->bounce_pfn = min_not_zero(rs->bounce_pfn, queue_bounce_pfn(q)); + + rs->no_cluster |= !test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); } EXPORT_SYMBOL_GPL(dm_set_device_limits); int dm_get_device(struct dm_target *ti, const char *path, sector_t start, sector_t len, fmode_t mode, struct dm_dev **result) { - return __table_get_device(ti->table, ti, path, - start, len, mode, result); -} + int r = __table_get_device(ti->table, ti, path, + start, len, mode, result); + if (!r) + dm_set_device_limits(ti, (*result)->bdev); + + return r; +} /* * Decrement a devices use count and remove it if necessary. @@ -635,78 +675,24 @@ int dm_split_args(int *argc, char ***argvp, char *input) return 0; } -/* - * Impose necessary and sufficient conditions on a devices's table such - * that any incoming bio which respects its logical_block_size can be - * processed successfully. If it falls across the boundary between - * two or more targets, the size of each piece it gets split into must - * be compatible with the logical_block_size of the target processing it. - */ -static int validate_hardware_logical_block_alignment(struct dm_table *table, - struct queue_limits *limits) +static void check_for_valid_limits(struct io_restrictions *rs) { - /* - * This function uses arithmetic modulo the logical_block_size - * (in units of 512-byte sectors). - */ - unsigned short device_logical_block_size_sects = - limits->logical_block_size >> SECTOR_SHIFT; - - /* - * Offset of the start of the next table entry, mod logical_block_size. - */ - unsigned short next_target_start = 0; - - /* - * Given an aligned bio that extends beyond the end of a - * target, how many sectors must the next target handle? - */ - unsigned short remaining = 0; - - struct dm_target *uninitialized_var(ti); - struct queue_limits ti_limits; - unsigned i = 0; - - /* - * Check each entry in the table in turn. - */ - while (i < dm_table_get_num_targets(table)) { - ti = dm_table_get_target(table, i++); - - blk_set_default_limits(&ti_limits); - - /* combine all target devices' limits */ - if (ti->type->iterate_devices) - ti->type->iterate_devices(ti, dm_set_device_limits, - &ti_limits); - - /* - * If the remaining sectors fall entirely within this - * table entry are they compatible with its logical_block_size? - */ - if (remaining < ti->len && - remaining & ((ti_limits.logical_block_size >> - SECTOR_SHIFT) - 1)) - break; /* Error */ - - next_target_start = - (unsigned short) ((next_target_start + ti->len) & - (device_logical_block_size_sects - 1)); - remaining = next_target_start ? - device_logical_block_size_sects - next_target_start : 0; - } - - if (remaining) { - DMWARN("%s: table line %u (start sect %llu len %llu) " - "not aligned to h/w logical block size %hu", - dm_device_name(table->md), i, - (unsigned long long) ti->begin, - (unsigned long long) ti->len, - limits->logical_block_size); - return -EINVAL; - } - - return 0; + if (!rs->max_sectors) + rs->max_sectors = SAFE_MAX_SECTORS; + if (!rs->max_hw_sectors) + rs->max_hw_sectors = SAFE_MAX_SECTORS; + if (!rs->max_phys_segments) + rs->max_phys_segments = MAX_PHYS_SEGMENTS; + if (!rs->max_hw_segments) + rs->max_hw_segments = MAX_HW_SEGMENTS; + if (!rs->logical_block_size) + rs->logical_block_size = 1 << SECTOR_SHIFT; + if (!rs->max_segment_size) + rs->max_segment_size = MAX_SEGMENT_SIZE; + if (!rs->seg_boundary_mask) + rs->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; + if (!rs->bounce_pfn) + rs->bounce_pfn = -1; } int dm_table_add_target(struct dm_table *t, const char *type, @@ -761,6 +747,9 @@ int dm_table_add_target(struct dm_table *t, const char *type, t->highs[t->num_targets++] = tgt->begin + tgt->len - 1; + /* FIXME: the plan is to combine high here and then have + * the merge fn apply the target level restrictions. */ + combine_restrictions_low(&t->limits, &tgt->limits); return 0; bad: @@ -769,104 +758,6 @@ int dm_table_add_target(struct dm_table *t, const char *type, return r; } -int dm_table_set_type(struct dm_table *t) -{ - unsigned i; - unsigned bio_based = 0, request_based = 0; - struct dm_target *tgt; - struct dm_dev_internal *dd; - struct list_head *devices; - - for (i = 0; i < t->num_targets; i++) { - tgt = t->targets + i; - if (dm_target_request_based(tgt)) - request_based = 1; - else - bio_based = 1; - - if (bio_based && request_based) { - DMWARN("Inconsistent table: different target types" - " can't be mixed up"); - return -EINVAL; - } - } - - if (bio_based) { - /* We must use this table as bio-based */ - t->type = DM_TYPE_BIO_BASED; - return 0; - } - - BUG_ON(!request_based); /* No targets in this table */ - - /* Non-request-stackable devices can't be used for request-based dm */ - devices = dm_table_get_devices(t); - list_for_each_entry(dd, devices, list) { - if (!blk_queue_stackable(bdev_get_queue(dd->dm_dev.bdev))) { - DMWARN("table load rejected: including" - " non-request-stackable devices"); - return -EINVAL; - } - } - - /* - * Request-based dm supports only tables that have a single target now. - * To support multiple targets, request splitting support is needed, - * and that needs lots of changes in the block-layer. - * (e.g. request completion process for partial completion.) - */ - if (t->num_targets > 1) { - DMWARN("Request-based dm doesn't support multiple targets yet"); - return -EINVAL; - } - - t->type = DM_TYPE_REQUEST_BASED; - - return 0; -} - -unsigned dm_table_get_type(struct dm_table *t) -{ - return t->type; -} - -bool dm_table_bio_based(struct dm_table *t) -{ - return dm_table_get_type(t) == DM_TYPE_BIO_BASED; -} - -bool dm_table_request_based(struct dm_table *t) -{ - return dm_table_get_type(t) == DM_TYPE_REQUEST_BASED; -} - -int dm_table_alloc_md_mempools(struct dm_table *t) -{ - unsigned type = dm_table_get_type(t); - - if (unlikely(type == DM_TYPE_NONE)) { - DMWARN("no table type is set, can't allocate mempools"); - return -EINVAL; - } - - t->mempools = dm_alloc_md_mempools(type); - if (!t->mempools) - return -ENOMEM; - - return 0; -} - -void dm_table_free_md_mempools(struct dm_table *t) -{ - dm_free_md_mempools(t->mempools); - t->mempools = NULL; -} - -struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t) -{ - return t->mempools; -} - static int setup_indexes(struct dm_table *t) { int i; @@ -901,6 +792,8 @@ int dm_table_complete(struct dm_table *t) int r = 0; unsigned int leaf_nodes; + check_for_valid_limits(&t->limits); + /* how many indexes will the btree have ? */ leaf_nodes = dm_div_up(t->num_targets, KEYS_PER_NODE); t->depth = 1 + int_log(leaf_nodes, CHILDREN_PER_NODE); @@ -975,57 +868,6 @@ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector) return &t->targets[(KEYS_PER_NODE * n) + k]; } -/* - * Establish the new table's queue_limits and validate them. - */ -int dm_calculate_queue_limits(struct dm_table *table, - struct queue_limits *limits) -{ - struct dm_target *uninitialized_var(ti); - struct queue_limits ti_limits; - unsigned i = 0; - - blk_set_default_limits(limits); - - while (i < dm_table_get_num_targets(table)) { - blk_set_default_limits(&ti_limits); - - ti = dm_table_get_target(table, i++); - - if (!ti->type->iterate_devices) - goto combine_limits; - - /* - * Combine queue limits of all the devices this target uses. - */ - ti->type->iterate_devices(ti, dm_set_device_limits, - &ti_limits); - - /* - * Check each device area is consistent with the target's - * overall queue limits. - */ - if (!ti->type->iterate_devices(ti, device_area_is_valid, - &ti_limits)) - return -EINVAL; - -combine_limits: - /* - * Merge this target's queue limits into the overall limits - * for the table. - */ - if (blk_stack_limits(limits, &ti_limits, 0) < 0) - DMWARN("%s: target device " - "(start sect %llu len %llu) " - "is misaligned", - dm_device_name(table->md), - (unsigned long long) ti->begin, - (unsigned long long) ti->len); - } - - return validate_hardware_logical_block_alignment(table, limits); -} - /* * Set the integrity profile for this device if all devices used have * matching profiles. @@ -1065,42 +907,27 @@ static void dm_table_set_integrity(struct dm_table *t) return; } -void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, - struct queue_limits *limits) +void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q) { /* - * Each target device in the table has a data area that should normally - * be aligned such that the DM device's alignment_offset is 0. - * FIXME: Propagate alignment_offsets up the stack and warn of - * sub-optimal or inconsistent settings. - */ - limits->alignment_offset = 0; - limits->misaligned = 0; - - /* - * Copy table's limits to the DM device's request_queue + * Make sure we obey the optimistic sub devices + * restrictions. */ - q->limits = *limits; - - if (limits->no_cluster) + blk_queue_max_sectors(q, t->limits.max_sectors); + blk_queue_max_phys_segments(q, t->limits.max_phys_segments); + blk_queue_max_hw_segments(q, t->limits.max_hw_segments); + blk_queue_logical_block_size(q, t->limits.logical_block_size); + blk_queue_max_segment_size(q, t->limits.max_segment_size); + blk_queue_max_hw_sectors(q, t->limits.max_hw_sectors); + blk_queue_segment_boundary(q, t->limits.seg_boundary_mask); + blk_queue_bounce_limit(q, t->limits.bounce_pfn); + + if (t->limits.no_cluster) queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); else queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q); dm_table_set_integrity(t); - - /* - * QUEUE_FLAG_STACKABLE must be set after all queue settings are - * visible to other CPUs because, once the flag is set, incoming bios - * are processed by request-based dm, which refers to the queue - * settings. - * Until the flag set, bios are passed to bio-based dm and queued to - * md->deferred where queue settings are not needed yet. - * Those bios are passed to request-based dm at the resume time. - */ - smp_mb(); - if (dm_table_request_based(t)) - queue_flag_set_unlocked(QUEUE_FLAG_STACKABLE, q); } unsigned int dm_table_get_num_targets(struct dm_table *t) @@ -1196,20 +1023,6 @@ int dm_table_any_congested(struct dm_table *t, int bdi_bits) return r; } -int dm_table_any_busy_target(struct dm_table *t) -{ - unsigned i; - struct dm_target *ti; - - for (i = 0; i < t->num_targets; i++) { - ti = t->targets + i; - if (ti->type->busy && ti->type->busy(ti)) - return 1; - } - - return 0; -} - void dm_table_unplug_all(struct dm_table *t) { struct dm_dev_internal *dd; diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 9acd54a5cffb..48db308fae67 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -24,13 +24,6 @@ #define DM_MSG_PREFIX "core" -/* - * Cookies are numeric values sent with CHANGE and REMOVE - * uevents while resuming, removing or renaming the device. - */ -#define DM_COOKIE_ENV_VAR_NAME "DM_COOKIE" -#define DM_COOKIE_LENGTH 24 - static const char *_name = DM_NAME; static unsigned int major = 0; @@ -78,7 +71,7 @@ struct dm_rq_target_io { */ struct dm_rq_clone_bio_info { struct bio *orig; - struct dm_rq_target_io *tio; + struct request *rq; }; union map_info *dm_get_mapinfo(struct bio *bio) @@ -88,14 +81,6 @@ union map_info *dm_get_mapinfo(struct bio *bio) return NULL; } -union map_info *dm_get_rq_mapinfo(struct request *rq) -{ - if (rq && rq->end_io_data) - return &((struct dm_rq_target_io *)rq->end_io_data)->info; - return NULL; -} -EXPORT_SYMBOL_GPL(dm_get_rq_mapinfo); - #define MINOR_ALLOCED ((void *)-1) /* @@ -172,31 +157,13 @@ struct mapped_device { * freeze/thaw support require holding onto a super block */ struct super_block *frozen_sb; - struct block_device *bdev; + struct block_device *suspended_bdev; /* forced geometry settings */ struct hd_geometry geometry; - /* marker of flush suspend for request-based dm */ - struct request suspend_rq; - - /* For saving the address of __make_request for request based dm */ - make_request_fn *saved_make_request_fn; - /* sysfs handle */ struct kobject kobj; - - /* zero-length barrier that will be cloned and submitted to targets */ - struct bio barrier_bio; -}; - -/* - * For mempools pre-allocation at the table loading time. - */ -struct dm_md_mempools { - mempool_t *io_pool; - mempool_t *tio_pool; - struct bio_set *bs; }; #define MIN_IOS 256 @@ -424,29 +391,14 @@ static void free_io(struct mapped_device *md, struct dm_io *io) mempool_free(io, md->io_pool); } -static void free_tio(struct mapped_device *md, struct dm_target_io *tio) -{ - mempool_free(tio, md->tio_pool); -} - -static struct dm_rq_target_io *alloc_rq_tio(struct mapped_device *md) -{ - return mempool_alloc(md->tio_pool, GFP_ATOMIC); -} - -static void free_rq_tio(struct dm_rq_target_io *tio) -{ - mempool_free(tio, tio->md->tio_pool); -} - -static struct dm_rq_clone_bio_info *alloc_bio_info(struct mapped_device *md) +static struct dm_target_io *alloc_tio(struct mapped_device *md) { - return mempool_alloc(md->io_pool, GFP_ATOMIC); + return mempool_alloc(md->tio_pool, GFP_NOIO); } -static void free_bio_info(struct dm_rq_clone_bio_info *info) +static void free_tio(struct mapped_device *md, struct dm_target_io *tio) { - mempool_free(info, info->tio->md->io_pool); + mempool_free(tio, md->tio_pool); } static void start_io_acct(struct dm_io *io) @@ -512,13 +464,12 @@ static void queue_io(struct mapped_device *md, struct bio *bio) struct dm_table *dm_get_table(struct mapped_device *md) { struct dm_table *t; - unsigned long flags; - read_lock_irqsave(&md->map_lock, flags); + read_lock(&md->map_lock); t = md->map; if (t) dm_table_get(t); - read_unlock_irqrestore(&md->map_lock, flags); + read_unlock(&md->map_lock); return t; } @@ -585,11 +536,9 @@ static void dec_pending(struct dm_io *io, int error) * Target requested pushing back the I/O. */ spin_lock_irqsave(&md->deferred_lock, flags); - if (__noflush_suspending(md)) { - if (!bio_barrier(io->bio)) - bio_list_add_head(&md->deferred, - io->bio); - } else + if (__noflush_suspending(md)) + bio_list_add_head(&md->deferred, io->bio); + else /* noflush suspend was interrupted. */ io->error = -EIO; spin_unlock_irqrestore(&md->deferred_lock, flags); @@ -604,8 +553,7 @@ static void dec_pending(struct dm_io *io, int error) * a per-device variable for error reporting. * Note that you can't touch the bio after end_io_acct */ - if (!md->barrier_error && io_error != -EOPNOTSUPP) - md->barrier_error = io_error; + md->barrier_error = io_error; end_io_acct(io); } else { end_io_acct(io); @@ -659,262 +607,6 @@ static void clone_endio(struct bio *bio, int error) dec_pending(io, error); } -/* - * Partial completion handling for request-based dm - */ -static void end_clone_bio(struct bio *clone, int error) -{ - struct dm_rq_clone_bio_info *info = clone->bi_private; - struct dm_rq_target_io *tio = info->tio; - struct bio *bio = info->orig; - unsigned int nr_bytes = info->orig->bi_size; - - bio_put(clone); - - if (tio->error) - /* - * An error has already been detected on the request. - * Once error occurred, just let clone->end_io() handle - * the remainder. - */ - return; - else if (error) { - /* - * Don't notice the error to the upper layer yet. - * The error handling decision is made by the target driver, - * when the request is completed. - */ - tio->error = error; - return; - } - - /* - * I/O for the bio successfully completed. - * Notice the data completion to the upper layer. - */ - - /* - * bios are processed from the head of the list. - * So the completing bio should always be rq->bio. - * If it's not, something wrong is happening. - */ - if (tio->orig->bio != bio) - DMERR("bio completion is going in the middle of the request"); - - /* - * Update the original request. - * Do not use blk_end_request() here, because it may complete - * the original request before the clone, and break the ordering. - */ - blk_update_request(tio->orig, 0, nr_bytes); -} - -/* - * Don't touch any member of the md after calling this function because - * the md may be freed in dm_put() at the end of this function. - * Or do dm_get() before calling this function and dm_put() later. - */ -static void rq_completed(struct mapped_device *md, int run_queue) -{ - int wakeup_waiters = 0; - struct request_queue *q = md->queue; - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - if (!queue_in_flight(q)) - wakeup_waiters = 1; - spin_unlock_irqrestore(q->queue_lock, flags); - - /* nudge anyone waiting on suspend queue */ - if (wakeup_waiters) - wake_up(&md->wait); - - if (run_queue) - blk_run_queue(q); - - /* - * dm_put() must be at the end of this function. See the comment above - */ - dm_put(md); -} - -static void dm_unprep_request(struct request *rq) -{ - struct request *clone = rq->special; - struct dm_rq_target_io *tio = clone->end_io_data; - - rq->special = NULL; - rq->cmd_flags &= ~REQ_DONTPREP; - - blk_rq_unprep_clone(clone); - free_rq_tio(tio); -} - -/* - * Requeue the original request of a clone. - */ -void dm_requeue_unmapped_request(struct request *clone) -{ - struct dm_rq_target_io *tio = clone->end_io_data; - struct mapped_device *md = tio->md; - struct request *rq = tio->orig; - struct request_queue *q = rq->q; - unsigned long flags; - - dm_unprep_request(rq); - - spin_lock_irqsave(q->queue_lock, flags); - if (elv_queue_empty(q)) - blk_plug_device(q); - blk_requeue_request(q, rq); - spin_unlock_irqrestore(q->queue_lock, flags); - - rq_completed(md, 0); -} -EXPORT_SYMBOL_GPL(dm_requeue_unmapped_request); - -static void __stop_queue(struct request_queue *q) -{ - blk_stop_queue(q); -} - -static void stop_queue(struct request_queue *q) -{ - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - __stop_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); -} - -static void __start_queue(struct request_queue *q) -{ - if (blk_queue_stopped(q)) - blk_start_queue(q); -} - -static void start_queue(struct request_queue *q) -{ - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - __start_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); -} - -/* - * Complete the clone and the original request. - * Must be called without queue lock. - */ -static void dm_end_request(struct request *clone, int error) -{ - struct dm_rq_target_io *tio = clone->end_io_data; - struct mapped_device *md = tio->md; - struct request *rq = tio->orig; - - if (blk_pc_request(rq)) { - rq->errors = clone->errors; - rq->resid_len = clone->resid_len; - - if (rq->sense) - /* - * We are using the sense buffer of the original - * request. - * So setting the length of the sense data is enough. - */ - rq->sense_len = clone->sense_len; - } - - BUG_ON(clone->bio); - free_rq_tio(tio); - - blk_end_request_all(rq, error); - - rq_completed(md, 1); -} - -/* - * Request completion handler for request-based dm - */ -static void dm_softirq_done(struct request *rq) -{ - struct request *clone = rq->completion_data; - struct dm_rq_target_io *tio = clone->end_io_data; - dm_request_endio_fn rq_end_io = tio->ti->type->rq_end_io; - int error = tio->error; - - if (!(rq->cmd_flags & REQ_FAILED) && rq_end_io) - error = rq_end_io(tio->ti, clone, error, &tio->info); - - if (error <= 0) - /* The target wants to complete the I/O */ - dm_end_request(clone, error); - else if (error == DM_ENDIO_INCOMPLETE) - /* The target will handle the I/O */ - return; - else if (error == DM_ENDIO_REQUEUE) - /* The target wants to requeue the I/O */ - dm_requeue_unmapped_request(clone); - else { - DMWARN("unimplemented target endio return value: %d", error); - BUG(); - } -} - -/* - * Complete the clone and the original request with the error status - * through softirq context. - */ -static void dm_complete_request(struct request *clone, int error) -{ - struct dm_rq_target_io *tio = clone->end_io_data; - struct request *rq = tio->orig; - - tio->error = error; - rq->completion_data = clone; - blk_complete_request(rq); -} - -/* - * Complete the not-mapped clone and the original request with the error status - * through softirq context. - * Target's rq_end_io() function isn't called. - * This may be used when the target's map_rq() function fails. - */ -void dm_kill_unmapped_request(struct request *clone, int error) -{ - struct dm_rq_target_io *tio = clone->end_io_data; - struct request *rq = tio->orig; - - rq->cmd_flags |= REQ_FAILED; - dm_complete_request(clone, error); -} -EXPORT_SYMBOL_GPL(dm_kill_unmapped_request); - -/* - * Called with the queue lock held - */ -static void end_clone_request(struct request *clone, int error) -{ - /* - * For just cleaning up the information of the queue in which - * the clone was dispatched. - * The clone is *NOT* freed actually here because it is alloced from - * dm own mempool and REQ_ALLOCED isn't set in clone->cmd_flags. - */ - __blk_put_request(clone->q, clone); - - /* - * Actual request completion is done in a softirq context which doesn't - * hold the queue lock. Otherwise, deadlock could occur because: - * - another request may be submitted by the upper level driver - * of the stacking during the completion - * - the submission which requires queue lock may be done - * against this queue - */ - dm_complete_request(clone, error); -} - static sector_t max_io_len(struct mapped_device *md, sector_t sector, struct dm_target *ti) { @@ -942,6 +634,11 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, sector_t sector; struct mapped_device *md; + /* + * Sanity checks. + */ + BUG_ON(!clone->bi_size); + clone->bi_end_io = clone_endio; clone->bi_private = tio; @@ -1017,7 +714,7 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector, clone->bi_flags |= 1 << BIO_CLONED; if (bio_integrity(bio)) { - bio_integrity_clone(clone, bio, GFP_NOIO, bs); + bio_integrity_clone(clone, bio, GFP_NOIO); bio_integrity_trim(clone, bio_sector_offset(bio, idx, offset), len); } @@ -1045,7 +742,7 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector, clone->bi_flags &= ~(1 << BIO_SEG_VALID); if (bio_integrity(bio)) { - bio_integrity_clone(clone, bio, GFP_NOIO, bs); + bio_integrity_clone(clone, bio, GFP_NOIO); if (idx != bio->bi_idx || clone->bi_size < bio->bi_size) bio_integrity_trim(clone, @@ -1055,48 +752,6 @@ static struct bio *clone_bio(struct bio *bio, sector_t sector, return clone; } -static struct dm_target_io *alloc_tio(struct clone_info *ci, - struct dm_target *ti) -{ - struct dm_target_io *tio = mempool_alloc(ci->md->tio_pool, GFP_NOIO); - - tio->io = ci->io; - tio->ti = ti; - memset(&tio->info, 0, sizeof(tio->info)); - - return tio; -} - -static void __flush_target(struct clone_info *ci, struct dm_target *ti, - unsigned flush_nr) -{ - struct dm_target_io *tio = alloc_tio(ci, ti); - struct bio *clone; - - tio->info.flush_request = flush_nr; - - clone = bio_alloc_bioset(GFP_NOIO, 0, ci->md->bs); - __bio_clone(clone, ci->bio); - clone->bi_destructor = dm_bio_destructor; - - __map_bio(ti, clone, tio); -} - -static int __clone_and_map_empty_barrier(struct clone_info *ci) -{ - unsigned target_nr = 0, flush_nr; - struct dm_target *ti; - - while ((ti = dm_table_get_target(ci->map, target_nr++))) - for (flush_nr = 0; flush_nr < ti->num_flush_requests; - flush_nr++) - __flush_target(ci, ti, flush_nr); - - ci->sector_count = 0; - - return 0; -} - static int __clone_and_map(struct clone_info *ci) { struct bio *clone, *bio = ci->bio; @@ -1104,9 +759,6 @@ static int __clone_and_map(struct clone_info *ci) sector_t len = 0, max; struct dm_target_io *tio; - if (unlikely(bio_empty_barrier(bio))) - return __clone_and_map_empty_barrier(ci); - ti = dm_table_find_target(ci->map, ci->sector); if (!dm_target_is_valid(ti)) return -EIO; @@ -1116,7 +768,10 @@ static int __clone_and_map(struct clone_info *ci) /* * Allocate a target io object. */ - tio = alloc_tio(ci, ti); + tio = alloc_tio(ci->md); + tio->io = ci->io; + tio->ti = ti; + memset(&tio->info, 0, sizeof(tio->info)); if (ci->sector_count <= max) { /* @@ -1172,7 +827,10 @@ static int __clone_and_map(struct clone_info *ci) max = max_io_len(ci->md, ci->sector, ti); - tio = alloc_tio(ci, ti); + tio = alloc_tio(ci->md); + tio->io = ci->io; + tio->ti = ti; + memset(&tio->info, 0, sizeof(tio->info)); } len = min(remaining, max); @@ -1207,8 +865,7 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) if (!bio_barrier(bio)) bio_io_error(bio); else - if (!md->barrier_error) - md->barrier_error = -EIO; + md->barrier_error = -EIO; return; } @@ -1221,8 +878,6 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) ci.io->md = md; ci.sector = bio->bi_sector; ci.sector_count = bio_sectors(bio); - if (unlikely(bio_empty_barrier(bio))) - ci.sector_count = 1; ci.idx = bio->bi_idx; start_io_acct(ci.io); @@ -1270,16 +925,6 @@ static int dm_merge_bvec(struct request_queue *q, */ if (max_size && ti->type->merge) max_size = ti->type->merge(ti, bvm, biovec, max_size); - /* - * If the target doesn't support merge method and some of the devices - * provided their merge_bvec method (we know this by looking at - * queue_max_hw_sectors), then we can't allow bios with multiple vector - * entries. So always set max_size to 0, and the code below allows - * just one page. - */ - else if (queue_max_hw_sectors(q) <= PAGE_SIZE >> 9) - - max_size = 0; out_table: dm_table_put(map); @@ -1298,7 +943,7 @@ static int dm_merge_bvec(struct request_queue *q, * The request function that just remaps the bio built up by * dm_merge_bvec. */ -static int _dm_request(struct request_queue *q, struct bio *bio) +static int dm_request(struct request_queue *q, struct bio *bio) { int rw = bio_data_dir(bio); struct mapped_device *md = q->queuedata; @@ -1335,274 +980,12 @@ static int _dm_request(struct request_queue *q, struct bio *bio) return 0; } -static int dm_make_request(struct request_queue *q, struct bio *bio) -{ - struct mapped_device *md = q->queuedata; - - if (unlikely(bio_barrier(bio))) { - bio_endio(bio, -EOPNOTSUPP); - return 0; - } - - return md->saved_make_request_fn(q, bio); /* call __make_request() */ -} - -static int dm_request_based(struct mapped_device *md) -{ - return blk_queue_stackable(md->queue); -} - -static int dm_request(struct request_queue *q, struct bio *bio) -{ - struct mapped_device *md = q->queuedata; - - if (dm_request_based(md)) - return dm_make_request(q, bio); - - return _dm_request(q, bio); -} - -void dm_dispatch_request(struct request *rq) -{ - int r; - - if (blk_queue_io_stat(rq->q)) - rq->cmd_flags |= REQ_IO_STAT; - - rq->start_time = jiffies; - r = blk_insert_cloned_request(rq->q, rq); - if (r) - dm_complete_request(rq, r); -} -EXPORT_SYMBOL_GPL(dm_dispatch_request); - -static void dm_rq_bio_destructor(struct bio *bio) -{ - struct dm_rq_clone_bio_info *info = bio->bi_private; - struct mapped_device *md = info->tio->md; - - free_bio_info(info); - bio_free(bio, md->bs); -} - -static int dm_rq_bio_constructor(struct bio *bio, struct bio *bio_orig, - void *data) -{ - struct dm_rq_target_io *tio = data; - struct mapped_device *md = tio->md; - struct dm_rq_clone_bio_info *info = alloc_bio_info(md); - - if (!info) - return -ENOMEM; - - info->orig = bio_orig; - info->tio = tio; - bio->bi_end_io = end_clone_bio; - bio->bi_private = info; - bio->bi_destructor = dm_rq_bio_destructor; - - return 0; -} - -static int setup_clone(struct request *clone, struct request *rq, - struct dm_rq_target_io *tio) -{ - int r = blk_rq_prep_clone(clone, rq, tio->md->bs, GFP_ATOMIC, - dm_rq_bio_constructor, tio); - - if (r) - return r; - - clone->cmd = rq->cmd; - clone->cmd_len = rq->cmd_len; - clone->sense = rq->sense; - clone->buffer = rq->buffer; - clone->end_io = end_clone_request; - clone->end_io_data = tio; - - return 0; -} - -static int dm_rq_flush_suspending(struct mapped_device *md) -{ - return !md->suspend_rq.special; -} - -/* - * Called with the queue lock held. - */ -static int dm_prep_fn(struct request_queue *q, struct request *rq) -{ - struct mapped_device *md = q->queuedata; - struct dm_rq_target_io *tio; - struct request *clone; - - if (unlikely(rq == &md->suspend_rq)) { - if (dm_rq_flush_suspending(md)) - return BLKPREP_OK; - else - /* The flush suspend was interrupted */ - return BLKPREP_KILL; - } - - if (unlikely(rq->special)) { - DMWARN("Already has something in rq->special."); - return BLKPREP_KILL; - } - - tio = alloc_rq_tio(md); /* Only one for each original request */ - if (!tio) - /* -ENOMEM */ - return BLKPREP_DEFER; - - tio->md = md; - tio->ti = NULL; - tio->orig = rq; - tio->error = 0; - memset(&tio->info, 0, sizeof(tio->info)); - - clone = &tio->clone; - if (setup_clone(clone, rq, tio)) { - /* -ENOMEM */ - free_rq_tio(tio); - return BLKPREP_DEFER; - } - - rq->special = clone; - rq->cmd_flags |= REQ_DONTPREP; - - return BLKPREP_OK; -} - -static void map_request(struct dm_target *ti, struct request *rq, - struct mapped_device *md) -{ - int r; - struct request *clone = rq->special; - struct dm_rq_target_io *tio = clone->end_io_data; - - /* - * Hold the md reference here for the in-flight I/O. - * We can't rely on the reference count by device opener, - * because the device may be closed during the request completion - * when all bios are completed. - * See the comment in rq_completed() too. - */ - dm_get(md); - - tio->ti = ti; - r = ti->type->map_rq(ti, clone, &tio->info); - switch (r) { - case DM_MAPIO_SUBMITTED: - /* The target has taken the I/O to submit by itself later */ - break; - case DM_MAPIO_REMAPPED: - /* The target has remapped the I/O so dispatch it */ - dm_dispatch_request(clone); - break; - case DM_MAPIO_REQUEUE: - /* The target wants to requeue the I/O */ - dm_requeue_unmapped_request(clone); - break; - default: - if (r > 0) { - DMWARN("unimplemented target map return value: %d", r); - BUG(); - } - - /* The target wants to complete the I/O */ - dm_kill_unmapped_request(clone, r); - break; - } -} - -/* - * q->request_fn for request-based dm. - * Called with the queue lock held. - */ -static void dm_request_fn(struct request_queue *q) -{ - struct mapped_device *md = q->queuedata; - struct dm_table *map = dm_get_table(md); - struct dm_target *ti; - struct request *rq; - - /* - * For noflush suspend, check blk_queue_stopped() to immediately - * quit I/O dispatching. - */ - while (!blk_queue_plugged(q) && !blk_queue_stopped(q)) { - rq = blk_peek_request(q); - if (!rq) - goto plug_and_out; - - if (unlikely(rq == &md->suspend_rq)) { /* Flush suspend maker */ - if (queue_in_flight(q)) - /* Not quiet yet. Wait more */ - goto plug_and_out; - - /* This device should be quiet now */ - __stop_queue(q); - blk_start_request(rq); - __blk_end_request_all(rq, 0); - wake_up(&md->wait); - goto out; - } - - ti = dm_table_find_target(map, blk_rq_pos(rq)); - if (ti->type->busy && ti->type->busy(ti)) - goto plug_and_out; - - blk_start_request(rq); - spin_unlock(q->queue_lock); - map_request(ti, rq, md); - spin_lock_irq(q->queue_lock); - } - - goto out; - -plug_and_out: - if (!elv_queue_empty(q)) - /* Some requests still remain, retry later */ - blk_plug_device(q); - -out: - dm_table_put(map); - - return; -} - -int dm_underlying_device_busy(struct request_queue *q) -{ - return blk_lld_busy(q); -} -EXPORT_SYMBOL_GPL(dm_underlying_device_busy); - -static int dm_lld_busy(struct request_queue *q) -{ - int r; - struct mapped_device *md = q->queuedata; - struct dm_table *map = dm_get_table(md); - - if (!map || test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) - r = 1; - else - r = dm_table_any_busy_target(map); - - dm_table_put(map); - - return r; -} - static void dm_unplug_all(struct request_queue *q) { struct mapped_device *md = q->queuedata; struct dm_table *map = dm_get_table(md); if (map) { - if (dm_request_based(md)) - generic_unplug_device(q); - dm_table_unplug_all(map); dm_table_put(map); } @@ -1617,16 +1000,7 @@ static int dm_any_congested(void *congested_data, int bdi_bits) if (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) { map = dm_get_table(md); if (map) { - /* - * Request-based dm cares about only own queue for - * the query about congestion status of request_queue - */ - if (dm_request_based(md)) - r = md->queue->backing_dev_info.state & - bdi_bits; - else - r = dm_table_any_congested(map, bdi_bits); - + r = dm_table_any_congested(map, bdi_bits); dm_table_put(map); } } @@ -1749,32 +1123,30 @@ static struct mapped_device *alloc_dev(int minor) INIT_LIST_HEAD(&md->uevent_list); spin_lock_init(&md->uevent_lock); - md->queue = blk_init_queue(dm_request_fn, NULL); + md->queue = blk_alloc_queue(GFP_KERNEL); if (!md->queue) goto bad_queue; - /* - * Request-based dm devices cannot be stacked on top of bio-based dm - * devices. The type of this dm device has not been decided yet, - * although we initialized the queue using blk_init_queue(). - * The type is decided at the first table loading time. - * To prevent problematic device stacking, clear the queue flag - * for request stacking support until then. - * - * This queue is new, so no concurrency on the queue_flags. - */ - queue_flag_clear_unlocked(QUEUE_FLAG_STACKABLE, md->queue); - md->saved_make_request_fn = md->queue->make_request_fn; md->queue->queuedata = md; md->queue->backing_dev_info.congested_fn = dm_any_congested; md->queue->backing_dev_info.congested_data = md; blk_queue_make_request(md->queue, dm_request); + blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL); blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); md->queue->unplug_fn = dm_unplug_all; blk_queue_merge_bvec(md->queue, dm_merge_bvec); - blk_queue_softirq_done(md->queue, dm_softirq_done); - blk_queue_prep_rq(md->queue, dm_prep_fn); - blk_queue_lld_busy(md->queue, dm_lld_busy); + + md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache); + if (!md->io_pool) + goto bad_io_pool; + + md->tio_pool = mempool_create_slab_pool(MIN_IOS, _tio_cache); + if (!md->tio_pool) + goto bad_tio_pool; + + md->bs = bioset_create(16, 0); + if (!md->bs) + goto bad_no_bioset; md->disk = alloc_disk(1); if (!md->disk) @@ -1798,10 +1170,6 @@ static struct mapped_device *alloc_dev(int minor) if (!md->wq) goto bad_thread; - md->bdev = bdget_disk(md->disk, 0); - if (!md->bdev) - goto bad_bdev; - /* Populate the mapping, nobody knows we exist yet */ spin_lock(&_minor_lock); old_md = idr_replace(&_minor_idr, md, minor); @@ -1811,11 +1179,15 @@ static struct mapped_device *alloc_dev(int minor) return md; -bad_bdev: - destroy_workqueue(md->wq); bad_thread: put_disk(md->disk); bad_disk: + bioset_free(md->bs); +bad_no_bioset: + mempool_destroy(md->tio_pool); +bad_tio_pool: + mempool_destroy(md->io_pool); +bad_io_pool: blk_cleanup_queue(md->queue); bad_queue: free_minor(minor); @@ -1832,15 +1204,14 @@ static void free_dev(struct mapped_device *md) { int minor = MINOR(disk_devt(md->disk)); - unlock_fs(md); - bdput(md->bdev); + if (md->suspended_bdev) { + unlock_fs(md); + bdput(md->suspended_bdev); + } destroy_workqueue(md->wq); - if (md->tio_pool) - mempool_destroy(md->tio_pool); - if (md->io_pool) - mempool_destroy(md->io_pool); - if (md->bs) - bioset_free(md->bs); + mempool_destroy(md->tio_pool); + mempool_destroy(md->io_pool); + bioset_free(md->bs); blk_integrity_unregister(md->disk); del_gendisk(md->disk); free_minor(minor); @@ -1855,29 +1226,6 @@ static void free_dev(struct mapped_device *md) kfree(md); } -static void __bind_mempools(struct mapped_device *md, struct dm_table *t) -{ - struct dm_md_mempools *p; - - if (md->io_pool && md->tio_pool && md->bs) - /* the md already has necessary mempools */ - goto out; - - p = dm_table_get_md_mempools(t); - BUG_ON(!p || md->io_pool || md->tio_pool || md->bs); - - md->io_pool = p->io_pool; - p->io_pool = NULL; - md->tio_pool = p->tio_pool; - p->tio_pool = NULL; - md->bs = p->bs; - p->bs = NULL; - -out: - /* mempool bind completed, now no need any mempools in the table */ - dm_table_free_md_mempools(t); -} - /* * Bind a table to the device. */ @@ -1901,17 +1249,15 @@ static void __set_size(struct mapped_device *md, sector_t size) { set_capacity(md->disk, size); - mutex_lock(&md->bdev->bd_inode->i_mutex); - i_size_write(md->bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); - mutex_unlock(&md->bdev->bd_inode->i_mutex); + mutex_lock(&md->suspended_bdev->bd_inode->i_mutex); + i_size_write(md->suspended_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); + mutex_unlock(&md->suspended_bdev->bd_inode->i_mutex); } -static int __bind(struct mapped_device *md, struct dm_table *t, - struct queue_limits *limits) +static int __bind(struct mapped_device *md, struct dm_table *t) { struct request_queue *q = md->queue; sector_t size; - unsigned long flags; size = dm_table_get_size(t); @@ -1921,7 +1267,8 @@ static int __bind(struct mapped_device *md, struct dm_table *t, if (size != get_capacity(md->disk)) memset(&md->geometry, 0, sizeof(md->geometry)); - __set_size(md, size); + if (md->suspended_bdev) + __set_size(md, size); if (!size) { dm_table_destroy(t); @@ -1930,22 +1277,10 @@ static int __bind(struct mapped_device *md, struct dm_table *t, dm_table_event_callback(t, event_callback, md); - /* - * The queue hasn't been stopped yet, if the old table type wasn't - * for request-based during suspension. So stop it to prevent - * I/O mapping before resume. - * This must be done before setting the queue restrictions, - * because request-based dm may be run just after the setting. - */ - if (dm_table_request_based(t) && !blk_queue_stopped(q)) - stop_queue(q); - - __bind_mempools(md, t); - - write_lock_irqsave(&md->map_lock, flags); + write_lock(&md->map_lock); md->map = t; - dm_table_set_restrictions(t, q, limits); - write_unlock_irqrestore(&md->map_lock, flags); + dm_table_set_restrictions(t, q); + write_unlock(&md->map_lock); return 0; } @@ -1953,15 +1288,14 @@ static int __bind(struct mapped_device *md, struct dm_table *t, static void __unbind(struct mapped_device *md) { struct dm_table *map = md->map; - unsigned long flags; if (!map) return; dm_table_event_callback(map, NULL, NULL); - write_lock_irqsave(&md->map_lock, flags); + write_lock(&md->map_lock); md->map = NULL; - write_unlock_irqrestore(&md->map_lock, flags); + write_unlock(&md->map_lock); dm_table_destroy(map); } @@ -2065,8 +1399,6 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) { int r = 0; DECLARE_WAITQUEUE(wait, current); - struct request_queue *q = md->queue; - unsigned long flags; dm_unplug_all(md->queue); @@ -2076,14 +1408,7 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) set_current_state(interruptible); smp_mb(); - if (dm_request_based(md)) { - spin_lock_irqsave(q->queue_lock, flags); - if (!queue_in_flight(q) && blk_queue_stopped(q)) { - spin_unlock_irqrestore(q->queue_lock, flags); - break; - } - spin_unlock_irqrestore(q->queue_lock, flags); - } else if (!atomic_read(&md->pending)) + if (!atomic_read(&md->pending)) break; if (interruptible == TASK_INTERRUPTIBLE && @@ -2101,36 +1426,34 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible) return r; } -static void dm_flush(struct mapped_device *md) +static int dm_flush(struct mapped_device *md) { dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE); - - bio_init(&md->barrier_bio); - md->barrier_bio.bi_bdev = md->bdev; - md->barrier_bio.bi_rw = WRITE_BARRIER; - __split_and_process_bio(md, &md->barrier_bio); - - dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE); + return 0; } static void process_barrier(struct mapped_device *md, struct bio *bio) { - md->barrier_error = 0; - - dm_flush(md); + int error = dm_flush(md); - if (!bio_empty_barrier(bio)) { - __split_and_process_bio(md, bio); - dm_flush(md); + if (unlikely(error)) { + bio_endio(bio, error); + return; } + if (bio_empty_barrier(bio)) { + bio_endio(bio, 0); + return; + } + + __split_and_process_bio(md, bio); + + error = dm_flush(md); + + if (!error && md->barrier_error) + error = md->barrier_error; if (md->barrier_error != DM_ENDIO_REQUEUE) - bio_endio(bio, md->barrier_error); - else { - spin_lock_irq(&md->deferred_lock); - bio_list_add_head(&md->deferred, bio); - spin_unlock_irq(&md->deferred_lock); - } + bio_endio(bio, error); } /* @@ -2156,14 +1479,10 @@ static void dm_wq_work(struct work_struct *work) up_write(&md->io_lock); - if (dm_request_based(md)) - generic_make_request(c); - else { - if (bio_barrier(c)) - process_barrier(md, c); - else - __split_and_process_bio(md, c); - } + if (bio_barrier(c)) + process_barrier(md, c); + else + __split_and_process_bio(md, c); down_write(&md->io_lock); } @@ -2183,7 +1502,6 @@ static void dm_queue_flush(struct mapped_device *md) */ int dm_swap_table(struct mapped_device *md, struct dm_table *table) { - struct queue_limits limits; int r = -EINVAL; mutex_lock(&md->suspend_lock); @@ -2192,96 +1510,19 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) if (!dm_suspended(md)) goto out; - r = dm_calculate_queue_limits(table, &limits); - if (r) - goto out; - - /* cannot change the device type, once a table is bound */ - if (md->map && - (dm_table_get_type(md->map) != dm_table_get_type(table))) { - DMWARN("can't change the device type after a table is bound"); - goto out; - } - - /* - * It is enought that blk_queue_ordered() is called only once when - * the first bio-based table is bound. - * - * This setting should be moved to alloc_dev() when request-based dm - * supports barrier. - */ - if (!md->map && dm_table_bio_based(table)) - blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL); + /* without bdev, the device size cannot be changed */ + if (!md->suspended_bdev) + if (get_capacity(md->disk) != dm_table_get_size(table)) + goto out; __unbind(md); - r = __bind(md, table, &limits); + r = __bind(md, table); out: mutex_unlock(&md->suspend_lock); return r; } -static void dm_rq_invalidate_suspend_marker(struct mapped_device *md) -{ - md->suspend_rq.special = (void *)0x1; -} - -static void dm_rq_abort_suspend(struct mapped_device *md, int noflush) -{ - struct request_queue *q = md->queue; - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - if (!noflush) - dm_rq_invalidate_suspend_marker(md); - __start_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); -} - -static void dm_rq_start_suspend(struct mapped_device *md, int noflush) -{ - struct request *rq = &md->suspend_rq; - struct request_queue *q = md->queue; - - if (noflush) - stop_queue(q); - else { - blk_rq_init(q, rq); - blk_insert_request(q, rq, 0, NULL); - } -} - -static int dm_rq_suspend_available(struct mapped_device *md, int noflush) -{ - int r = 1; - struct request *rq = &md->suspend_rq; - struct request_queue *q = md->queue; - unsigned long flags; - - if (noflush) - return r; - - /* The marker must be protected by queue lock if it is in use */ - spin_lock_irqsave(q->queue_lock, flags); - if (unlikely(rq->ref_count)) { - /* - * This can happen, when the previous flush suspend was - * interrupted, the marker is still in the queue and - * this flush suspend has been invoked, because we don't - * remove the marker at the time of suspend interruption. - * We have only one marker per mapped_device, so we can't - * start another flush suspend while it is in use. - */ - BUG_ON(!rq->special); /* The marker should be invalidated */ - DMWARN("Invalidating the previous flush suspend is still in" - " progress. Please retry later."); - r = 0; - } - spin_unlock_irqrestore(q->queue_lock, flags); - - return r; -} - /* * Functions to lock and unlock any filesystem running on the * device. @@ -2292,7 +1533,7 @@ static int lock_fs(struct mapped_device *md) WARN_ON(md->frozen_sb); - md->frozen_sb = freeze_bdev(md->bdev); + md->frozen_sb = freeze_bdev(md->suspended_bdev); if (IS_ERR(md->frozen_sb)) { r = PTR_ERR(md->frozen_sb); md->frozen_sb = NULL; @@ -2301,6 +1542,9 @@ static int lock_fs(struct mapped_device *md) set_bit(DMF_FROZEN, &md->flags); + /* don't bdput right now, we don't want the bdev + * to go away while it is locked. + */ return 0; } @@ -2309,7 +1553,7 @@ static void unlock_fs(struct mapped_device *md) if (!test_bit(DMF_FROZEN, &md->flags)) return; - thaw_bdev(md->bdev, md->frozen_sb); + thaw_bdev(md->suspended_bdev, md->frozen_sb); md->frozen_sb = NULL; clear_bit(DMF_FROZEN, &md->flags); } @@ -2321,53 +1565,6 @@ static void unlock_fs(struct mapped_device *md) * dm_bind_table, dm_suspend must be called to flush any in * flight bios and ensure that any further io gets deferred. */ -/* - * Suspend mechanism in request-based dm. - * - * After the suspend starts, further incoming requests are kept in - * the request_queue and deferred. - * Remaining requests in the request_queue at the start of suspend are flushed - * if it is flush suspend. - * The suspend completes when the following conditions have been satisfied, - * so wait for it: - * 1. q->in_flight is 0 (which means no in_flight request) - * 2. queue has been stopped (which means no request dispatching) - * - * - * Noflush suspend - * --------------- - * Noflush suspend doesn't need to dispatch remaining requests. - * So stop the queue immediately. Then, wait for all in_flight requests - * to be completed or requeued. - * - * To abort noflush suspend, start the queue. - * - * - * Flush suspend - * ------------- - * Flush suspend needs to dispatch remaining requests. So stop the queue - * after the remaining requests are completed. (Requeued request must be also - * re-dispatched and completed. Until then, we can't stop the queue.) - * - * During flushing the remaining requests, further incoming requests are also - * inserted to the same queue. To distinguish which requests are to be - * flushed, we insert a marker request to the queue at the time of starting - * flush suspend, like a barrier. - * The dispatching is blocked when the marker is found on the top of the queue. - * And the queue is stopped when all in_flight requests are completed, since - * that means the remaining requests are completely flushed. - * Then, the marker is removed from the queue. - * - * To abort flush suspend, we also need to take care of the marker, not only - * starting the queue. - * We don't remove the marker forcibly from the queue since it's against - * the block-layer manner. Instead, we put a invalidated mark on the marker. - * When the invalidated marker is found on the top of the queue, it is - * immediately removed from the queue, so it doesn't block dispatching. - * Because we have only one marker per mapped_device, we can't start another - * flush suspend until the invalidated marker is removed from the queue. - * So fail and return with -EBUSY in such a case. - */ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) { struct dm_table *map = NULL; @@ -2382,11 +1579,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) goto out_unlock; } - if (dm_request_based(md) && !dm_rq_suspend_available(md, noflush)) { - r = -EBUSY; - goto out_unlock; - } - map = dm_get_table(md); /* @@ -2399,14 +1591,24 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) /* This does not get reverted if there's an error later. */ dm_table_presuspend_targets(map); - /* - * Flush I/O to the device. noflush supersedes do_lockfs, - * because lock_fs() needs to flush I/Os. - */ - if (!noflush && do_lockfs) { - r = lock_fs(md); - if (r) + /* bdget() can stall if the pending I/Os are not flushed */ + if (!noflush) { + md->suspended_bdev = bdget_disk(md->disk, 0); + if (!md->suspended_bdev) { + DMWARN("bdget failed in dm_suspend"); + r = -ENOMEM; goto out; + } + + /* + * Flush I/O to the device. noflush supersedes do_lockfs, + * because lock_fs() needs to flush I/Os. + */ + if (do_lockfs) { + r = lock_fs(md); + if (r) + goto out; + } } /* @@ -2432,9 +1634,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) flush_workqueue(md->wq); - if (dm_request_based(md)) - dm_rq_start_suspend(md, noflush); - /* * At this point no more requests are entering target request routines. * We call dm_wait_for_completion to wait for all existing requests @@ -2451,9 +1650,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) if (r < 0) { dm_queue_flush(md); - if (dm_request_based(md)) - dm_rq_abort_suspend(md, noflush); - unlock_fs(md); goto out; /* pushback list is already flushed, so skip flush */ } @@ -2469,6 +1665,11 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) set_bit(DMF_SUSPENDED, &md->flags); out: + if (r && md->suspended_bdev) { + bdput(md->suspended_bdev); + md->suspended_bdev = NULL; + } + dm_table_put(map); out_unlock: @@ -2495,20 +1696,21 @@ int dm_resume(struct mapped_device *md) dm_queue_flush(md); - /* - * Flushing deferred I/Os must be done after targets are resumed - * so that mapping of targets can work correctly. - * Request-based dm is queueing the deferred I/Os in its request_queue. - */ - if (dm_request_based(md)) - start_queue(md->queue); - unlock_fs(md); + if (md->suspended_bdev) { + bdput(md->suspended_bdev); + md->suspended_bdev = NULL; + } + clear_bit(DMF_SUSPENDED, &md->flags); dm_table_unplug_all(map); + + dm_kobject_uevent(md); + r = 0; + out: dm_table_put(map); mutex_unlock(&md->suspend_lock); @@ -2519,19 +1721,9 @@ int dm_resume(struct mapped_device *md) /*----------------------------------------------------------------- * Event notification. *---------------------------------------------------------------*/ -void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action, - unsigned cookie) -{ - char udev_cookie[DM_COOKIE_LENGTH]; - char *envp[] = { udev_cookie, NULL }; - - if (!cookie) - kobject_uevent(&disk_to_dev(md->disk)->kobj, action); - else { - snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u", - DM_COOKIE_ENV_VAR_NAME, cookie); - kobject_uevent_env(&disk_to_dev(md->disk)->kobj, action, envp); - } +void dm_kobject_uevent(struct mapped_device *md) +{ + kobject_uevent(&disk_to_dev(md->disk)->kobj, KOBJ_CHANGE); } uint32_t dm_next_uevent_seq(struct mapped_device *md) @@ -2585,10 +1777,6 @@ struct mapped_device *dm_get_from_kobject(struct kobject *kobj) if (&md->kobj != kobj) return NULL; - if (test_bit(DMF_FREEING, &md->flags) || - test_bit(DMF_DELETING, &md->flags)) - return NULL; - dm_get(md); return md; } @@ -2609,61 +1797,6 @@ int dm_noflush_suspending(struct dm_target *ti) } EXPORT_SYMBOL_GPL(dm_noflush_suspending); -struct dm_md_mempools *dm_alloc_md_mempools(unsigned type) -{ - struct dm_md_mempools *pools = kmalloc(sizeof(*pools), GFP_KERNEL); - - if (!pools) - return NULL; - - pools->io_pool = (type == DM_TYPE_BIO_BASED) ? - mempool_create_slab_pool(MIN_IOS, _io_cache) : - mempool_create_slab_pool(MIN_IOS, _rq_bio_info_cache); - if (!pools->io_pool) - goto free_pools_and_out; - - pools->tio_pool = (type == DM_TYPE_BIO_BASED) ? - mempool_create_slab_pool(MIN_IOS, _tio_cache) : - mempool_create_slab_pool(MIN_IOS, _rq_tio_cache); - if (!pools->tio_pool) - goto free_io_pool_and_out; - - pools->bs = (type == DM_TYPE_BIO_BASED) ? - bioset_create(16, 0) : bioset_create(MIN_IOS, 0); - if (!pools->bs) - goto free_tio_pool_and_out; - - return pools; - -free_tio_pool_and_out: - mempool_destroy(pools->tio_pool); - -free_io_pool_and_out: - mempool_destroy(pools->io_pool); - -free_pools_and_out: - kfree(pools); - - return NULL; -} - -void dm_free_md_mempools(struct dm_md_mempools *pools) -{ - if (!pools) - return; - - if (pools->io_pool) - mempool_destroy(pools->io_pool); - - if (pools->tio_pool) - mempool_destroy(pools->tio_pool); - - if (pools->bs) - bioset_free(pools->bs); - - kfree(pools); -} - static struct block_device_operations dm_blk_dops = { .open = dm_blk_open, .release = dm_blk_close, diff --git a/trunk/drivers/md/dm.h b/trunk/drivers/md/dm.h index 23278ae80f08..a31506d93e91 100644 --- a/trunk/drivers/md/dm.h +++ b/trunk/drivers/md/dm.h @@ -22,13 +22,6 @@ #define DM_SUSPEND_LOCKFS_FLAG (1 << 0) #define DM_SUSPEND_NOFLUSH_FLAG (1 << 1) -/* - * Type of table and mapped_device's mempool - */ -#define DM_TYPE_NONE 0 -#define DM_TYPE_BIO_BASED 1 -#define DM_TYPE_REQUEST_BASED 2 - /* * List of devices that a metadevice uses and should open/close. */ @@ -39,7 +32,6 @@ struct dm_dev_internal { }; struct dm_table; -struct dm_md_mempools; /*----------------------------------------------------------------- * Internal table functions. @@ -49,34 +41,18 @@ void dm_table_event_callback(struct dm_table *t, void (*fn)(void *), void *context); struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index); struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector); -int dm_calculate_queue_limits(struct dm_table *table, - struct queue_limits *limits); -void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, - struct queue_limits *limits); +void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q); struct list_head *dm_table_get_devices(struct dm_table *t); void dm_table_presuspend_targets(struct dm_table *t); void dm_table_postsuspend_targets(struct dm_table *t); int dm_table_resume_targets(struct dm_table *t); int dm_table_any_congested(struct dm_table *t, int bdi_bits); -int dm_table_any_busy_target(struct dm_table *t); -int dm_table_set_type(struct dm_table *t); -unsigned dm_table_get_type(struct dm_table *t); -bool dm_table_bio_based(struct dm_table *t); -bool dm_table_request_based(struct dm_table *t); -int dm_table_alloc_md_mempools(struct dm_table *t); -void dm_table_free_md_mempools(struct dm_table *t); -struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t); /* * To check the return value from dm_table_find_target(). */ #define dm_target_is_valid(t) ((t)->table) -/* - * To check whether the target type is request-based or not (bio-based). - */ -#define dm_target_request_based(t) ((t)->type->map_rq != NULL) - /*----------------------------------------------------------------- * A registry of target types. *---------------------------------------------------------------*/ @@ -116,16 +92,9 @@ void dm_stripe_exit(void); int dm_open_count(struct mapped_device *md); int dm_lock_for_deletion(struct mapped_device *md); -void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action, - unsigned cookie); +void dm_kobject_uevent(struct mapped_device *md); int dm_kcopyd_init(void); void dm_kcopyd_exit(void); -/* - * Mempool operations - */ -struct dm_md_mempools *dm_alloc_md_mempools(unsigned type); -void dm_free_md_mempools(struct dm_md_mempools *pools); - #endif diff --git a/trunk/drivers/md/linear.c b/trunk/drivers/md/linear.c index 5810fa906af0..15c8b7b25a9b 100644 --- a/trunk/drivers/md/linear.c +++ b/trunk/drivers/md/linear.c @@ -166,8 +166,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) rdev->sectors = sectors * mddev->chunk_sectors; } - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 0f4a70c43ffc..09be637d52cb 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -3573,8 +3573,7 @@ suspend_lo_store(mddev_t *mddev, const char *buf, size_t len) char *e; unsigned long long new = simple_strtoull(buf, &e, 10); - if (mddev->pers == NULL || - mddev->pers->quiesce == NULL) + if (mddev->pers->quiesce == NULL) return -EINVAL; if (buf == e || (*e && *e != '\n')) return -EINVAL; @@ -3602,8 +3601,7 @@ suspend_hi_store(mddev_t *mddev, const char *buf, size_t len) char *e; unsigned long long new = simple_strtoull(buf, &e, 10); - if (mddev->pers == NULL || - mddev->pers->quiesce == NULL) + if (mddev->pers->quiesce == NULL) return -EINVAL; if (buf == e || (*e && *e != '\n')) return -EINVAL; @@ -3846,9 +3844,11 @@ static int md_alloc(dev_t dev, char *name) flush_scheduled_work(); mutex_lock(&disks_mutex); - error = -EEXIST; - if (mddev->gendisk) - goto abort; + if (mddev->gendisk) { + mutex_unlock(&disks_mutex); + mddev_put(mddev); + return -EEXIST; + } if (name) { /* Need to ensure that 'name' is not a duplicate. @@ -3860,15 +3860,17 @@ static int md_alloc(dev_t dev, char *name) if (mddev2->gendisk && strcmp(mddev2->gendisk->disk_name, name) == 0) { spin_unlock(&all_mddevs_lock); - goto abort; + return -EEXIST; } spin_unlock(&all_mddevs_lock); } - error = -ENOMEM; mddev->queue = blk_alloc_queue(GFP_KERNEL); - if (!mddev->queue) - goto abort; + if (!mddev->queue) { + mutex_unlock(&disks_mutex); + mddev_put(mddev); + return -ENOMEM; + } mddev->queue->queuedata = mddev; /* Can be unlocked because the queue is new: no concurrency */ @@ -3878,9 +3880,11 @@ static int md_alloc(dev_t dev, char *name) disk = alloc_disk(1 << shift); if (!disk) { + mutex_unlock(&disks_mutex); blk_cleanup_queue(mddev->queue); mddev->queue = NULL; - goto abort; + mddev_put(mddev); + return -ENOMEM; } disk->major = MAJOR(mddev->unit); disk->first_minor = unit << shift; @@ -3902,22 +3906,16 @@ static int md_alloc(dev_t dev, char *name) mddev->gendisk = disk; error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk_to_dev(disk)->kobj, "%s", "md"); - if (error) { - /* This isn't possible, but as kobject_init_and_add is marked - * __must_check, we must do something with the result - */ + mutex_unlock(&disks_mutex); + if (error) printk(KERN_WARNING "md: cannot register %s/md - name in use\n", disk->disk_name); - error = 0; - } - abort: - mutex_unlock(&disks_mutex); - if (!error) { + else { kobject_uevent(&mddev->kobj, KOBJ_ADD); mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); } mddev_put(mddev); - return error; + return 0; } static struct kobject *md_probe(dev_t dev, int *part, void *data) @@ -6336,16 +6334,10 @@ void md_do_sync(mddev_t *mddev) sysfs_notify(&mddev->kobj, NULL, "sync_completed"); } - while (j >= mddev->resync_max && !kthread_should_stop()) { - /* As this condition is controlled by user-space, - * we can block indefinitely, so use '_interruptible' - * to avoid triggering warnings. - */ - flush_signals(current); /* just in case */ - wait_event_interruptible(mddev->recovery_wait, - mddev->resync_max > j - || kthread_should_stop()); - } + if (j >= mddev->resync_max) + wait_event(mddev->recovery_wait, + mddev->resync_max > j + || kthread_should_stop()); if (kthread_should_stop()) goto interrupted; diff --git a/trunk/drivers/md/multipath.c b/trunk/drivers/md/multipath.c index 237fe3fd235c..cbe368fa6598 100644 --- a/trunk/drivers/md/multipath.c +++ b/trunk/drivers/md/multipath.c @@ -294,8 +294,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) for (path = first; path <= last; path++) if ((p=conf->multipaths+path)->rdev == NULL) { q = rdev->bdev->bd_disk->queue; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, q); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as @@ -464,9 +463,9 @@ static int multipath_run (mddev_t *mddev) disk = conf->multipaths + disk_idx; disk->rdev = rdev; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, not that we ever expect a device with * a merge_bvec_fn to be involved in multipath */ diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c index 335f490dcad6..ab4a489d8695 100644 --- a/trunk/drivers/md/raid0.c +++ b/trunk/drivers/md/raid0.c @@ -170,8 +170,8 @@ static int create_strip_zones(mddev_t *mddev) } dev[j] = rdev1; - disk_stack_limits(mddev->gendisk, rdev1->bdev, - rdev1->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev1->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. @@ -250,11 +250,6 @@ static int create_strip_zones(mddev_t *mddev) mddev->chunk_sectors << 9); goto abort; } - - blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); - blk_queue_io_opt(mddev->queue, - (mddev->chunk_sectors << 9) * mddev->raid_disks); - printk(KERN_INFO "raid0: done.\n"); mddev->private = conf; return 0; diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 0569efba0c02..89939a7aef57 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1123,8 +1123,8 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) for (mirror = first; mirror <= last; mirror++) if ( !(p=conf->mirrors+mirror)->rdev) { - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. @@ -1988,8 +1988,9 @@ static int run(mddev_t *mddev) disk = conf->mirrors + disk_idx; disk->rdev = rdev; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index 7298a5e5a183..ae12ceafe10c 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1151,8 +1151,8 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) for ( ; mirror <= last ; mirror++) if ( !(p=conf->mirrors+mirror)->rdev) { - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. @@ -2044,7 +2044,7 @@ raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks) static int run(mddev_t *mddev) { conf_t *conf; - int i, disk_idx, chunk_size; + int i, disk_idx; mirror_info_t *disk; mdk_rdev_t *rdev; int nc, fc, fo; @@ -2130,14 +2130,6 @@ static int run(mddev_t *mddev) spin_lock_init(&conf->device_lock); mddev->queue->queue_lock = &conf->device_lock; - chunk_size = mddev->chunk_sectors << 9; - blk_queue_io_min(mddev->queue, chunk_size); - if (conf->raid_disks % conf->near_copies) - blk_queue_io_opt(mddev->queue, chunk_size * conf->raid_disks); - else - blk_queue_io_opt(mddev->queue, chunk_size * - (conf->raid_disks / conf->near_copies)); - list_for_each_entry(rdev, &mddev->disks, same_set) { disk_idx = rdev->raid_disk; if (disk_idx >= mddev->raid_disks @@ -2146,8 +2138,9 @@ static int run(mddev_t *mddev) disk = conf->mirrors + disk_idx; disk->rdev = rdev; - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); + + blk_queue_stack_limits(mddev->queue, + rdev->bdev->bd_disk->queue); /* as we don't honour merge_bvec_fn, we must never risk * violating it, so limit ->max_sector to one PAGE, as * a one page request is never in violation. diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 37835538b58e..f9f991e6e138 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -3699,21 +3699,13 @@ static int make_request(struct request_queue *q, struct bio * bi) goto retry; } } - - if (bio_data_dir(bi) == WRITE && - logical_sector >= mddev->suspend_lo && + /* FIXME what if we get a false positive because these + * are being updated. + */ + if (logical_sector >= mddev->suspend_lo && logical_sector < mddev->suspend_hi) { release_stripe(sh); - /* As the suspend_* range is controlled by - * userspace, we want an interruptible - * wait. - */ - flush_signals(current); - prepare_to_wait(&conf->wait_for_overlap, - &w, TASK_INTERRUPTIBLE); - if (logical_sector >= mddev->suspend_lo && - logical_sector < mddev->suspend_hi) - schedule(); + schedule(); goto retry; } @@ -4460,7 +4452,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) static int run(mddev_t *mddev) { raid5_conf_t *conf; - int working_disks = 0, chunk_size; + int working_disks = 0; mdk_rdev_t *rdev; if (mddev->recovery_cp != MaxSector) @@ -4615,14 +4607,6 @@ static int run(mddev_t *mddev) md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec); - chunk_size = mddev->chunk_sectors << 9; - blk_queue_io_min(mddev->queue, chunk_size); - blk_queue_io_opt(mddev->queue, chunk_size * - (conf->raid_disks - conf->max_degraded)); - - list_for_each_entry(rdev, &mddev->disks, same_set) - disk_stack_limits(mddev->gendisk, rdev->bdev, - rdev->data_offset << 9); return 0; abort: diff --git a/trunk/drivers/media/common/ir-keymaps.c b/trunk/drivers/media/common/ir-keymaps.c index 4216328552f6..3fe158ac7bbf 100644 --- a/trunk/drivers/media/common/ir-keymaps.c +++ b/trunk/drivers/media/common/ir-keymaps.c @@ -2750,26 +2750,3 @@ IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = { [0x1b] = KEY_B, /*recall*/ }; EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec); - -/* EVGA inDtube - Devin Heitmueller - */ -IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE] = { - [0x12] = KEY_POWER, - [0x02] = KEY_MODE, /* TV */ - [0x14] = KEY_MUTE, - [0x1a] = KEY_CHANNELUP, - [0x16] = KEY_TV2, /* PIP */ - [0x1d] = KEY_VOLUMEUP, - [0x05] = KEY_CHANNELDOWN, - [0x0f] = KEY_PLAYPAUSE, - [0x19] = KEY_VOLUMEDOWN, - [0x1c] = KEY_REWIND, - [0x0d] = KEY_RECORD, - [0x18] = KEY_FORWARD, - [0x1e] = KEY_PREVIOUS, - [0x1b] = KEY_STOP, - [0x1f] = KEY_NEXT, - [0x13] = KEY_CAMERA, -}; -EXPORT_SYMBOL_GPL(ir_codes_evga_indtube); diff --git a/trunk/drivers/media/dvb/frontends/stv0900.h b/trunk/drivers/media/dvb/frontends/stv0900.h index bf4e9b633044..8a1332c2031d 100644 --- a/trunk/drivers/media/dvb/frontends/stv0900.h +++ b/trunk/drivers/media/dvb/frontends/stv0900.h @@ -29,11 +29,6 @@ #include #include "dvb_frontend.h" -struct stv0900_reg { - u16 addr; - u8 val; -}; - struct stv0900_config { u8 demod_address; u32 xtal; @@ -43,7 +38,7 @@ struct stv0900_config { u8 path1_mode; u8 path2_mode; - struct stv0900_reg *ts_config_regs; + u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */ u8 tun2_maddress; u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */ diff --git a/trunk/drivers/media/dvb/frontends/stv0900_core.c b/trunk/drivers/media/dvb/frontends/stv0900_core.c index 1da045fbb4ef..8499bcf7f251 100644 --- a/trunk/drivers/media/dvb/frontends/stv0900_core.c +++ b/trunk/drivers/media/dvb/frontends/stv0900_core.c @@ -149,31 +149,31 @@ void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr, dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); } -u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg) +u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg_addr) { + u8 data[2]; int ret; - u8 b0[] = { MSB(reg), LSB(reg) }; - u8 buf = 0; - struct i2c_msg msg[] = { - { - .addr = i_params->i2c_addr, - .flags = 0, - .buf = b0, - .len = 2, - }, { - .addr = i_params->i2c_addr, - .flags = I2C_M_RD, - .buf = &buf, - .len = 1, - }, + struct i2c_msg i2cmsg = { + .addr = i_params->i2c_addr, + .flags = 0, + .len = 2, + .buf = data, }; - ret = i2c_transfer(i_params->i2c_adap, msg, 2); - if (ret != 2) - dprintk(KERN_ERR "%s: i2c error %d, reg[0x%02x]\n", - __func__, ret, reg); + data[0] = MSB(reg_addr); + data[1] = LSB(reg_addr); + + ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); + if (ret != 1) + dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); + + i2cmsg.flags = I2C_M_RD; + i2cmsg.len = 1; + ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1); + if (ret != 1) + dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret); - return buf; + return data[0]; } void extract_mask_pos(u32 label, u8 *mask, u8 *pos) @@ -712,44 +712,6 @@ static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, return c_n; } -static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) -{ - struct stv0900_state *state = fe->demodulator_priv; - struct stv0900_internal *i_params = state->internal; - enum fe_stv0900_demod_num demod = state->demod; - u8 err_val1, err_val0; - s32 err_field1, err_field0; - u32 header_err_val = 0; - - *ucblocks = 0x0; - if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { - /* DVB-S2 delineator errors count */ - - /* retreiving number for errnous headers */ - dmd_reg(err_field0, R0900_P1_BBFCRCKO0, - R0900_P2_BBFCRCKO0); - dmd_reg(err_field1, R0900_P1_BBFCRCKO1, - R0900_P2_BBFCRCKO1); - - err_val1 = stv0900_read_reg(i_params, err_field1); - err_val0 = stv0900_read_reg(i_params, err_field0); - header_err_val = (err_val1<<8) | err_val0; - - /* retreiving number for errnous packets */ - dmd_reg(err_field0, R0900_P1_UPCRCKO0, - R0900_P2_UPCRCKO0); - dmd_reg(err_field1, R0900_P1_UPCRCKO1, - R0900_P2_UPCRCKO1); - - err_val1 = stv0900_read_reg(i_params, err_field1); - err_val0 = stv0900_read_reg(i_params, err_field0); - *ucblocks = (err_val1<<8) | err_val0; - *ucblocks += header_err_val; - } - - return 0; -} - static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) { *snr = stv0900_carr_get_quality(fe, @@ -1393,7 +1355,7 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, struct stv0900_state *state = fe->demodulator_priv; enum fe_stv0900_error error = STV0900_NO_ERROR; enum fe_stv0900_error demodError = STV0900_NO_ERROR; - int selosci, i; + int selosci; struct stv0900_inode *temp_int = find_inode(state->i2c_adap, state->config->demod_address); @@ -1440,23 +1402,7 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff); stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff); - state->internal->ts_config = p_init->ts_config; - if (state->internal->ts_config == NULL) - stv0900_set_ts_parallel_serial(state->internal, - p_init->path1_ts_clock, - p_init->path2_ts_clock); - else { - for (i = 0; state->internal->ts_config[i].addr != 0xffff; i++) - stv0900_write_reg(state->internal, - state->internal->ts_config[i].addr, - state->internal->ts_config[i].val); - - stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 1); - stv0900_write_bits(state->internal, F0900_P2_RST_HWARE, 0); - stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 1); - stv0900_write_bits(state->internal, F0900_P1_RST_HWARE, 0); - } - + stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock); stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); switch (p_init->tuner1_adc) { case 1: @@ -1936,7 +1882,6 @@ static struct dvb_frontend_ops stv0900_ops = { .read_ber = stv0900_read_ber, .read_signal_strength = stv0900_read_signal_strength, .read_snr = stv0900_read_snr, - .read_ucblocks = stv0900_read_ucblocks, }; struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, @@ -1970,7 +1915,6 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, init_params.tun1_iq_inversion = STV0900_IQ_NORMAL; init_params.tuner1_adc = config->tun1_adc; init_params.path2_ts_clock = config->path2_mode; - init_params.ts_config = config->ts_config_regs; init_params.tun2_maddress = config->tun2_maddress; init_params.tuner2_adc = config->tun2_adc; init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED; diff --git a/trunk/drivers/media/dvb/frontends/stv0900_priv.h b/trunk/drivers/media/dvb/frontends/stv0900_priv.h index 5ed7a145c7d3..67dc8ec634e2 100644 --- a/trunk/drivers/media/dvb/frontends/stv0900_priv.h +++ b/trunk/drivers/media/dvb/frontends/stv0900_priv.h @@ -271,7 +271,6 @@ struct stv0900_init_params{ /* IQ from the tuner2 to the demod */ enum stv0900_iq_inversion tun2_iq_inversion; - struct stv0900_reg *ts_config; }; struct stv0900_search_params { @@ -364,7 +363,6 @@ struct stv0900_internal{ u8 i2c_addr; u8 clkmode;/* 0 for CLKI, 2 for XTALI */ u8 chip_id; - struct stv0900_reg *ts_config; enum fe_stv0900_error errs; int dmds_used; }; diff --git a/trunk/drivers/media/dvb/frontends/stv090x.c b/trunk/drivers/media/dvb/frontends/stv090x.c index 488bdfb34fb3..96ef745a2e4e 100644 --- a/trunk/drivers/media/dvb/frontends/stv090x.c +++ b/trunk/drivers/media/dvb/frontends/stv090x.c @@ -2674,7 +2674,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) { - struct stv090x_short_frame_crloop *short_crl = NULL; + struct stv090x_short_frame_crloop *short_crl; s32 index = 0; u8 aclc = 0x0b; @@ -2694,13 +2694,10 @@ static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) break; } - if (state->dev_ver >= 0x30) { - /* Cut 3.0 and up */ - short_crl = stv090x_s2_short_crl_cut30; - } else { - /* Cut 2.0 and up: we don't support cuts older than 2.0 */ + if (state->dev_ver >= 0x30) short_crl = stv090x_s2_short_crl_cut20; - } + else if (state->dev_ver >= 0x20) + short_crl = stv090x_s2_short_crl_cut30; if (state->srate <= 3000000) aclc = short_crl[index].crl_2; diff --git a/trunk/drivers/media/dvb/frontends/tda10048.c b/trunk/drivers/media/dvb/frontends/tda10048.c index cc8862ce4aae..4302c563a6b8 100644 --- a/trunk/drivers/media/dvb/frontends/tda10048.c +++ b/trunk/drivers/media/dvb/frontends/tda10048.c @@ -210,7 +210,6 @@ static struct pll_tab { { TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 }, { TDA10048_CLK_16000, TDA10048_IF_3300, 10, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_3500, 10, 3, 0 }, - { TDA10048_CLK_16000, TDA10048_IF_3800, 10, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 }, diff --git a/trunk/drivers/media/dvb/siano/smscoreapi.c b/trunk/drivers/media/dvb/siano/smscoreapi.c index a246903c3341..32be382f0e97 100644 --- a/trunk/drivers/media/dvb/siano/smscoreapi.c +++ b/trunk/drivers/media/dvb/siano/smscoreapi.c @@ -1422,8 +1422,8 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, struct smscore_gpio_config *pGpioConfig) { u32 totalLen; - u32 TranslatedPinNum = 0; - u32 GroupNum = 0; + u32 TranslatedPinNum; + u32 GroupNum; u32 ElectricChar; u32 groupCfg; void *buffer; diff --git a/trunk/drivers/media/radio/radio-tea5764.c b/trunk/drivers/media/radio/radio-tea5764.c index 3cd76dddb6aa..393623818ade 100644 --- a/trunk/drivers/media/radio/radio-tea5764.c +++ b/trunk/drivers/media/radio/radio-tea5764.c @@ -322,9 +322,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, v->rangehigh = FREQ_MAX * FREQ_MUL; v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; if (r->tunchk & TEA5764_TUNCHK_STEREO) - v->rxsubchans = V4L2_TUNER_SUB_STEREO; - else - v->rxsubchans = V4L2_TUNER_SUB_MONO; + v->rxsubchans = V4L2_TUNER_SUB_STEREO; v->audmode = tea5764_get_audout_mode(radio); v->signal = TEA5764_TUNCHK_LEVEL(r->tunchk) * 0xffff / 0xf; v->afc = TEA5764_TUNCHK_IFCNT(r->tunchk); diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 061e147f6f26..94f440535c64 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -866,13 +866,9 @@ config USB_W9968CF module will be called w9968cf. config USB_OV511 - tristate "USB OV511 Camera support (DEPRECATED)" + tristate "USB OV511 Camera support" depends on VIDEO_V4L1 ---help--- - This driver is DEPRECATED please use the gspca ov519 module - instead. Note that for the ov511 / ov518 support of the gspca module - you need atleast version 0.6.0 of libv4l. - Say Y here if you want to connect this type of camera to your computer's USB port. See for more information and for a list of supported cameras. diff --git a/trunk/drivers/media/video/cx18/cx18-controls.c b/trunk/drivers/media/video/cx18/cx18-controls.c index 5136df198338..8e35c3aed544 100644 --- a/trunk/drivers/media/video/cx18/cx18-controls.c +++ b/trunk/drivers/media/video/cx18/cx18-controls.c @@ -61,8 +61,6 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) switch (qctrl->id) { /* Standard V4L2 controls */ - case V4L2_CID_USER_CLASS: - return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0); case V4L2_CID_BRIGHTNESS: case V4L2_CID_HUE: case V4L2_CID_SATURATION: diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-avcore.c b/trunk/drivers/media/video/cx231xx/cx231xx-avcore.c index 28f48f41f218..6a9464079b4c 100644 --- a/trunk/drivers/media/video/cx231xx/cx231xx-avcore.c +++ b/trunk/drivers/media/video/cx231xx/cx231xx-avcore.c @@ -1052,13 +1052,22 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, /* Set resolution of the video */ int cx231xx_resolution_set(struct cx231xx *dev) { + int width, height; + u32 hscale, vscale; + int status = 0; + + width = dev->width; + height = dev->height; + + get_scale(dev, width, height, &hscale, &vscale); + /* set horzontal scale */ - int status = vid_blk_write_word(dev, HSCALE_CTRL, dev->hscale); - if (status) - return status; + status = vid_blk_write_word(dev, HSCALE_CTRL, hscale); /* set vertical scale */ - return vid_blk_write_word(dev, VSCALE_CTRL, dev->vscale); + status = vid_blk_write_word(dev, VSCALE_CTRL, vscale); + + return status; } /****************************************************************************** @@ -2046,7 +2055,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type) { - int rc = -1; + int rc; u32 ep_mask = -1; struct pcb_config *pcb_config; diff --git a/trunk/drivers/media/video/cx231xx/cx231xx-video.c b/trunk/drivers/media/video/cx231xx/cx231xx-video.c index 609bae6098d3..a23ae73fe634 100644 --- a/trunk/drivers/media/video/cx231xx/cx231xx-video.c +++ b/trunk/drivers/media/video/cx231xx/cx231xx-video.c @@ -893,9 +893,9 @@ static int check_dev(struct cx231xx *dev) return 0; } -static void get_scale(struct cx231xx *dev, - unsigned int width, unsigned int height, - unsigned int *hscale, unsigned int *vscale) +void get_scale(struct cx231xx *dev, + unsigned int width, unsigned int height, + unsigned int *hscale, unsigned int *vscale) { unsigned int maxw = norm_maxw(dev); unsigned int maxh = norm_maxh(dev); @@ -907,6 +907,10 @@ static void get_scale(struct cx231xx *dev, *vscale = (((unsigned long)maxh) << 12) / height - 4096L; if (*vscale >= 0x4000) *vscale = 0x3fff; + + dev->hscale = *hscale; + dev->vscale = *vscale; + } /* ------------------------------------------------------------------ @@ -951,8 +955,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, { struct cx231xx_fh *fh = priv; struct cx231xx *dev = fh->dev; - unsigned int width = f->fmt.pix.width; - unsigned int height = f->fmt.pix.height; + int width = f->fmt.pix.width; + int height = f->fmt.pix.height; unsigned int maxw = norm_maxw(dev); unsigned int maxh = norm_maxh(dev); unsigned int hscale, vscale; @@ -967,7 +971,17 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, /* width must even because of the YUYV format height must be even because of interlacing */ - v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); + height &= 0xfffe; + width &= 0xfffe; + + if (unlikely(height < 32)) + height = 32; + if (unlikely(height > maxh)) + height = maxh; + if (unlikely(width < 48)) + width = 48; + if (unlikely(width > maxw)) + width = maxw; get_scale(dev, width, height, &hscale, &vscale); diff --git a/trunk/drivers/media/video/cx231xx/cx231xx.h b/trunk/drivers/media/video/cx231xx/cx231xx.h index a0f823ac6b8d..e38eb2d425f7 100644 --- a/trunk/drivers/media/video/cx231xx/cx231xx.h +++ b/trunk/drivers/media/video/cx231xx/cx231xx.h @@ -722,6 +722,9 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input); int cx231xx_set_decoder_video_input(struct cx231xx *dev, u8 pin_type, u8 input); int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev); int cx231xx_set_audio_input(struct cx231xx *dev, u8 input); +void get_scale(struct cx231xx *dev, + unsigned int width, unsigned int height, + unsigned int *hscale, unsigned int *vscale); /* Provided by cx231xx-video.c */ int cx231xx_register_extension(struct cx231xx_ops *dev); diff --git a/trunk/drivers/media/video/cx2341x.c b/trunk/drivers/media/video/cx2341x.c index 4c8e95853fa3..8ded52946334 100644 --- a/trunk/drivers/media/video/cx2341x.c +++ b/trunk/drivers/media/video/cx2341x.c @@ -500,8 +500,6 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, int err; switch (qctrl->id) { - case V4L2_CID_MPEG_CLASS: - return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0); case V4L2_CID_MPEG_STREAM_TYPE: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_STREAM_TYPE_MPEG2_PS, diff --git a/trunk/drivers/media/video/cx23885/cx23885-dvb.c b/trunk/drivers/media/video/cx23885/cx23885-dvb.c index 48a975134ac5..e236df23370e 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-dvb.c +++ b/trunk/drivers/media/video/cx23885/cx23885-dvb.c @@ -45,7 +45,6 @@ #include "dibx000_common.h" #include "zl10353.h" #include "stv0900.h" -#include "stv0900_reg.h" #include "stv6110.h" #include "lnbh24.h" #include "cx24116.h" @@ -243,22 +242,12 @@ static struct tda18271_std_map hauppauge_tda18271_std_map = { .if_lvl = 6, .rfagc_top = 0x37 }, }; -static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = { - .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, - .if_lvl = 1, .rfagc_top = 0x37, }, - .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5, - .if_lvl = 1, .rfagc_top = 0x37, }, - .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6, - .if_lvl = 1, .rfagc_top = 0x37, }, -}; - static struct tda18271_config hauppauge_tda18271_config = { .std_map = &hauppauge_tda18271_std_map, .gate = TDA18271_GATE_ANALOG, }; static struct tda18271_config hauppauge_hvr1200_tuner_config = { - .std_map = &hauppauge_hvr1200_tda18271_std_map, .gate = TDA18271_GATE_ANALOG, }; @@ -381,25 +370,13 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = { .disable_i2c_gate_ctrl = 1, }; -static struct stv0900_reg stv0900_ts_regs[] = { - { R0900_TSGENERAL, 0x00 }, - { R0900_P1_TSSPEED, 0x40 }, - { R0900_P2_TSSPEED, 0x40 }, - { R0900_P1_TSCFGM, 0xc0 }, - { R0900_P2_TSCFGM, 0xc0 }, - { R0900_P1_TSCFGH, 0xe0 }, - { R0900_P2_TSCFGH, 0xe0 }, - { R0900_P1_TSCFGL, 0x20 }, - { R0900_P2_TSCFGL, 0x20 }, - { 0xffff, 0xff }, /* terminate */ -}; - static struct stv0900_config netup_stv0900_config = { .demod_address = 0x68, .xtal = 27000000, .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ .diseqc_mode = 2,/* 2/3 PWM */ - .ts_config_regs = stv0900_ts_regs, + .path1_mode = 2,/*Serial continues clock */ + .path2_mode = 2,/*Serial continues clock */ .tun1_maddress = 0,/* 0x60 */ .tun2_maddress = 3,/* 0x63 */ .tun1_adc = 1,/* 1 Vpp */ @@ -759,8 +736,7 @@ static int dvb_register(struct cx23885_tsport *port) if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, - LNBH24_PCL, - LNBH24_TTX, 0x09)) + LNBH24_PCL, 0, 0x09)) printk(KERN_ERR "No LNBH24 found!\n"); @@ -780,8 +756,7 @@ static int dvb_register(struct cx23885_tsport *port) if (!dvb_attach(lnbh24_attach, fe0->dvb.frontend, &i2c_bus->i2c_adap, - LNBH24_PCL, - LNBH24_TTX, 0x0a)) + LNBH24_PCL, 0, 0x0a)) printk(KERN_ERR "No LNBH24 found!\n"); diff --git a/trunk/drivers/media/video/cx23885/cx23885-video.c b/trunk/drivers/media/video/cx23885/cx23885-video.c index 70836af3ab48..66bbd2e71105 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-video.c +++ b/trunk/drivers/media/video/cx23885/cx23885-video.c @@ -963,8 +963,15 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } f->fmt.pix.field = field; - v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, - &f->fmt.pix.height, 32, maxh, 0, 0); + if (f->fmt.pix.height < 32) + f->fmt.pix.height = 32; + if (f->fmt.pix.height > maxh) + f->fmt.pix.height = maxh; + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.width > maxw) + f->fmt.pix.width = maxw; + f->fmt.pix.width &= ~0x03; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index a5cc1c1fc2d6..94b7a52629d0 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -1524,45 +1524,33 @@ static const struct cx88_board cx88_boards[] = { }, .mpeg = CX88_MPEG_DVB, }, - /* Terry Wu */ - /* TV Audio : set GPIO 2, 18, 19 value to 0, 1, 0 */ - /* FM Audio : set GPIO 2, 18, 19 value to 0, 0, 0 */ - /* Line-in Audio : set GPIO 2, 18, 19 value to 0, 1, 1 */ - /* Mute Audio : set GPIO 2 value to 1 */ [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = { - .name = "Leadtek TV2000 XP Global", + .name = "Winfast TV2000 XP Global", .tuner_type = TUNER_XC2028, .tuner_addr = 0x61, - .radio_type = TUNER_XC2028, - .radio_addr = 0x61, .input = { { .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio0 = 0x0400, /* pin 2 = 0 */ + .gpio0 = 0x0400, /* pin 2:mute = 0 (off?) */ .gpio1 = 0x0000, - .gpio2 = 0x0C04, /* pin 18 = 1, pin 19 = 0 */ - .gpio3 = 0x0000, + .gpio2 = 0x0800, /* pin 19:audio = 0 (tv) */ + }, { .type = CX88_VMUX_COMPOSITE1, .vmux = 1, - .gpio0 = 0x0400, /* pin 2 = 0 */ + .gpio0 = 0x0400, /* probably? or 0x0404 to turn mute on */ .gpio1 = 0x0000, - .gpio2 = 0x0C0C, /* pin 18 = 1, pin 19 = 1 */ - .gpio3 = 0x0000, + .gpio2 = 0x0808, /* pin 19:audio = 1 (line) */ + }, { .type = CX88_VMUX_SVIDEO, .vmux = 2, - .gpio0 = 0x0400, /* pin 2 = 0 */ - .gpio1 = 0x0000, - .gpio2 = 0x0C0C, /* pin 18 = 1, pin 19 = 1 */ - .gpio3 = 0x0000, } }, .radio = { .type = CX88_RADIO, - .gpio0 = 0x0400, /* pin 2 = 0 */ - .gpio1 = 0x0000, - .gpio2 = 0x0C00, /* pin 18 = 0, pin 19 = 0 */ - .gpio3 = 0x0000, + .gpio0 = 0x004ff, + .gpio1 = 0x010ff, + .gpio2 = 0x0ff, }, }, [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = { @@ -2450,41 +2438,6 @@ static const struct cx88_subid cx88_subids[] = { .subvendor = 0x107d, .subdevice = 0x6654, .card = CX88_BOARD_WINFAST_DTV1800H, - }, { - /* PVR2000 PAL Model [107d:6630] */ - .subvendor = 0x107d, - .subdevice = 0x6630, - .card = CX88_BOARD_LEADTEK_PVR2000, - }, { - /* PVR2000 PAL Model [107d:6638] */ - .subvendor = 0x107d, - .subdevice = 0x6638, - .card = CX88_BOARD_LEADTEK_PVR2000, - }, { - /* PVR2000 NTSC Model [107d:6631] */ - .subvendor = 0x107d, - .subdevice = 0x6631, - .card = CX88_BOARD_LEADTEK_PVR2000, - }, { - /* PVR2000 NTSC Model [107d:6637] */ - .subvendor = 0x107d, - .subdevice = 0x6637, - .card = CX88_BOARD_LEADTEK_PVR2000, - }, { - /* PVR2000 NTSC Model [107d:663d] */ - .subvendor = 0x107d, - .subdevice = 0x663d, - .card = CX88_BOARD_LEADTEK_PVR2000, - }, { - /* DV2000 NTSC Model [107d:6621] */ - .subvendor = 0x107d, - .subdevice = 0x6621, - .card = CX88_BOARD_WINFAST_DV2000, - }, { - /* TV2000 XP Global [107d:6618] */ - .subvendor = 0x107d, - .subdevice = 0x6618, - .card = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL, }, }; @@ -2493,6 +2446,12 @@ static const struct cx88_subid cx88_subids[] = { static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) { + /* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on + * any others. + * + * Byte 0 is 1 on the NTSC board. + */ + if (eeprom_data[4] != 0x7d || eeprom_data[5] != 0x10 || eeprom_data[7] != 0x66) { @@ -2500,19 +2459,8 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) return; } - /* Terry Wu */ - switch (eeprom_data[6]) { - case 0x13: /* SSID 6613 for TV2000 XP Expert NTSC Model */ - case 0x21: /* SSID 6621 for DV2000 NTSC Model */ - case 0x31: /* SSID 6631 for PVR2000 NTSC Model */ - case 0x37: /* SSID 6637 for PVR2000 NTSC Model */ - case 0x3d: /* SSID 6637 for PVR2000 NTSC Model */ - core->board.tuner_type = TUNER_PHILIPS_FM1236_MK3; - break; - default: - core->board.tuner_type = TUNER_PHILIPS_FM1216ME_MK3; - break; - } + core->board.tuner_type = (eeprom_data[6] == 0x13) ? + TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3; info_printk(core, "Leadtek Winfast 2000XP Expert config: " "tuner=%d, eeprom[0]=0x%02x\n", @@ -2765,6 +2713,7 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core, { /* Board-specific callbacks */ switch (core->boardnr) { + case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: case CX88_BOARD_POWERCOLOR_REAL_ANGEL: case CX88_BOARD_GENIATECH_X8000_MT: case CX88_BOARD_KWORLD_ATSC_120: @@ -2776,7 +2725,6 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core, case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: return cx88_dvico_xc2028_callback(core, command, arg); - case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: case CX88_BOARD_WINFAST_DTV1800H: return cx88_xc3028_winfast1800h_callback(core, command, arg); } @@ -2966,7 +2914,6 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core) udelay(1000); break; - case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: case CX88_BOARD_WINFAST_DTV1800H: /* GPIO 12 (xc3028 tuner reset) */ cx_set(MO_GP1_IO, 0x1010); @@ -3003,7 +2950,6 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: ctl->demod = XC3028_FE_OREN538; break; - case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME: case CX88_BOARD_PROLINK_PV_8000GT: /* @@ -3047,8 +2993,6 @@ static void cx88_card_setup(struct cx88_core *core) if (0 == core->i2c_rc) gdi_eeprom(core, eeprom); break; - case CX88_BOARD_LEADTEK_PVR2000: - case CX88_BOARD_WINFAST_DV2000: case CX88_BOARD_WINFAST2000XP_EXPERT: if (0 == core->i2c_rc) leadtek_eeprom(core, eeprom); diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index b12770848c00..0ccac702bea4 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -1111,8 +1111,15 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } f->fmt.pix.field = field; - v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, - &f->fmt.pix.height, 32, maxh, 0, 0); + if (f->fmt.pix.height < 32) + f->fmt.pix.height = 32; + if (f->fmt.pix.height > maxh) + f->fmt.pix.height = maxh; + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.width > maxw) + f->fmt.pix.width = maxw; + f->fmt.pix.width &= ~0x03; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index c43fdb9bc888..00cc791a9e44 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -139,24 +139,6 @@ static struct em28xx_reg_seq kworld_330u_digital[] = { { -1, -1, -1, -1}, }; -/* Evga inDtube - GPIO0 - Enable digital power (s5h1409) - low to enable - GPIO1 - Enable analog power (tvp5150/emp202) - low to enable - GPIO4 - xc3028 reset - GOP3 - s5h1409 reset - */ -static struct em28xx_reg_seq evga_indtube_analog[] = { - {EM28XX_R08_GPIO, 0x79, 0xff, 60}, - { -1, -1, -1, -1}, -}; - -static struct em28xx_reg_seq evga_indtube_digital[] = { - {EM28XX_R08_GPIO, 0x7a, 0xff, 1}, - {EM2880_R04_GPO, 0x04, 0xff, 10}, - {EM2880_R04_GPO, 0x0c, 0xff, 1}, - { -1, -1, -1, -1}, -}; - /* Callback for the most boards */ static struct em28xx_reg_seq default_tuner_gpio[] = { {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, @@ -1467,33 +1449,6 @@ struct em28xx_board em28xx_boards[] = { .gpio = terratec_av350_unmute_gpio, } }, }, - [EM2882_BOARD_EVGA_INDTUBE] = { - .name = "Evga inDtube", - .tuner_type = TUNER_XC2028, - .tuner_gpio = default_tuner_gpio, - .decoder = EM28XX_TVP5150, - .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */ - .mts_firmware = 1, - .has_dvb = 1, - .dvb_gpio = evga_indtube_digital, - .ir_codes = ir_codes_evga_indtube, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = TVP5150_COMPOSITE0, - .amux = EM28XX_AMUX_VIDEO, - .gpio = evga_indtube_analog, - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = TVP5150_COMPOSITE1, - .amux = EM28XX_AMUX_LINE_IN, - .gpio = evga_indtube_analog, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = TVP5150_SVIDEO, - .amux = EM28XX_AMUX_LINE_IN, - .gpio = evga_indtube_analog, - } }, - }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -1616,7 +1571,6 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = { {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, {0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, - {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, }; /* I2C devicelist hash table for devices with generic USB IDs */ @@ -1880,10 +1834,6 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) ctl->demod = XC3028_FE_CHINA; ctl->fname = XC2028_DEFAULT_FIRMWARE; break; - case EM2882_BOARD_EVGA_INDTUBE: - ctl->demod = XC3028_FE_CHINA; - ctl->fname = XC3028L_DEFAULT_FIRMWARE; - break; default: ctl->demod = XC3028_FE_OREN538; } @@ -2151,12 +2101,6 @@ void em28xx_card_setup(struct em28xx *dev) case EM2880_BOARD_MSI_DIGIVOX_AD: if (!em28xx_hint_board(dev)) em28xx_set_model(dev); - - /* In cases where we had to use a board hint, the call to - em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, - so make the call now so the analog GPIOs are set properly - before probing the i2c bus. */ - em28xx_set_mode(dev, EM28XX_ANALOG_MODE); break; } diff --git a/trunk/drivers/media/video/em28xx/em28xx-dvb.c b/trunk/drivers/media/video/em28xx/em28xx-dvb.c index e7b47c8da8f3..563dd2b1c8e9 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-dvb.c +++ b/trunk/drivers/media/video/em28xx/em28xx-dvb.c @@ -445,7 +445,6 @@ static int dvb_init(struct em28xx *dev) } break; case EM2883_BOARD_KWORLD_HYBRID_330U: - case EM2882_BOARD_EVGA_INDTUBE: dvb->frontend = dvb_attach(s5h1409_attach, &em28xx_s5h1409_with_xc3028, &dev->i2c_adap); diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index 8fe1beecfffa..882796e84dbc 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -687,8 +687,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - unsigned int width = f->fmt.pix.width; - unsigned int height = f->fmt.pix.height; + int width = f->fmt.pix.width; + int height = f->fmt.pix.height; unsigned int maxw = norm_maxw(dev); unsigned int maxh = norm_maxh(dev); unsigned int hscale, vscale; @@ -701,20 +701,34 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; } + /* width must even because of the YUYV format + height must be even because of interlacing */ + height &= 0xfffe; + width &= 0xfffe; + + if (unlikely(height < 32)) + height = 32; + if (unlikely(height > maxh)) + height = maxh; + if (unlikely(width < 48)) + width = 48; + if (unlikely(width > maxw)) + width = maxw; + if (dev->board.is_em2800) { /* the em2800 can only scale down to 50% */ - height = height > (3 * maxh / 4) ? maxh : maxh / 2; - width = width > (3 * maxw / 4) ? maxw : maxw / 2; - /* According to empiatech support the MaxPacketSize is too small - * to support framesizes larger than 640x480 @ 30 fps or 640x576 - * @ 25 fps. As this would cut of a part of the image we prefer - * 360x576 or 360x480 for now */ + if (height % (maxh / 2)) + height = maxh; + if (width % (maxw / 2)) + width = maxw; + /* according to empiatech support */ + /* the MaxPacketSize is to small to support */ + /* framesizes larger than 640x480 @ 30 fps */ + /* or 640x576 @ 25 fps. As this would cut */ + /* of a part of the image we prefer */ + /* 360x576 or 360x480 for now */ if (width == maxw && height == maxh) width /= 2; - } else { - /* width must even because of the YUYV format - height must be even because of interlacing */ - v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); } get_scale(dev, width, height, &hscale, &vscale); diff --git a/trunk/drivers/media/video/em28xx/em28xx.h b/trunk/drivers/media/video/em28xx/em28xx.h index 813ce45c2f99..8bf81be1da61 100644 --- a/trunk/drivers/media/video/em28xx/em28xx.h +++ b/trunk/drivers/media/video/em28xx/em28xx.h @@ -106,7 +106,6 @@ #define EM2860_BOARD_TERRATEC_GRABBY 67 #define EM2860_BOARD_TERRATEC_AV350 68 #define EM2882_BOARD_KWORLD_ATSC_315U 69 -#define EM2882_BOARD_EVGA_INDTUBE 70 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 diff --git a/trunk/drivers/media/video/gspca/gspca.c b/trunk/drivers/media/video/gspca/gspca.c index 1e89600986c8..f7e0355ad644 100644 --- a/trunk/drivers/media/video/gspca/gspca.c +++ b/trunk/drivers/media/video/gspca/gspca.c @@ -1042,11 +1042,13 @@ static int vidioc_queryctrl(struct file *file, void *priv, for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { if (gspca_dev->ctrl_dis & (1 << i)) continue; - if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id) + if (ctrls->qctrl.id < id) continue; - if (ctrls && gspca_dev->sd_desc->ctrls[i].qctrl.id + if (ctrls != NULL) { + if (gspca_dev->sd_desc->ctrls[i].qctrl.id > ctrls->qctrl.id) - continue; + continue; + } ctrls = &gspca_dev->sd_desc->ctrls[i]; } } else { diff --git a/trunk/drivers/media/video/gspca/ov519.c b/trunk/drivers/media/video/gspca/ov519.c index 2f6e135d94bc..188866ac6cef 100644 --- a/trunk/drivers/media/video/gspca/ov519.c +++ b/trunk/drivers/media/video/gspca/ov519.c @@ -50,18 +50,12 @@ static int i2c_detect_tries = 10; struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - __u8 packet_nr; - char bridge; #define BRIDGE_OV511 0 #define BRIDGE_OV511PLUS 1 #define BRIDGE_OV518 2 #define BRIDGE_OV518PLUS 3 #define BRIDGE_OV519 4 -#define BRIDGE_MASK 7 - - char invert_led; -#define BRIDGE_INVERT_LED 8 /* Determined by sensor type */ __u8 sif; @@ -71,25 +65,22 @@ struct sd { __u8 colors; __u8 hflip; __u8 vflip; - __u8 autobrightness; - __u8 freq; __u8 stopped; /* Streaming is temporarily paused */ - __u8 frame_rate; /* current Framerate */ - __u8 clockdiv; /* clockdiv override */ + __u8 frame_rate; /* current Framerate (OV519 only) */ + __u8 clockdiv; /* clockdiv override for OV519 only */ char sensor; /* Type of image sensor chip (SEN_*) */ #define SEN_UNKNOWN 0 #define SEN_OV6620 1 #define SEN_OV6630 2 -#define SEN_OV66308AF 3 -#define SEN_OV7610 4 -#define SEN_OV7620 5 -#define SEN_OV7640 6 -#define SEN_OV7670 7 -#define SEN_OV76BE 8 -#define SEN_OV8610 9 +#define SEN_OV7610 3 +#define SEN_OV7620 4 +#define SEN_OV7640 5 +#define SEN_OV7670 6 +#define SEN_OV76BE 7 +#define SEN_OV8610 8 }; /* V4L2 controls supported by the driver */ @@ -103,17 +94,11 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static void setbrightness(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev); static void setcolors(struct gspca_dev *gspca_dev); -static void setautobrightness(struct sd *sd); -static void setfreq(struct sd *sd); -static const struct ctrl sd_ctrls[] = { +static struct ctrl sd_ctrls[] = { { { .id = V4L2_CID_BRIGHTNESS, @@ -156,7 +141,7 @@ static const struct ctrl sd_ctrls[] = { .set = sd_setcolors, .get = sd_getcolors, }, -/* The flip controls work with ov7670 only */ +/* next controls work with ov7670 only */ #define HFLIP_IDX 3 { { @@ -187,51 +172,6 @@ static const struct ctrl sd_ctrls[] = { .set = sd_setvflip, .get = sd_getvflip, }, -#define AUTOBRIGHT_IDX 5 - { - { - .id = V4L2_CID_AUTOBRIGHTNESS, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Brightness", - .minimum = 0, - .maximum = 1, - .step = 1, -#define AUTOBRIGHT_DEF 1 - .default_value = AUTOBRIGHT_DEF, - }, - .set = sd_setautobrightness, - .get = sd_getautobrightness, - }, -#define FREQ_IDX 6 - { - { - .id = V4L2_CID_POWER_LINE_FREQUENCY, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Light frequency filter", - .minimum = 0, - .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ - .step = 1, -#define FREQ_DEF 0 - .default_value = FREQ_DEF, - }, - .set = sd_setfreq, - .get = sd_getfreq, - }, -#define OV7670_FREQ_IDX 7 - { - { - .id = V4L2_CID_POWER_LINE_FREQUENCY, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Light frequency filter", - .minimum = 0, - .maximum = 3, /* 0: 0, 1: 50Hz, 2:60Hz 3: Auto Hz */ - .step = 1, -#define OV7670_FREQ_DEF 3 - .default_value = OV7670_FREQ_DEF, - }, - .set = sd_setfreq, - .get = sd_getfreq, - }, }; static const struct v4l2_pix_format ov519_vga_mode[] = { @@ -247,21 +187,11 @@ static const struct v4l2_pix_format ov519_vga_mode[] = { .priv = 0}, }; static const struct v4l2_pix_format ov519_sif_mode[] = { - {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 176, .sizeimage = 176 * 144 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1}, - {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8 + 590, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 352, .sizeimage = 352 * 288 * 3 / 8 + 590, @@ -269,118 +199,42 @@ static const struct v4l2_pix_format ov519_sif_mode[] = { .priv = 0}, }; -/* Note some of the sizeimage values for the ov511 / ov518 may seem - larger then necessary, however they need to be this big as the ov511 / - ov518 always fills the entire isoc frame, using 0 padding bytes when - it doesn't have any data. So with low framerates the amount of data - transfered can become quite large (libv4l will remove all the 0 padding - in userspace). */ static const struct v4l2_pix_format ov518_vga_mode[] = { {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, .bytesperline = 320, - .sizeimage = 320 * 240 * 3, + .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1}, {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, .bytesperline = 640, - .sizeimage = 640 * 480 * 2, + .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, }; static const struct v4l2_pix_format ov518_sif_mode[] = { - {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 70000, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, .bytesperline = 176, - .sizeimage = 70000, + .sizeimage = 40000, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1}, - {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, .bytesperline = 352, - .sizeimage = 352 * 288 * 3, + .sizeimage = 352 * 288 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, }; -static const struct v4l2_pix_format ov511_vga_mode[] = { - {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 640, - .sizeimage = 640 * 480 * 2, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; -static const struct v4l2_pix_format ov511_sif_mode[] = { - {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 160, - .sizeimage = 70000, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 3}, - {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 176, - .sizeimage = 70000, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 1}, - {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 320, - .sizeimage = 320 * 240 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 2}, - {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, - .bytesperline = 352, - .sizeimage = 352 * 288 * 3, - .colorspace = V4L2_COLORSPACE_JPEG, - .priv = 0}, -}; /* Registers common to OV511 / OV518 */ -#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ #define R51x_SYS_RESET 0x50 - /* Reset type flags */ - #define OV511_RESET_OMNICE 0x08 #define R51x_SYS_INIT 0x53 #define R51x_SYS_SNAP 0x52 #define R51x_SYS_CUST_ID 0x5F #define R51x_COMP_LUT_BEGIN 0x80 /* OV511 Camera interface register numbers */ -#define R511_CAM_DELAY 0x10 -#define R511_CAM_EDGE 0x11 -#define R511_CAM_PXCNT 0x12 -#define R511_CAM_LNCNT 0x13 -#define R511_CAM_PXDIV 0x14 -#define R511_CAM_LNDIV 0x15 -#define R511_CAM_UV_EN 0x16 -#define R511_CAM_LINE_MODE 0x17 -#define R511_CAM_OPTS 0x18 - -#define R511_SNAP_FRAME 0x19 -#define R511_SNAP_PXCNT 0x1A -#define R511_SNAP_LNCNT 0x1B -#define R511_SNAP_PXDIV 0x1C -#define R511_SNAP_LNDIV 0x1D -#define R511_SNAP_UV_EN 0x1E -#define R511_SNAP_UV_EN 0x1E -#define R511_SNAP_OPTS 0x1F - -#define R511_DRAM_FLOW_CTL 0x20 -#define R511_FIFO_OPTS 0x31 -#define R511_I2C_CTL 0x40 #define R511_SYS_LED_CTL 0x55 /* OV511+ only */ -#define R511_COMP_EN 0x78 -#define R511_COMP_LUT_EN 0x79 +#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */ /* OV518 Camera interface register numbers */ #define R518_GPIO_OUT 0x56 /* OV518(+) only */ @@ -529,7 +383,7 @@ static const struct ov_i2c_regvals norm_6x20[] = { { 0x28, 0x05 }, { 0x2a, 0x04 }, /* Disable framerate adjust */ /* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */ - { 0x2d, 0x85 }, + { 0x2d, 0x99 }, { 0x33, 0xa0 }, /* Color Processing Parameter */ { 0x34, 0xd2 }, /* Max A/D range */ { 0x38, 0x8b }, @@ -562,7 +416,7 @@ static const struct ov_i2c_regvals norm_6x30[] = { { 0x07, 0x2d }, /* Sharpness */ { 0x0c, 0x20 }, { 0x0d, 0x20 }, - { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */ + { 0x0e, 0x20 }, { 0x0f, 0x05 }, { 0x10, 0x9a }, { 0x11, 0x00 }, /* Pixel clock = fastest */ @@ -704,7 +558,7 @@ static const struct ov_i2c_regvals norm_7620[] = { { 0x23, 0x00 }, { 0x26, 0xa2 }, { 0x27, 0xea }, - { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */ + { 0x28, 0x20 }, { 0x29, 0x00 }, { 0x2a, 0x10 }, { 0x2b, 0x00 }, @@ -1145,128 +999,13 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) return ret; } -static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) -{ - int rc, retries; - - PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); - - /* Three byte write cycle */ - for (retries = 6; ; ) { - /* Select camera register */ - rc = reg_w(sd, R51x_I2C_SADDR_3, reg); - if (rc < 0) - return rc; - - /* Write "value" to I2C data port of OV511 */ - rc = reg_w(sd, R51x_I2C_DATA, value); - if (rc < 0) - return rc; - - /* Initiate 3-byte write cycle */ - rc = reg_w(sd, R511_I2C_CTL, 0x01); - if (rc < 0) - return rc; - - do - rc = reg_r(sd, R511_I2C_CTL); - while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ - - if (rc < 0) - return rc; - - if ((rc & 2) == 0) /* Ack? */ - break; - if (--retries < 0) { - PDEBUG(D_USBO, "i2c write retries exhausted"); - return -1; - } - } - - return 0; -} - -static int ov511_i2c_r(struct sd *sd, __u8 reg) -{ - int rc, value, retries; - - /* Two byte write cycle */ - for (retries = 6; ; ) { - /* Select camera register */ - rc = reg_w(sd, R51x_I2C_SADDR_2, reg); - if (rc < 0) - return rc; - - /* Initiate 2-byte write cycle */ - rc = reg_w(sd, R511_I2C_CTL, 0x03); - if (rc < 0) - return rc; - - do - rc = reg_r(sd, R511_I2C_CTL); - while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ - - if (rc < 0) - return rc; - - if ((rc & 2) == 0) /* Ack? */ - break; - - /* I2C abort */ - reg_w(sd, R511_I2C_CTL, 0x10); - - if (--retries < 0) { - PDEBUG(D_USBI, "i2c write retries exhausted"); - return -1; - } - } - - /* Two byte read cycle */ - for (retries = 6; ; ) { - /* Initiate 2-byte read cycle */ - rc = reg_w(sd, R511_I2C_CTL, 0x05); - if (rc < 0) - return rc; - - do - rc = reg_r(sd, R511_I2C_CTL); - while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */ - - if (rc < 0) - return rc; - - if ((rc & 2) == 0) /* Ack? */ - break; - - /* I2C abort */ - rc = reg_w(sd, R511_I2C_CTL, 0x10); - if (rc < 0) - return rc; - - if (--retries < 0) { - PDEBUG(D_USBI, "i2c read retries exhausted"); - return -1; - } - } - - value = reg_r(sd, R51x_I2C_DATA); - - PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); - - /* This is needed to make i2c_w() work */ - rc = reg_w(sd, R511_I2C_CTL, 0x05); - if (rc < 0) - return rc; - - return value; -} /* * The OV518 I2C I/O procedure is different, hence, this function. * This is normally only called from i2c_w(). Note that this function * always succeeds regardless of whether the sensor is present and working. */ -static int ov518_i2c_w(struct sd *sd, +static int i2c_w(struct sd *sd, __u8 reg, __u8 value) { @@ -1301,7 +1040,7 @@ static int ov518_i2c_w(struct sd *sd, * This is normally only called from i2c_r(). Note that this function * always succeeds regardless of whether the sensor is present and working. */ -static int ov518_i2c_r(struct sd *sd, __u8 reg) +static int i2c_r(struct sd *sd, __u8 reg) { int rc, value; @@ -1324,34 +1063,6 @@ static int ov518_i2c_r(struct sd *sd, __u8 reg) return value; } -static int i2c_w(struct sd *sd, __u8 reg, __u8 value) -{ - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - return ov511_i2c_w(sd, reg, value); - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - case BRIDGE_OV519: - return ov518_i2c_w(sd, reg, value); - } - return -1; /* Should never happen */ -} - -static int i2c_r(struct sd *sd, __u8 reg) -{ - switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - return ov511_i2c_r(sd, reg); - case BRIDGE_OV518: - case BRIDGE_OV518PLUS: - case BRIDGE_OV519: - return ov518_i2c_r(sd, reg); - } - return -1; /* Should never happen */ -} - /* Writes bits at positions specified by mask to an I2C reg. Bits that are in * the same position as 1's in "mask" are cleared and set to "value". Bits * that are in the same position as 0's in "mask" are preserved, regardless @@ -1531,6 +1242,7 @@ static int ov8xx0_configure(struct sd *sd) } /* Set sensor-specific vars */ +/* sd->sif = 0; already done */ return 0; } @@ -1567,13 +1279,15 @@ static int ov7xx0_configure(struct sd *sd) } } else if ((rc & 3) == 1) { /* I don't know what's different about the 76BE yet. */ - if (i2c_r(sd, 0x15) & 1) { + if (i2c_r(sd, 0x15) & 1) PDEBUG(D_PROBE, "Sensor is an OV7620AE"); - sd->sensor = SEN_OV7620; - } else { + else PDEBUG(D_PROBE, "Sensor is an OV76BE"); - sd->sensor = SEN_OV76BE; - } + + /* OV511+ will return all zero isoc data unless we + * configure the sensor as a 7620. Someone needs to + * find the exact reg. setting that causes this. */ + sd->sensor = SEN_OV76BE; } else if ((rc & 3) == 0) { /* try to read product id registers */ high = i2c_r(sd, 0x0a); @@ -1619,6 +1333,7 @@ static int ov7xx0_configure(struct sd *sd) } /* Set sensor-specific vars */ +/* sd->sif = 0; already done */ return 0; } @@ -1647,14 +1362,13 @@ static int ov6xx0_configure(struct sd *sd) break; case 0x01: sd->sensor = SEN_OV6620; - PDEBUG(D_PROBE, "Sensor is an OV6620"); break; case 0x02: sd->sensor = SEN_OV6630; PDEBUG(D_PROBE, "Sensor is an OV66308AE"); break; case 0x03: - sd->sensor = SEN_OV66308AF; + sd->sensor = SEN_OV6630; PDEBUG(D_PROBE, "Sensor is an OV66308AF"); break; case 0x90: @@ -1677,9 +1391,6 @@ static int ov6xx0_configure(struct sd *sd) /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ static void ov51x_led_control(struct sd *sd, int on) { - if (sd->invert_led) - on = !on; - switch (sd->bridge) { /* OV511 has no LED control */ case BRIDGE_OV511PLUS: @@ -1695,31 +1406,9 @@ static void ov51x_led_control(struct sd *sd, int on) } } -static int ov51x_upload_quan_tables(struct sd *sd) +/* OV518 quantization tables are 8x4 (instead of 8x8) */ +static int ov518_upload_quan_tables(struct sd *sd) { - const unsigned char yQuanTable511[] = { - 0, 1, 1, 2, 2, 3, 3, 4, - 1, 1, 1, 2, 2, 3, 4, 4, - 1, 1, 2, 2, 3, 4, 4, 4, - 2, 2, 2, 3, 4, 4, 4, 4, - 2, 2, 3, 4, 4, 5, 5, 5, - 3, 3, 4, 4, 5, 5, 5, 5, - 3, 4, 4, 4, 5, 5, 5, 5, - 4, 4, 4, 4, 5, 5, 5, 5 - }; - - const unsigned char uvQuanTable511[] = { - 0, 2, 2, 3, 4, 4, 4, 4, - 2, 2, 2, 4, 4, 4, 4, 4, - 2, 2, 3, 4, 4, 4, 4, 4, - 3, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4 - }; - - /* OV518 quantization tables are 8x4 (instead of 8x8) */ const unsigned char yQuanTable518[] = { 5, 4, 5, 6, 6, 7, 7, 7, 5, 5, 5, 5, 6, 7, 7, 7, @@ -1734,23 +1423,14 @@ static int ov51x_upload_quan_tables(struct sd *sd) 7, 7, 7, 7, 7, 7, 8, 8 }; - const unsigned char *pYTable, *pUVTable; + const unsigned char *pYTable = yQuanTable518; + const unsigned char *pUVTable = uvQuanTable518; unsigned char val0, val1; - int i, size, rc, reg = R51x_COMP_LUT_BEGIN; + int i, rc, reg = R51x_COMP_LUT_BEGIN; PDEBUG(D_PROBE, "Uploading quantization tables"); - if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) { - pYTable = yQuanTable511; - pUVTable = uvQuanTable511; - size = 32; - } else { - pYTable = yQuanTable518; - pUVTable = uvQuanTable518; - size = 16; - } - - for (i = 0; i < size; i++) { + for (i = 0; i < 16; i++) { val0 = *pYTable++; val1 = *pYTable++; val0 &= 0x0f; @@ -1765,7 +1445,7 @@ static int ov51x_upload_quan_tables(struct sd *sd) val0 &= 0x0f; val1 &= 0x0f; val0 |= val1 << 4; - rc = reg_w(sd, reg + size, val0); + rc = reg_w(sd, reg + 16, val0); if (rc < 0) return rc; @@ -1775,87 +1455,6 @@ static int ov51x_upload_quan_tables(struct sd *sd) return 0; } -/* This initializes the OV511/OV511+ and the sensor */ -static int ov511_configure(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - int rc; - - /* For 511 and 511+ */ - const struct ov_regvals init_511[] = { - { R51x_SYS_RESET, 0x7f }, - { R51x_SYS_INIT, 0x01 }, - { R51x_SYS_RESET, 0x7f }, - { R51x_SYS_INIT, 0x01 }, - { R51x_SYS_RESET, 0x3f }, - { R51x_SYS_INIT, 0x01 }, - { R51x_SYS_RESET, 0x3d }, - }; - - const struct ov_regvals norm_511[] = { - { R511_DRAM_FLOW_CTL, 0x01 }, - { R51x_SYS_SNAP, 0x00 }, - { R51x_SYS_SNAP, 0x02 }, - { R51x_SYS_SNAP, 0x00 }, - { R511_FIFO_OPTS, 0x1f }, - { R511_COMP_EN, 0x00 }, - { R511_COMP_LUT_EN, 0x03 }, - }; - - const struct ov_regvals norm_511_p[] = { - { R511_DRAM_FLOW_CTL, 0xff }, - { R51x_SYS_SNAP, 0x00 }, - { R51x_SYS_SNAP, 0x02 }, - { R51x_SYS_SNAP, 0x00 }, - { R511_FIFO_OPTS, 0xff }, - { R511_COMP_EN, 0x00 }, - { R511_COMP_LUT_EN, 0x03 }, - }; - - const struct ov_regvals compress_511[] = { - { 0x70, 0x1f }, - { 0x71, 0x05 }, - { 0x72, 0x06 }, - { 0x73, 0x06 }, - { 0x74, 0x14 }, - { 0x75, 0x03 }, - { 0x76, 0x04 }, - { 0x77, 0x04 }, - }; - - PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID)); - - rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511)); - if (rc < 0) - return rc; - - switch (sd->bridge) { - case BRIDGE_OV511: - rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511)); - if (rc < 0) - return rc; - break; - case BRIDGE_OV511PLUS: - rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p)); - if (rc < 0) - return rc; - break; - } - - /* Init compression */ - rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511)); - if (rc < 0) - return rc; - - rc = ov51x_upload_quan_tables(sd); - if (rc < 0) { - PDEBUG(D_ERR, "Error uploading quantization tables"); - return rc; - } - - return 0; -} - /* This initializes the OV518/OV518+ and the sensor */ static int ov518_configure(struct gspca_dev *gspca_dev) { @@ -1863,7 +1462,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev) int rc; /* For 518 and 518+ */ - const struct ov_regvals init_518[] = { + static struct ov_regvals init_518[] = { { R51x_SYS_RESET, 0x40 }, { R51x_SYS_INIT, 0xe1 }, { R51x_SYS_RESET, 0x3e }, @@ -1874,7 +1473,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev) { 0x5d, 0x03 }, }; - const struct ov_regvals norm_518[] = { + static struct ov_regvals norm_518[] = { { R51x_SYS_SNAP, 0x02 }, /* Reset */ { R51x_SYS_SNAP, 0x01 }, /* Enable */ { 0x31, 0x0f }, @@ -1887,7 +1486,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev) { 0x2f, 0x80 }, }; - const struct ov_regvals norm_518_p[] = { + static struct ov_regvals norm_518_p[] = { { R51x_SYS_SNAP, 0x02 }, /* Reset */ { R51x_SYS_SNAP, 0x01 }, /* Enable */ { 0x31, 0x0f }, @@ -1932,7 +1531,7 @@ static int ov518_configure(struct gspca_dev *gspca_dev) break; } - rc = ov51x_upload_quan_tables(sd); + rc = ov518_upload_quan_tables(sd); if (rc < 0) { PDEBUG(D_ERR, "Error uploading quantization tables"); return rc; @@ -1974,14 +1573,9 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; int ret = 0; - sd->bridge = id->driver_info & BRIDGE_MASK; - sd->invert_led = id->driver_info & BRIDGE_INVERT_LED; + sd->bridge = id->driver_info; switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - ret = ov511_configure(gspca_dev); - break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: ret = ov518_configure(gspca_dev); @@ -2040,16 +1634,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - if (!sd->sif) { - cam->cam_mode = ov511_vga_mode; - cam->nmodes = ARRAY_SIZE(ov511_vga_mode); - } else { - cam->cam_mode = ov511_sif_mode; - cam->nmodes = ARRAY_SIZE(ov511_sif_mode); - } - break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: if (!sd->sif) { @@ -2071,28 +1655,13 @@ static int sd_config(struct gspca_dev *gspca_dev, break; } sd->brightness = BRIGHTNESS_DEF; - if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) - sd->contrast = 200; /* The default is too low for the ov6630 */ - else - sd->contrast = CONTRAST_DEF; + sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; sd->hflip = HFLIP_DEF; sd->vflip = VFLIP_DEF; - sd->autobrightness = AUTOBRIGHT_DEF; - if (sd->sensor == SEN_OV7670) { - sd->freq = OV7670_FREQ_DEF; - gspca_dev->ctrl_dis = 1 << FREQ_IDX; - } else { - sd->freq = FREQ_DEF; - gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | - (1 << OV7670_FREQ_IDX); - } - if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) - gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; - /* OV8610 Frequency filter control should work but needs testing */ - if (sd->sensor == SEN_OV8610) - gspca_dev->ctrl_dis |= 1 << FREQ_IDX; - + if (sd->sensor != SEN_OV7670) + gspca_dev->ctrl_dis = (1 << HFLIP_IDX) + | (1 << VFLIP_IDX); return 0; error: PDEBUG(D_ERR, "OV519 Config failed"); @@ -2111,7 +1680,6 @@ static int sd_init(struct gspca_dev *gspca_dev) return -EIO; break; case SEN_OV6630: - case SEN_OV66308AF: if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) return -EIO; break; @@ -2120,8 +1688,6 @@ static int sd_init(struct gspca_dev *gspca_dev) /* case SEN_OV76BE: */ if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610))) return -EIO; - if (i2c_w_mask(sd, 0x0e, 0x00, 0x40)) - return -EIO; break; case SEN_OV7620: if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) @@ -2143,126 +1709,6 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -/* Set up the OV511/OV511+ with the given image parameters. - * - * Do not put any sensor-specific code in here (including I2C I/O functions) - */ -static int ov511_mode_init_regs(struct sd *sd) -{ - int hsegs, vsegs, packet_size, fps, needed; - int interlaced = 0; - struct usb_host_interface *alt; - struct usb_interface *intf; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - PDEBUG(D_ERR, "Couldn't get altsetting"); - return -EIO; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5); - - reg_w(sd, R511_CAM_UV_EN, 0x01); - reg_w(sd, R511_SNAP_UV_EN, 0x01); - reg_w(sd, R511_SNAP_OPTS, 0x03); - - /* Here I'm assuming that snapshot size == image size. - * I hope that's always true. --claudio - */ - hsegs = (sd->gspca_dev.width >> 3) - 1; - vsegs = (sd->gspca_dev.height >> 3) - 1; - - reg_w(sd, R511_CAM_PXCNT, hsegs); - reg_w(sd, R511_CAM_LNCNT, vsegs); - reg_w(sd, R511_CAM_PXDIV, 0x00); - reg_w(sd, R511_CAM_LNDIV, 0x00); - - /* YUV420, low pass filter on */ - reg_w(sd, R511_CAM_OPTS, 0x03); - - /* Snapshot additions */ - reg_w(sd, R511_SNAP_PXCNT, hsegs); - reg_w(sd, R511_SNAP_LNCNT, vsegs); - reg_w(sd, R511_SNAP_PXDIV, 0x00); - reg_w(sd, R511_SNAP_LNDIV, 0x00); - - /******** Set the framerate ********/ - if (frame_rate > 0) - sd->frame_rate = frame_rate; - - switch (sd->sensor) { - case SEN_OV6620: - /* No framerate control, doesn't like higher rates yet */ - sd->clockdiv = 3; - break; - - /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed - for more sensors we need to do this for them too */ - case SEN_OV7620: - case SEN_OV7640: - case SEN_OV76BE: - if (sd->gspca_dev.width == 320) - interlaced = 1; - /* Fall through */ - case SEN_OV6630: - case SEN_OV7610: - case SEN_OV7670: - switch (sd->frame_rate) { - case 30: - case 25: - /* Not enough bandwidth to do 640x480 @ 30 fps */ - if (sd->gspca_dev.width != 640) { - sd->clockdiv = 0; - break; - } - /* Fall through for 640x480 case */ - default: -/* case 20: */ -/* case 15: */ - sd->clockdiv = 1; - break; - case 10: - sd->clockdiv = 2; - break; - case 5: - sd->clockdiv = 5; - break; - } - if (interlaced) { - sd->clockdiv = (sd->clockdiv + 1) * 2 - 1; - /* Higher then 10 does not work */ - if (sd->clockdiv > 10) - sd->clockdiv = 10; - } - break; - - case SEN_OV8610: - /* No framerate control ?? */ - sd->clockdiv = 0; - break; - } - - /* Check if we have enough bandwidth to disable compression */ - fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1; - needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2; - /* 1400 is a conservative estimate of the max nr of isoc packets/sec */ - if (needed > 1400 * packet_size) { - /* Enable Y and UV quantization and compression */ - reg_w(sd, R511_COMP_EN, 0x07); - reg_w(sd, R511_COMP_LUT_EN, 0x03); - } else { - reg_w(sd, R511_COMP_EN, 0x06); - reg_w(sd, R511_COMP_LUT_EN, 0x00); - } - - reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE); - reg_w(sd, R51x_SYS_RESET, 0); - - return 0; -} - /* Sets up the OV518/OV518+ with the given image parameters * * OV518 needs a completely different approach, until we can figure out what @@ -2272,19 +1718,7 @@ static int ov511_mode_init_regs(struct sd *sd) */ static int ov518_mode_init_regs(struct sd *sd) { - int hsegs, vsegs, packet_size; - struct usb_host_interface *alt; - struct usb_interface *intf; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - PDEBUG(D_ERR, "Couldn't get altsetting"); - return -EIO; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2); + int hsegs, vsegs; /******** Set the mode ********/ @@ -2321,30 +1755,20 @@ static int ov518_mode_init_regs(struct sd *sd) /* Windows driver does this here; who knows why */ reg_w(sd, 0x2f, 0x80); - /******** Set the framerate ********/ - sd->clockdiv = 1; + /******** Set the framerate (to 30 FPS) ********/ + if (sd->bridge == BRIDGE_OV518PLUS) + sd->clockdiv = 1; + else + sd->clockdiv = 0; /* Mode independent, but framerate dependent, regs */ - /* 0x51: Clock divider; Only works on some cams which use 2 crystals */ - reg_w(sd, 0x51, 0x04); + reg_w(sd, 0x51, 0x04); /* Clock divider; lower==faster */ reg_w(sd, 0x22, 0x18); reg_w(sd, 0x23, 0xff); - if (sd->bridge == BRIDGE_OV518PLUS) { - switch (sd->sensor) { - case SEN_OV7620: - if (sd->gspca_dev.width == 320) { - reg_w(sd, 0x20, 0x00); - reg_w(sd, 0x21, 0x19); - } else { - reg_w(sd, 0x20, 0x60); - reg_w(sd, 0x21, 0x1f); - } - break; - default: - reg_w(sd, 0x21, 0x19); - } - } else + if (sd->bridge == BRIDGE_OV518PLUS) + reg_w(sd, 0x21, 0x19); + else reg_w(sd, 0x71, 0x17); /* Compression-related? */ /* FIXME: Sensor-specific */ @@ -2455,11 +1879,7 @@ static int ov519_mode_init_regs(struct sd *sd) reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4); reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3); - if (sd->sensor == SEN_OV7670 && - sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv) - reg_w(sd, OV519_R12_X_OFFSETL, 0x04); - else - reg_w(sd, OV519_R12_X_OFFSETL, 0x00); + reg_w(sd, OV519_R12_X_OFFSETL, 0x00); reg_w(sd, OV519_R13_X_OFFSETH, 0x00); reg_w(sd, OV519_R14_Y_OFFSETL, 0x00); reg_w(sd, OV519_R15_Y_OFFSETH, 0x00); @@ -2551,7 +1971,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) int qvga; gspca_dev = &sd->gspca_dev; - qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; + qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; /******** Mode (VGA/QVGA) and sensor specific regs ********/ switch (sd->sensor) { @@ -2563,16 +1983,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd) i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); break; case SEN_OV7620: - case SEN_OV76BE: +/* i2c_w(sd, 0x2b, 0x00); */ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); - i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0); + i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); break; + case SEN_OV76BE: +/* i2c_w(sd, 0x2b, 0x00); */ + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + break; case SEN_OV7640: +/* i2c_w(sd, 0x2b, 0x00); */ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); /* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ @@ -2591,7 +2016,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd) break; case SEN_OV6620: case SEN_OV6630: - case SEN_OV66308AF: i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); break; default: @@ -2599,6 +2023,10 @@ static int mode_init_ov_sensor_regs(struct sd *sd) } /******** Palette-specific regs ********/ + if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { + /* not valid on the OV6620/OV7620/6630? */ + i2c_w_mask(sd, 0x0e, 0x00, 0x40); + } /* The OV518 needs special treatment. Although both the OV518 * and the OV6630 support a 16-bit video bus, only the 8 bit Y @@ -2608,12 +2036,25 @@ static int mode_init_ov_sensor_regs(struct sd *sd) /* OV7640 is 8-bit only */ - if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF && - sd->sensor != SEN_OV7640) + if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) i2c_w_mask(sd, 0x13, 0x00, 0x20); /******** Clock programming ********/ - i2c_w(sd, 0x11, sd->clockdiv); + /* The OV6620 needs special handling. This prevents the + * severe banding that normally occurs */ + if (sd->sensor == SEN_OV6620) { + + /* Clock down */ + i2c_w(sd, 0x2a, 0x04); + i2c_w(sd, 0x11, sd->clockdiv); + i2c_w(sd, 0x2a, 0x84); + /* This next setting is critical. It seems to improve + * the gain or the contrast. The "reserved" bits seem + * to have some effect in this case. */ + i2c_w(sd, 0x2d, 0x85); + } else { + i2c_w(sd, 0x11, sd->clockdiv); + } /******** Special Features ********/ /* no evidence this is possible with OV7670, either */ @@ -2657,14 +2098,13 @@ static void sethvflip(struct sd *sd) static int set_ov_sensor_window(struct sd *sd) { struct gspca_dev *gspca_dev; - int qvga, crop; + int qvga; int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; int ret, hstart, hstop, vstop, vstart; __u8 v; gspca_dev = &sd->gspca_dev; - qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; - crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2; + qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; /* The different sensor ICs handle setting up of window differently. * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ @@ -2683,19 +2123,14 @@ static int set_ov_sensor_window(struct sd *sd) break; case SEN_OV6620: case SEN_OV6630: - case SEN_OV66308AF: hwsbase = 0x38; hwebase = 0x3a; vwsbase = 0x05; vwebase = 0x06; - if (sd->sensor == SEN_OV66308AF && qvga) + if (qvga) { /* HDG: this fixes U and V getting swapped */ - hwsbase++; - if (crop) { - hwsbase += 8; - hwebase += 8; - vwsbase += 11; - vwebase += 11; + hwsbase--; + vwsbase--; } break; case SEN_OV7620: @@ -2720,7 +2155,6 @@ static int set_ov_sensor_window(struct sd *sd) switch (sd->sensor) { case SEN_OV6620: case SEN_OV6630: - case SEN_OV66308AF: if (qvga) { /* QCIF */ hwscale = 0; vwscale = 0; @@ -2773,7 +2207,7 @@ static int set_ov_sensor_window(struct sd *sd) if (qvga) { /* QVGA from ov7670.c by * Jonathan Corbet */ hstart = 164; - hstop = 28; + hstop = 20; vstart = 14; vstop = 494; } else { /* VGA */ @@ -2799,6 +2233,7 @@ static int set_ov_sensor_window(struct sd *sd) msleep(10); /* need to sleep between read and write to * same reg! */ i2c_w(sd, OV7670_REG_VREF, v); + sethvflip(sd); } else { i2c_w(sd, 0x17, hwsbase); i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); @@ -2815,10 +2250,6 @@ static int sd_start(struct gspca_dev *gspca_dev) int ret = 0; switch (sd->bridge) { - case BRIDGE_OV511: - case BRIDGE_OV511PLUS: - ret = ov511_mode_init_regs(sd); - break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: ret = ov518_mode_init_regs(sd); @@ -2837,9 +2268,6 @@ static int sd_start(struct gspca_dev *gspca_dev) setcontrast(gspca_dev); setbrightness(gspca_dev); setcolors(gspca_dev); - sethvflip(sd); - setautobrightness(sd); - setfreq(sd); ret = ov51x_restart(sd); if (ret < 0) @@ -2859,88 +2287,23 @@ static void sd_stopN(struct gspca_dev *gspca_dev) ov51x_led_control(sd, 0); } -static void ov511_pkt_scan(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, /* target */ - __u8 *in, /* isoc packet */ - int len) /* iso packet length */ -{ - struct sd *sd = (struct sd *) gspca_dev; - - /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th - * byte non-zero. The EOF packet has image width/height in the - * 10th and 11th bytes. The 9th byte is given as follows: - * - * bit 7: EOF - * 6: compression enabled - * 5: 422/420/400 modes - * 4: 422/420/400 modes - * 3: 1 - * 2: snapshot button on - * 1: snapshot frame - * 0: even/odd field - */ - if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) && - (in[8] & 0x08)) { - if (in[8] & 0x80) { - /* Frame end */ - if ((in[9] + 1) * 8 != gspca_dev->width || - (in[10] + 1) * 8 != gspca_dev->height) { - PDEBUG(D_ERR, "Invalid frame size, got: %dx%d," - " requested: %dx%d\n", - (in[9] + 1) * 8, (in[10] + 1) * 8, - gspca_dev->width, gspca_dev->height); - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } - /* Add 11 byte footer to frame, might be usefull */ - gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11); - return; - } else { - /* Frame start */ - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0); - sd->packet_nr = 0; - } - } - - /* Ignore the packet number */ - len--; - - /* intermediate packet */ - gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len); -} - static void ov518_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; + PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len); + + if (len & 7) { + len--; + PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]); + } /* A false positive here is likely, until OVT gives me * the definitive SOF/EOF format */ if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); - sd->packet_nr = 0; - } - - if (gspca_dev->last_packet_type == DISCARD_PACKET) - return; - - /* Does this device use packet numbers ? */ - if (len & 7) { - len--; - if (sd->packet_nr == data[len]) - sd->packet_nr++; - /* The last few packets of the frame (which are all 0's - except that they may contain part of the footer), are - numbered 0 */ - else if (sd->packet_nr == 0 || data[len]) { - PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)", - (int)data[len], (int)sd->packet_nr); - gspca_dev->last_packet_type = DISCARD_PACKET; - return; - } } /* intermediate packet */ @@ -3001,7 +2364,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, switch (sd->bridge) { case BRIDGE_OV511: case BRIDGE_OV511PLUS: - ov511_pkt_scan(gspca_dev, frame, data, len); break; case BRIDGE_OV518: case BRIDGE_OV518PLUS: @@ -3027,13 +2389,13 @@ static void setbrightness(struct gspca_dev *gspca_dev) case SEN_OV76BE: case SEN_OV6620: case SEN_OV6630: - case SEN_OV66308AF: case SEN_OV7640: i2c_w(sd, OV7610_REG_BRT, val); break; case SEN_OV7620: /* 7620 doesn't like manual changes when in auto mode */ - if (!sd->autobrightness) +/*fixme + * if (!sd->auto_brt) */ i2c_w(sd, OV7610_REG_BRT, val); break; case SEN_OV7670: @@ -3056,7 +2418,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) i2c_w(sd, OV7610_REG_CNT, val); break; case SEN_OV6630: - case SEN_OV66308AF: i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); break; case SEN_OV8610: { @@ -3101,7 +2462,6 @@ static void setcolors(struct gspca_dev *gspca_dev) case SEN_OV76BE: case SEN_OV6620: case SEN_OV6630: - case SEN_OV66308AF: i2c_w(sd, OV7610_REG_SAT, val); break; case SEN_OV7620: @@ -3122,72 +2482,6 @@ static void setcolors(struct gspca_dev *gspca_dev) } } -static void setautobrightness(struct sd *sd) -{ - if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) - return; - - i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10); -} - -static void setfreq(struct sd *sd) -{ - if (sd->sensor == SEN_OV7670) { - switch (sd->freq) { - case 0: /* Banding filter disabled */ - i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT); - break; - case 1: /* 50 hz */ - i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, - OV7670_COM8_BFILT); - i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18); - break; - case 2: /* 60 hz */ - i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, - OV7670_COM8_BFILT); - i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18); - break; - case 3: /* Auto hz */ - i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT, - OV7670_COM8_BFILT); - i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO, - 0x18); - break; - } - } else { - switch (sd->freq) { - case 0: /* Banding filter disabled */ - i2c_w_mask(sd, 0x2d, 0x00, 0x04); - i2c_w_mask(sd, 0x2a, 0x00, 0x80); - break; - case 1: /* 50 hz (filter on and framerate adj) */ - i2c_w_mask(sd, 0x2d, 0x04, 0x04); - i2c_w_mask(sd, 0x2a, 0x80, 0x80); - /* 20 fps -> 16.667 fps */ - if (sd->sensor == SEN_OV6620 || - sd->sensor == SEN_OV6630 || - sd->sensor == SEN_OV66308AF) - i2c_w(sd, 0x2b, 0x5e); - else - i2c_w(sd, 0x2b, 0xac); - break; - case 2: /* 60 hz (filter on, ...) */ - i2c_w_mask(sd, 0x2d, 0x04, 0x04); - if (sd->sensor == SEN_OV6620 || - sd->sensor == SEN_OV6630 || - sd->sensor == SEN_OV66308AF) { - /* 20 fps -> 15 fps */ - i2c_w_mask(sd, 0x2a, 0x80, 0x80); - i2c_w(sd, 0x2b, 0xa8); - } else { - /* no framerate adj. */ - i2c_w_mask(sd, 0x2a, 0x00, 0x80); - } - break; - } - } -} - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -3278,71 +2572,6 @@ static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->autobrightness = val; - if (gspca_dev->streaming) - setautobrightness(sd); - return 0; -} - -static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->autobrightness; - return 0; -} - -static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->freq = val; - if (gspca_dev->streaming) - setfreq(sd); - return 0; -} - -static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->freq; - return 0; -} - -static int sd_querymenu(struct gspca_dev *gspca_dev, - struct v4l2_querymenu *menu) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (menu->id) { - case V4L2_CID_POWER_LINE_FREQUENCY: - switch (menu->index) { - case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ - strcpy((char *) menu->name, "NoFliker"); - return 0; - case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy((char *) menu->name, "50 Hz"); - return 0; - case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy((char *) menu->name, "60 Hz"); - return 0; - case 3: - if (sd->sensor != SEN_OV7670) - return -EINVAL; - - strcpy((char *) menu->name, "Automatic"); - return 0; - } - break; - } - return -EINVAL; -} - /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -3353,7 +2582,6 @@ static const struct sd_desc sd_desc = { .start = sd_start, .stopN = sd_stopN, .pkt_scan = sd_pkt_scan, - .querymenu = sd_querymenu, }; /* -- module initialisation -- */ @@ -3362,22 +2590,17 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x041e, 0x4064), - .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, - {USB_DEVICE(0x041e, 0x4068), - .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, + {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 }, + {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 }, {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, - {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS }, {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, - {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, {} }; diff --git a/trunk/drivers/media/video/gspca/sonixj.c b/trunk/drivers/media/video/gspca/sonixj.c index 0d02f41fa7d0..dc6a6f11354a 100644 --- a/trunk/drivers/media/video/gspca/sonixj.c +++ b/trunk/drivers/media/video/gspca/sonixj.c @@ -46,7 +46,6 @@ struct sd { u8 gamma; u8 vflip; /* ov7630/ov7648 only */ u8 infrared; /* mt9v111 only */ - u8 freq; /* ov76xx only */ u8 quality; /* image quality */ #define QUALITY_MIN 60 #define QUALITY_MAX 95 @@ -97,11 +96,8 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val); static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define BRIGHTNESS_IDX 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -117,7 +113,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setbrightness, .get = sd_getbrightness, }, -#define CONTRAST_IDX 1 { { .id = V4L2_CID_CONTRAST, @@ -133,22 +128,20 @@ static struct ctrl sd_ctrls[] = { .set = sd_setcontrast, .get = sd_getcontrast, }, -#define COLOR_IDX 2 { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", + .name = "Color", .minimum = 0, .maximum = 40, .step = 1, -#define COLOR_DEF 25 +#define COLOR_DEF 32 .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, }, -#define BLUE_BALANCE_IDX 3 { { .id = V4L2_CID_BLUE_BALANCE, @@ -163,7 +156,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setblue_balance, .get = sd_getblue_balance, }, -#define RED_BALANCE_IDX 4 { { .id = V4L2_CID_RED_BALANCE, @@ -178,7 +170,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setred_balance, .get = sd_getred_balance, }, -#define GAMMA_IDX 5 { { .id = V4L2_CID_GAMMA, @@ -193,7 +184,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setgamma, .get = sd_getgamma, }, -#define AUTOGAIN_IDX 6 +#define AUTOGAIN_IDX 5 { { .id = V4L2_CID_AUTOGAIN, @@ -209,7 +200,7 @@ static struct ctrl sd_ctrls[] = { .get = sd_getautogain, }, /* ov7630/ov7648 only */ -#define VFLIP_IDX 7 +#define VFLIP_IDX 6 { { .id = V4L2_CID_VFLIP, @@ -218,14 +209,14 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, -#define VFLIP_DEF 0 +#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */ .default_value = VFLIP_DEF, }, .set = sd_setvflip, .get = sd_getvflip, }, /* mt9v111 only */ -#define INFRARED_IDX 8 +#define INFRARED_IDX 7 { { .id = V4L2_CID_INFRARED, @@ -240,44 +231,28 @@ static struct ctrl sd_ctrls[] = { .set = sd_setinfrared, .get = sd_getinfrared, }, -/* ov7630/ov7648/ov7660 only */ -#define FREQ_IDX 9 - { - { - .id = V4L2_CID_POWER_LINE_FREQUENCY, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Light frequency filter", - .minimum = 0, - .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ - .step = 1, -#define FREQ_DEF 2 - .default_value = FREQ_DEF, - }, - .set = sd_setfreq, - .get = sd_getfreq, - }, }; /* table of the disabled controls */ static __u32 ctrl_dis[] = { - (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), + (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_HV7131R 0 */ - (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), + (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_MI0360 1 */ - (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), + (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_MO4000 2 */ - (1 << VFLIP_IDX) | (1 << FREQ_IDX), + (1 << VFLIP_IDX), /* SENSOR_MT9V111 3 */ - (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX), + (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_OM6802 4 */ - (1 << INFRARED_IDX), + (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX), /* SENSOR_OV7630 5 */ (1 << INFRARED_IDX), /* SENSOR_OV7648 6 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_OV7660 7 */ - (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | - (1 << FREQ_IDX), /* SENSOR_SP80708 8 */ + (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), + /* SENSOR_SP80708 8 */ }; static const struct v4l2_pix_format vga_mode[] = { @@ -293,8 +268,7 @@ static const struct v4l2_pix_format vga_mode[] = { .priv = 1}, {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 640, - /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */ - .sizeimage = 640 * 480 * 3 / 4 + 590, + .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0}, }; @@ -630,9 +604,7 @@ static const u8 ov7630_sensor_init[][8] = { /* win: i2c_r from 00 to 80 */ {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10}, {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10}, -/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30) - 0x13 was 0xc0 change to 0xc3 for auto gain and exposure */ - {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10}, + {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10}, {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10}, {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10}, {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10}, @@ -666,8 +638,9 @@ static const u8 ov7630_sensor_init[][8] = { {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, /* */ -/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */ -/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */ + {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, /* */ {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10}, /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */ @@ -700,7 +673,7 @@ static const u8 ov7648_sensor_init[][8] = { {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10}, /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */ /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */ -/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */ + {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, /*...*/ /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN @@ -1321,9 +1294,11 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->gamma = GAMMA_DEF; sd->autogain = AUTOGAIN_DEF; sd->ag_cnt = -1; - sd->vflip = VFLIP_DEF; + if (sd->sensor != SENSOR_OV7630) + sd->vflip = 0; + else + sd->vflip = 1; sd->infrared = INFRARED_DEF; - sd->freq = FREQ_DEF; sd->quality = QUALITY_DEF; sd->jpegqual = 80; @@ -1594,7 +1569,7 @@ static void setautogain(struct gspca_dev *gspca_dev) else comb = 0xa0; if (sd->autogain) - comb |= 0x03; + comb |= 0x02; i2c_w1(&sd->gspca_dev, 0x13, comb); return; } @@ -1610,15 +1585,12 @@ static void setvflip(struct sd *sd) { u8 comn; - if (sd->sensor == SENSOR_OV7630) { + if (sd->sensor == SENSOR_OV7630) comn = 0x02; - if (!sd->vflip) - comn |= 0x80; - } else { + else comn = 0x06; - if (sd->vflip) - comn |= 0x80; - } + if (sd->vflip) + comn |= 0x80; i2c_w1(&sd->gspca_dev, 0x75, comn); } @@ -1630,58 +1602,6 @@ static void setinfrared(struct sd *sd) sd->infrared ? 0x66 : 0x64); } -static void setfreq(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - if (sd->sensor == SENSOR_OV7660) { - switch (sd->freq) { - case 0: /* Banding filter disabled */ - i2c_w1(gspca_dev, 0x13, 0xdf); - break; - case 1: /* 50 hz */ - i2c_w1(gspca_dev, 0x13, 0xff); - i2c_w1(gspca_dev, 0x3b, 0x0a); - break; - case 2: /* 60 hz */ - i2c_w1(gspca_dev, 0x13, 0xff); - i2c_w1(gspca_dev, 0x3b, 0x02); - break; - } - } else { - u8 reg2a = 0, reg2b = 0, reg2d = 0; - - /* Get reg2a / reg2d base values */ - switch (sd->sensor) { - case SENSOR_OV7630: - reg2a = 0x08; - reg2d = 0x01; - break; - case SENSOR_OV7648: - reg2a = 0x11; - reg2d = 0x81; - break; - } - - switch (sd->freq) { - case 0: /* Banding filter disabled */ - break; - case 1: /* 50 hz (filter on and framerate adj) */ - reg2a |= 0x80; - reg2b = 0xac; - reg2d |= 0x04; - break; - case 2: /* 60 hz (filter on, no framerate adj) */ - reg2a |= 0x80; - reg2d |= 0x04; - break; - } - i2c_w1(gspca_dev, 0x2a, reg2a); - i2c_w1(gspca_dev, 0x2b, reg2b); - i2c_w1(gspca_dev, 0x2d, reg2d); - } -} - static void setjpegqual(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1908,7 +1828,6 @@ static int sd_start(struct gspca_dev *gspca_dev) setbrightness(gspca_dev); setcontrast(gspca_dev); setautogain(gspca_dev); - setfreq(gspca_dev); return 0; } @@ -2212,24 +2131,6 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->freq = val; - if (gspca_dev->streaming) - setfreq(gspca_dev); - return 0; -} - -static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->freq; - return 0; -} - static int sd_set_jcomp(struct gspca_dev *gspca_dev, struct v4l2_jpegcompression *jcomp) { @@ -2258,27 +2159,6 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, return 0; } -static int sd_querymenu(struct gspca_dev *gspca_dev, - struct v4l2_querymenu *menu) -{ - switch (menu->id) { - case V4L2_CID_POWER_LINE_FREQUENCY: - switch (menu->index) { - case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ - strcpy((char *) menu->name, "NoFliker"); - return 0; - case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy((char *) menu->name, "50 Hz"); - return 0; - case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy((char *) menu->name, "60 Hz"); - return 0; - } - break; - } - return -EINVAL; -} - /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -2293,7 +2173,6 @@ static const struct sd_desc sd_desc = { .dq_callback = do_autogain, .get_jcomp = sd_get_jcomp, .set_jcomp = sd_set_jcomp, - .querymenu = sd_querymenu, }; /* -- module initialisation -- */ @@ -2354,7 +2233,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, #endif {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, - {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, {} }; diff --git a/trunk/drivers/media/video/gspca/stv06xx/Makefile b/trunk/drivers/media/video/gspca/stv06xx/Makefile index 2f3c3a606ce4..feeaa94ab588 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/Makefile +++ b/trunk/drivers/media/video/gspca/stv06xx/Makefile @@ -3,8 +3,7 @@ obj-$(CONFIG_USB_STV06XX) += gspca_stv06xx.o gspca_stv06xx-objs := stv06xx.o \ stv06xx_vv6410.o \ stv06xx_hdcs.o \ - stv06xx_pb0100.o \ - stv06xx_st6422.o + stv06xx_pb0100.o EXTRA_CFLAGS += -Idrivers/media/video/gspca diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx.c b/trunk/drivers/media/video/gspca/stv06xx/stv06xx.c index 0da8e0de0456..e573c3406324 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -92,10 +92,11 @@ static int stv06xx_write_sensor_finish(struct sd *sd) { int err = 0; - if (sd->bridge == BRIDGE_STV610) { + if (IS_850(sd)) { struct usb_device *udev = sd->gspca_dev.dev; __u8 *buf = sd->gspca_dev.usb_buf; + /* Quickam Web needs an extra packet */ buf[0] = 0; err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x04, 0x40, 0x1704, 0, buf, 1, @@ -252,7 +253,7 @@ static int stv06xx_init(struct gspca_dev *gspca_dev) err = sd->sensor->init(sd); - if (dump_sensor && sd->sensor->dump) + if (dump_sensor) sd->sensor->dump(sd); return (err < 0) ? err : 0; @@ -317,8 +318,6 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_PACK, "Packet of length %d arrived", len); /* A packet may contain several frames @@ -344,29 +343,14 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, if (len < chunk_len) { PDEBUG(D_ERR, "URB packet length is smaller" " than the specified chunk length"); - gspca_dev->last_packet_type = DISCARD_PACKET; return; } - /* First byte seem to be 02=data 2nd byte is unknown??? */ - if (sd->bridge == BRIDGE_ST6422 && (id & 0xFF00) == 0x0200) - goto frame_data; - switch (id) { case 0x0200: case 0x4200: -frame_data: PDEBUG(D_PACK, "Frame data packet detected"); - if (sd->to_skip) { - int skip = (sd->to_skip < chunk_len) ? - sd->to_skip : chunk_len; - data += skip; - len -= skip; - chunk_len -= skip; - sd->to_skip -= skip; - } - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, chunk_len); break; @@ -381,9 +365,6 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); - if (sd->bridge == BRIDGE_ST6422) - sd->to_skip = gspca_dev->width * 4; - if (chunk_len) PDEBUG(D_ERR, "Chunk length is " "non-zero on a SOF"); @@ -414,12 +395,8 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, /* Unknown chunk with 2 bytes of data, occurs 2-3 times per USB interrupt */ break; - case 0x42ff: - PDEBUG(D_PACK, "Chunk 0x42ff detected"); - /* Special chunk seen sometimes on the ST6422 */ - break; default: - PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id); + PDEBUG(D_PACK, "Unknown chunk %d detected", id); /* Unknown chunk */ } data += chunk_len; @@ -451,16 +428,11 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; sd->desc = sd_desc; - sd->bridge = id->driver_info; gspca_dev->sd_desc = &sd->desc; if (dump_bridge) stv06xx_dump_bridge(sd); - sd->sensor = &stv06xx_sensor_st6422; - if (!sd->sensor->probe(sd)) - return 0; - sd->sensor = &stv06xx_sensor_vv6410; if (!sd->sensor->probe(sd)) return 0; @@ -485,20 +457,9 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - /* QuickCam Express */ - {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, - /* LEGO cam / QuickCam Web */ - {USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 }, - /* Dexxa WebCam USB */ - {USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 }, - /* QuickCam Messenger */ - {USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Communicate */ - {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Messenger (new) */ - {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 }, - /* QuickCam Messenger (new) */ - {USB_DEVICE(0x046D, 0x08DA), .driver_info = BRIDGE_ST6422 }, + {USB_DEVICE(0x046d, 0x0840)}, /* QuickCam Express */ + {USB_DEVICE(0x046d, 0x0850)}, /* LEGO cam / QuickCam Web */ + {USB_DEVICE(0x046d, 0x0870)}, /* Dexxa WebCam USB */ {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx.h b/trunk/drivers/media/video/gspca/stv06xx/stv06xx.h index 9df7137fe67e..1207e7d17f14 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx.h +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx.h @@ -93,17 +93,6 @@ struct sd { /* Sensor private data */ void *sensor_priv; - - /* The first 4 lines produced by the stv6422 are no good, this keeps - track of how many bytes we still need to skip during a frame */ - int to_skip; - - /* Bridge / Camera type */ - u8 bridge; - #define BRIDGE_STV600 0 - #define BRIDGE_STV602 1 - #define BRIDGE_STV610 2 - #define BRIDGE_ST6422 3 /* With integrated sensor */ }; int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data); diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c index 3039ec208f3a..b16903814203 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c @@ -434,7 +434,7 @@ static int hdcs_probe_1x00(struct sd *sd) hdcs->exp.er = 100; /* - * Frame rate on HDCS-1000 with STV600 depends on PSMP: + * Frame rate on HDCS-1000 0x46D:0x840 depends on PSMP: * 4 = doesn't work at all * 5 = 7.8 fps, * 6 = 6.9 fps, @@ -443,7 +443,7 @@ static int hdcs_probe_1x00(struct sd *sd) * 15 = 4.4 fps, * 31 = 2.8 fps * - * Frame rate on HDCS-1000 with STV602 depends on PSMP: + * Frame rate on HDCS-1000 0x46D:0x870 depends on PSMP: * 15 = doesn't work at all * 18 = doesn't work at all * 19 = 7.3 fps @@ -453,7 +453,7 @@ static int hdcs_probe_1x00(struct sd *sd) * 24 = 6.3 fps * 30 = 5.4 fps */ - hdcs->psmp = (sd->bridge == BRIDGE_STV602) ? 20 : 5; + hdcs->psmp = IS_870(sd) ? 20 : 5; sd->sensor_priv = hdcs; @@ -530,7 +530,7 @@ static int hdcs_init(struct sd *sd) int i, err = 0; /* Set the STV0602AA in STV0600 emulation mode */ - if (sd->bridge == BRIDGE_STV602) + if (IS_870(sd)) stv06xx_write_bridge(sd, STV_STV0600_EMULATION, 1); /* Execute the bridge init */ @@ -558,7 +558,7 @@ static int hdcs_init(struct sd *sd) return err; /* Set PGA sample duration - (was 0x7E for the STV602, but caused slow framerate with HDCS-1020) */ + (was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */ if (IS_1020(sd)) err = stv06xx_write_sensor(sd, HDCS_TCTRL, (HDCS_ADC_START_SIG_DUR << 6) | hdcs->psmp); diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h index 934b9cebc1ab..e88c42f7d2f8 100644 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h +++ b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h @@ -32,13 +32,14 @@ #include "stv06xx.h" +#define IS_850(sd) ((sd)->gspca_dev.dev->descriptor.idProduct == 0x850) +#define IS_870(sd) ((sd)->gspca_dev.dev->descriptor.idProduct == 0x870) #define IS_1020(sd) ((sd)->sensor == &stv06xx_sensor_hdcs1020) extern const struct stv06xx_sensor stv06xx_sensor_vv6410; extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00; extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020; extern const struct stv06xx_sensor stv06xx_sensor_pb0100; -extern const struct stv06xx_sensor stv06xx_sensor_st6422; struct stv06xx_sensor { /* Defines the name of a sensor */ diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c deleted file mode 100644 index 87cb5b9ddfa7..000000000000 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Support for the sensor part which is integrated (I think) into the - * st6422 stv06xx alike bridge, as its integrated there are no i2c writes - * but instead direct bridge writes. - * - * Copyright (c) 2009 Hans de Goede - * - * Strongly based on qc-usb-messenger, which is: - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * - * 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 - * - */ - -#include "stv06xx_st6422.h" - -static struct v4l2_pix_format st6422_mode[] = { - /* Note we actually get 124 lines of data, of which we skip the 4st - 4 as they are garbage */ - { - 162, - 120, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 162 * 120, - .bytesperline = 162, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 1 - }, - /* Note we actually get 248 lines of data, of which we skip the 4st - 4 as they are garbage, and we tell the app it only gets the - first 240 of the 244 lines it actually gets, so that it ignores - the last 4. */ - { - 324, - 240, - V4L2_PIX_FMT_SGRBG8, - V4L2_FIELD_NONE, - .sizeimage = 324 * 244, - .bytesperline = 324, - .colorspace = V4L2_COLORSPACE_SRGB, - .priv = 0 - }, -}; - -static const struct ctrl st6422_ctrl[] = { -#define BRIGHTNESS_IDX 0 - { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 31, - .step = 1, - .default_value = 3 - }, - .set = st6422_set_brightness, - .get = st6422_get_brightness - }, -#define CONTRAST_IDX 1 - { - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 15, - .step = 1, - .default_value = 11 - }, - .set = st6422_set_contrast, - .get = st6422_get_contrast - }, -#define GAIN_IDX 2 - { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 64 - }, - .set = st6422_set_gain, - .get = st6422_get_gain - }, -#define EXPOSURE_IDX 3 - { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 0, - .maximum = 1023, - .step = 1, - .default_value = 256 - }, - .set = st6422_set_exposure, - .get = st6422_get_exposure - }, -}; - -static int st6422_probe(struct sd *sd) -{ - int i; - s32 *sensor_settings; - - if (sd->bridge != BRIDGE_ST6422) - return -ENODEV; - - info("st6422 sensor detected"); - - sensor_settings = kmalloc(ARRAY_SIZE(st6422_ctrl) * sizeof(s32), - GFP_KERNEL); - if (!sensor_settings) - return -ENOMEM; - - sd->gspca_dev.cam.cam_mode = st6422_mode; - sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); - sd->desc.ctrls = st6422_ctrl; - sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl); - sd->sensor_priv = sensor_settings; - - for (i = 0; i < sd->desc.nctrls; i++) - sensor_settings[i] = st6422_ctrl[i].qctrl.default_value; - - return 0; -} - -static int st6422_init(struct sd *sd) -{ - int err = 0, i; - - const u16 st6422_bridge_init[][2] = { - { STV_ISO_ENABLE, 0x00 }, /* disable capture */ - { 0x1436, 0x00 }, - { 0x1432, 0x03 }, /* 0x00-0x1F brightness */ - { 0x143a, 0xF9 }, /* 0x00-0x0F contrast */ - { 0x0509, 0x38 }, /* R */ - { 0x050a, 0x38 }, /* G */ - { 0x050b, 0x38 }, /* B */ - { 0x050c, 0x2A }, - { 0x050d, 0x01 }, - - - { 0x1431, 0x00 }, /* 0x00-0x07 ??? */ - { 0x1433, 0x34 }, /* 160x120, 0x00-0x01 night filter */ - { 0x1438, 0x18 }, /* 640x480 */ -/* 18 bayes */ -/* 10 compressed? */ - - { 0x1439, 0x00 }, -/* antiflimmer?? 0xa2 ger perfekt bild mot monitor */ - - { 0x143b, 0x05 }, - { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */ - - -/* shutter time 0x0000-0x03FF */ -/* low value give good picures on moving objects (but requires much light) */ -/* high value gives good picures in darkness (but tends to be overexposed) */ - { 0x143e, 0x01 }, - { 0x143d, 0x00 }, - - { 0x1442, 0xe2 }, -/* write: 1x1x xxxx */ -/* read: 1x1x xxxx */ -/* bit 5 == button pressed and hold if 0 */ -/* write 0xe2,0xea */ - -/* 0x144a */ -/* 0x00 init */ -/* bit 7 == button has been pressed, but not handled */ - -/* interrupt */ -/* if(urb->iso_frame_desc[i].status == 0x80) { */ -/* if(urb->iso_frame_desc[i].status == 0x88) { */ - - { 0x1500, 0xd0 }, - { 0x1500, 0xd0 }, - { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */ - - { 0x1501, 0xaf }, -/* high val-> ljus area blir morkare. */ -/* low val -> ljus area blir ljusare. */ - { 0x1502, 0xc2 }, -/* high val-> ljus area blir morkare. */ -/* low val -> ljus area blir ljusare. */ - { 0x1503, 0x45 }, -/* high val-> ljus area blir morkare. */ -/* low val -> ljus area blir ljusare. */ - - { 0x1505, 0x02 }, -/* 2 : 324x248 80352 bytes */ -/* 7 : 248x162 40176 bytes */ -/* c+f: 162*124 20088 bytes */ - - { 0x150e, 0x8e }, - { 0x150f, 0x37 }, - { 0x15c0, 0x00 }, - { 0x15c1, 1023 }, /* 160x120, ISOC_PACKET_SIZE */ - { 0x15c3, 0x08 }, /* 0x04/0x14 ... test pictures ??? */ - - - { 0x143f, 0x01 }, /* commit settings */ - - }; - - for (i = 0; i < ARRAY_SIZE(st6422_bridge_init) && !err; i++) { - err = stv06xx_write_bridge(sd, st6422_bridge_init[i][0], - st6422_bridge_init[i][1]); - } - - return err; -} - -static void st6422_disconnect(struct sd *sd) -{ - sd->sensor = NULL; - kfree(sd->sensor_priv); -} - -static int st6422_start(struct sd *sd) -{ - int err, packet_size; - struct cam *cam = &sd->gspca_dev.cam; - s32 *sensor_settings = sd->sensor_priv; - struct usb_host_interface *alt; - struct usb_interface *intf; - - intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); - alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); - if (!alt) { - PDEBUG(D_ERR, "Couldn't get altsetting"); - return -EIO; - } - - packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); - err = stv06xx_write_bridge(sd, 0x15c1, packet_size); - if (err < 0) - return err; - - if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) - err = stv06xx_write_bridge(sd, 0x1505, 0x0f); - else - err = stv06xx_write_bridge(sd, 0x1505, 0x02); - if (err < 0) - return err; - - err = st6422_set_brightness(&sd->gspca_dev, - sensor_settings[BRIGHTNESS_IDX]); - if (err < 0) - return err; - - err = st6422_set_contrast(&sd->gspca_dev, - sensor_settings[CONTRAST_IDX]); - if (err < 0) - return err; - - err = st6422_set_exposure(&sd->gspca_dev, - sensor_settings[EXPOSURE_IDX]); - if (err < 0) - return err; - - err = st6422_set_gain(&sd->gspca_dev, - sensor_settings[GAIN_IDX]); - if (err < 0) - return err; - - PDEBUG(D_STREAM, "Starting stream"); - - return 0; -} - -static int st6422_stop(struct sd *sd) -{ - PDEBUG(D_STREAM, "Halting stream"); - - return 0; -} - -static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[BRIGHTNESS_IDX]; - - PDEBUG(D_V4L2, "Read brightness %d", *val); - - return 0; -} - -static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[BRIGHTNESS_IDX] = val; - - if (!gspca_dev->streaming) - return 0; - - /* val goes from 0 -> 31 */ - PDEBUG(D_V4L2, "Set brightness to %d", val); - err = stv06xx_write_bridge(sd, 0x1432, val); - if (err < 0) - return err; - - /* commit settings */ - err = stv06xx_write_bridge(sd, 0x143f, 0x01); - return (err < 0) ? err : 0; -} - -static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[CONTRAST_IDX]; - - PDEBUG(D_V4L2, "Read contrast %d", *val); - - return 0; -} - -static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[CONTRAST_IDX] = val; - - if (!gspca_dev->streaming) - return 0; - - /* Val goes from 0 -> 15 */ - PDEBUG(D_V4L2, "Set contrast to %d\n", val); - err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val); - if (err < 0) - return err; - - /* commit settings */ - err = stv06xx_write_bridge(sd, 0x143f, 0x01); - return (err < 0) ? err : 0; -} - -static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[GAIN_IDX]; - - PDEBUG(D_V4L2, "Read gain %d", *val); - - return 0; -} - -static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[GAIN_IDX] = val; - - if (!gspca_dev->streaming) - return 0; - - PDEBUG(D_V4L2, "Set gain to %d", val); - - /* Set red, green, blue, gain */ - err = stv06xx_write_bridge(sd, 0x0509, val); - if (err < 0) - return err; - - err = stv06xx_write_bridge(sd, 0x050a, val); - if (err < 0) - return err; - - err = stv06xx_write_bridge(sd, 0x050b, val); - if (err < 0) - return err; - - /* 2 mystery writes */ - err = stv06xx_write_bridge(sd, 0x050c, 0x2a); - if (err < 0) - return err; - - err = stv06xx_write_bridge(sd, 0x050d, 0x01); - if (err < 0) - return err; - - /* commit settings */ - err = stv06xx_write_bridge(sd, 0x143f, 0x01); - return (err < 0) ? err : 0; -} - -static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - *val = sensor_settings[EXPOSURE_IDX]; - - PDEBUG(D_V4L2, "Read exposure %d", *val); - - return 0; -} - -static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val) -{ - int err; - struct sd *sd = (struct sd *) gspca_dev; - s32 *sensor_settings = sd->sensor_priv; - - sensor_settings[EXPOSURE_IDX] = val; - - if (!gspca_dev->streaming) - return 0; - - PDEBUG(D_V4L2, "Set exposure to %d\n", val); - err = stv06xx_write_bridge(sd, 0x143d, val & 0xff); - if (err < 0) - return err; - - err = stv06xx_write_bridge(sd, 0x143e, val >> 8); - if (err < 0) - return err; - - /* commit settings */ - err = stv06xx_write_bridge(sd, 0x143f, 0x01); - return (err < 0) ? err : 0; -} diff --git a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h b/trunk/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h deleted file mode 100644 index b2d45fe50522..000000000000 --- a/trunk/drivers/media/video/gspca/stv06xx/stv06xx_st6422.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Support for the sensor part which is integrated (I think) into the - * st6422 stv06xx alike bridge, as its integrated there are no i2c writes - * but instead direct bridge writes. - * - * Copyright (c) 2009 Hans de Goede - * - * Strongly based on qc-usb-messenger, which is: - * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher - * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland - * Copyright (c) 2002, 2003 Tuukka Toivonen - * - * 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 - * - */ - -#ifndef STV06XX_ST6422_H_ -#define STV06XX_ST6422_H_ - -#include "stv06xx_sensor.h" - -static int st6422_probe(struct sd *sd); -static int st6422_start(struct sd *sd); -static int st6422_init(struct sd *sd); -static int st6422_stop(struct sd *sd); -static void st6422_disconnect(struct sd *sd); - -/* V4L2 controls supported by the driver */ -static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val); -static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val); -static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val); -static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val); -static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val); -static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val); -static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); -static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val); - -const struct stv06xx_sensor stv06xx_sensor_st6422 = { - .name = "ST6422", - .init = st6422_init, - .probe = st6422_probe, - .start = st6422_start, - .stop = st6422_stop, - .disconnect = st6422_disconnect, -}; - -#endif diff --git a/trunk/drivers/media/video/ivtv/ivtv-controls.c b/trunk/drivers/media/video/ivtv/ivtv-controls.c index a3b77ed3f089..84995bcf4a75 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-controls.c +++ b/trunk/drivers/media/video/ivtv/ivtv-controls.c @@ -60,8 +60,6 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) switch (qctrl->id) { /* Standard V4L2 controls */ - case V4L2_CID_USER_CLASS: - return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0); case V4L2_CID_BRIGHTNESS: case V4L2_CID_HUE: case V4L2_CID_SATURATION: diff --git a/trunk/drivers/media/video/mt9m001.c b/trunk/drivers/media/video/mt9m001.c index 4d794b42d6cd..459c04cbf69d 100644 --- a/trunk/drivers/media/video/mt9m001.c +++ b/trunk/drivers/media/video/mt9m001.c @@ -280,9 +280,15 @@ static int mt9m001_try_fmt(struct soc_camera_device *icd, { struct v4l2_pix_format *pix = &f->fmt.pix; - v4l_bound_align_image(&pix->width, 48, 1280, 1, - &pix->height, 32 + icd->y_skip_top, - 1024 + icd->y_skip_top, 0, 0); + if (pix->height < 32 + icd->y_skip_top) + pix->height = 32 + icd->y_skip_top; + if (pix->height > 1024 + icd->y_skip_top) + pix->height = 1024 + icd->y_skip_top; + if (pix->width < 48) + pix->width = 48; + if (pix->width > 1280) + pix->width = 1280; + pix->width &= ~0x01; /* has to be even, unsure why was ~3 */ return 0; } diff --git a/trunk/drivers/media/video/mt9t031.c b/trunk/drivers/media/video/mt9t031.c index 4207fb342670..f72aeb7c4deb 100644 --- a/trunk/drivers/media/video/mt9t031.c +++ b/trunk/drivers/media/video/mt9t031.c @@ -385,9 +385,17 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd, { struct v4l2_pix_format *pix = &f->fmt.pix; - v4l_bound_align_image( - &pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, - &pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); + if (pix->height < MT9T031_MIN_HEIGHT) + pix->height = MT9T031_MIN_HEIGHT; + if (pix->height > MT9T031_MAX_HEIGHT) + pix->height = MT9T031_MAX_HEIGHT; + if (pix->width < MT9T031_MIN_WIDTH) + pix->width = MT9T031_MIN_WIDTH; + if (pix->width > MT9T031_MAX_WIDTH) + pix->width = MT9T031_MAX_WIDTH; + + pix->width &= ~0x01; /* has to be even */ + pix->height &= ~0x01; /* has to be even */ return 0; } diff --git a/trunk/drivers/media/video/mt9v022.c b/trunk/drivers/media/video/mt9v022.c index dbdcc86ae50d..be20d312b1dc 100644 --- a/trunk/drivers/media/video/mt9v022.c +++ b/trunk/drivers/media/video/mt9v022.c @@ -364,9 +364,15 @@ static int mt9v022_try_fmt(struct soc_camera_device *icd, { struct v4l2_pix_format *pix = &f->fmt.pix; - v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */, - &pix->height, 32 + icd->y_skip_top, - 480 + icd->y_skip_top, 0, 0); + if (pix->height < 32 + icd->y_skip_top) + pix->height = 32 + icd->y_skip_top; + if (pix->height > 480 + icd->y_skip_top) + pix->height = 480 + icd->y_skip_top; + if (pix->width < 48) + pix->width = 48; + if (pix->width > 752) + pix->width = 752; + pix->width &= ~0x03; /* ? */ return 0; } diff --git a/trunk/drivers/media/video/ov511.c b/trunk/drivers/media/video/ov511.c index 0bc2cf573c76..08cfd3e4ae8a 100644 --- a/trunk/drivers/media/video/ov511.c +++ b/trunk/drivers/media/video/ov511.c @@ -211,6 +211,8 @@ static const int i2c_detect_tries = 5; static struct usb_device_id device_table [] = { { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) }, { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) }, + { USB_DEVICE(VEND_OMNIVISION, PROD_OV518) }, + { USB_DEVICE(VEND_OMNIVISION, PROD_OV518PLUS) }, { USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c index 416933ca607d..10ef1a2c13ea 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c @@ -48,13 +48,11 @@ static const int routing_scheme0[] = { MSP_DSP_IN_SCART), }; -static const struct routing_scheme routing_def0 = { - .def = routing_scheme0, - .cnt = ARRAY_SIZE(routing_scheme0), -}; - -static const struct routing_scheme *routing_schemes[] = { - [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, +static const struct routing_scheme routing_schemes[] = { + [PVR2_ROUTING_SCHEME_HAUPPAUGE] = { + .def = routing_scheme0, + .cnt = ARRAY_SIZE(routing_scheme0), + }, }; void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) @@ -67,7 +65,7 @@ void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo"); if ((sid < ARRAY_SIZE(routing_schemes)) && - ((sp = routing_schemes[sid]) != NULL) && + ((sp = routing_schemes + sid) != NULL) && (hdw->input_val >= 0) && (hdw->input_val < sp->cnt)) { input = sp->def[hdw->input_val]; diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c index 68980e19409f..9023adf3fdcc 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c @@ -49,13 +49,11 @@ static const int routing_scheme1[] = { [PVR2_CVAL_INPUT_SVIDEO] = 0, }; -static const struct routing_scheme routing_def1 = { - .def = routing_scheme1, - .cnt = ARRAY_SIZE(routing_scheme1), -}; - -static const struct routing_scheme *routing_schemes[] = { - [PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1, +static const struct routing_scheme routing_schemes[] = { + [PVR2_ROUTING_SCHEME_ONAIR] = { + .def = routing_scheme1, + .cnt = ARRAY_SIZE(routing_scheme1), + }, }; @@ -67,11 +65,12 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) u32 input; pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)", hdw->input_val); - sp = (sid < ARRAY_SIZE(routing_schemes)) ? - routing_schemes[sid] : NULL; - if ((sp == NULL) || - (hdw->input_val < 0) || - (hdw->input_val >= sp->cnt)) { + if ((sid < ARRAY_SIZE(routing_schemes)) && + ((sp = routing_schemes + sid) != NULL) && + (hdw->input_val >= 0) && + (hdw->input_val < sp->cnt)) { + input = sp->def[hdw->input_val]; + } else { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "*** WARNING *** subdev v4l2 set_input:" " Invalid routing scheme (%u)" @@ -79,7 +78,6 @@ void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) sid, hdw->input_val); return; } - input = sp->def[hdw->input_val]; sd->ops->audio->s_routing(sd, input, 0, 0); } } diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index 82c135835753..05e52358ae49 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -68,11 +68,6 @@ static const struct routing_scheme_item routing_scheme0[] = { }, }; -static const struct routing_scheme routing_def0 = { - .def = routing_scheme0, - .cnt = ARRAY_SIZE(routing_scheme0), -}; - /* Specific to gotview device */ static const struct routing_scheme_item routing_schemegv[] = { [PVR2_CVAL_INPUT_TV] = { @@ -95,14 +90,15 @@ static const struct routing_scheme_item routing_schemegv[] = { }, }; -static const struct routing_scheme routing_defgv = { - .def = routing_schemegv, - .cnt = ARRAY_SIZE(routing_schemegv), -}; - -static const struct routing_scheme *routing_schemes[] = { - [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, - [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv, +static const struct routing_scheme routing_schemes[] = { + [PVR2_ROUTING_SCHEME_HAUPPAUGE] = { + .def = routing_scheme0, + .cnt = ARRAY_SIZE(routing_scheme0), + }, + [PVR2_ROUTING_SCHEME_GOTVIEW] = { + .def = routing_schemegv, + .cnt = ARRAY_SIZE(routing_schemegv), + }, }; void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) @@ -114,11 +110,13 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) const struct routing_scheme *sp; unsigned int sid = hdw->hdw_desc->signal_routing_scheme; - sp = (sid < ARRAY_SIZE(routing_schemes)) ? - routing_schemes[sid] : NULL; - if ((sp == NULL) || - (hdw->input_val < 0) || - (hdw->input_val >= sp->cnt)) { + if ((sid < ARRAY_SIZE(routing_schemes)) && + ((sp = routing_schemes + sid) != NULL) && + (hdw->input_val >= 0) && + (hdw->input_val < sp->cnt)) { + vid_input = sp->def[hdw->input_val].vid; + aud_input = sp->def[hdw->input_val].aud; + } else { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "*** WARNING *** subdev cx2584x set_input:" " Invalid routing scheme (%u)" @@ -126,8 +124,7 @@ void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) sid, hdw->input_val); return; } - vid_input = sp->def[hdw->input_val].vid; - aud_input = sp->def[hdw->input_val].aud; + pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x set_input vid=0x%x aud=0x%x", vid_input, aud_input); diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c index cbc388729d77..0c745b142fb7 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -85,8 +85,8 @@ MODULE_PARM_DESC(video_std,"specify initial video standard"); module_param_array(tolerance, int, NULL, 0444); MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); -/* US Broadcast channel 3 (61.25 MHz), to help with testing */ -static int default_tv_freq = 61250000L; +/* US Broadcast channel 7 (175.25 MHz) */ +static int default_tv_freq = 175250000L; /* 104.3 MHz, a usable FM station for my area */ static int default_radio_freq = 104300000L; @@ -1987,34 +1987,6 @@ static unsigned int pvr2_copy_i2c_addr_list( } -static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw) -{ - /* - Mike Isely 19-Nov-2006 - This bit of nuttiness - for cx25840 causes that module to correctly set up its video - scaling. This is really a problem in the cx25840 module itself, - but we work around it here. The problem has not been seen in - ivtv because there VBI is supported and set up. We don't do VBI - here (at least not yet) and thus we never attempted to even set - it up. - */ - struct v4l2_format fmt; - if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) { - /* We're not using a cx25840 so don't enable the hack */ - return; - } - - pvr2_trace(PVR2_TRACE_INIT, - "Module ID %u:" - " Executing cx25840 VBI hack", - hdw->decoder_client_id); - memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, - video, s_fmt, &fmt); -} - - static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, const struct pvr2_device_client_desc *cd) { @@ -2106,6 +2078,30 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw, /* client-specific setup... */ switch (mid) { case PVR2_CLIENT_ID_CX25840: + hdw->decoder_client_id = mid; + { + /* + Mike Isely 19-Nov-2006 - This + bit of nuttiness for cx25840 causes that module + to correctly set up its video scaling. This is + really a problem in the cx25840 module itself, + but we work around it here. The problem has not + been seen in ivtv because there VBI is supported + and set up. We don't do VBI here (at least not + yet) and thus we never attempted to even set it + up. + */ + struct v4l2_format fmt; + pvr2_trace(PVR2_TRACE_INIT, + "Module ID %u:" + " Executing cx25840 VBI hack", + mid); + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; + v4l2_device_call_all(&hdw->v4l2_dev, mid, + video, s_fmt, &fmt); + } + break; case PVR2_CLIENT_ID_SAA7115: hdw->decoder_client_id = mid; break; @@ -2206,8 +2202,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) cptr->info->set_value(cptr,~0,cptr->info->default_value); } - pvr2_hdw_cx25840_vbi_hack(hdw); - /* Set up special default values for the television and radio frequencies here. It's not really important what these defaults are, but I set them to something usable in the Chicago area just @@ -2960,7 +2954,6 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) vs = hdw->std_mask_cur; v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_std, vs); - pvr2_hdw_cx25840_vbi_hack(hdw); } hdw->tuner_signal_stale = !0; hdw->cropcap_stale = !0; @@ -4083,7 +4076,6 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) if (hdw->decoder_client_id) { v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, core, reset, 0); - pvr2_hdw_cx25840_vbi_hack(hdw); return 0; } pvr2_trace(PVR2_TRACE_INIT, diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c index 4c96cf48c796..d2fe7c8f2c3a 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c @@ -54,11 +54,6 @@ static const int routing_scheme0[] = { [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, }; -static const struct routing_scheme routing_def0 = { - .def = routing_scheme0, - .cnt = ARRAY_SIZE(routing_scheme0), -}; - static const int routing_scheme1[] = { [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4, [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5, @@ -66,14 +61,15 @@ static const int routing_scheme1[] = { [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */ }; -static const struct routing_scheme routing_def1 = { - .def = routing_scheme1, - .cnt = ARRAY_SIZE(routing_scheme1), -}; - -static const struct routing_scheme *routing_schemes[] = { - [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, - [PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1, +static const struct routing_scheme routing_schemes[] = { + [PVR2_ROUTING_SCHEME_HAUPPAUGE] = { + .def = routing_scheme0, + .cnt = ARRAY_SIZE(routing_scheme0), + }, + [PVR2_ROUTING_SCHEME_ONAIR] = { + .def = routing_scheme1, + .cnt = ARRAY_SIZE(routing_scheme1), + }, }; void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) @@ -85,12 +81,12 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)", hdw->input_val); - - sp = (sid < ARRAY_SIZE(routing_schemes)) ? - routing_schemes[sid] : NULL; - if ((sp == NULL) || - (hdw->input_val < 0) || - (hdw->input_val >= sp->cnt)) { + if ((sid < ARRAY_SIZE(routing_schemes)) && + ((sp = routing_schemes + sid) != NULL) && + (hdw->input_val >= 0) && + (hdw->input_val < sp->cnt)) { + input = sp->def[hdw->input_val]; + } else { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "*** WARNING *** subdev v4l2 set_input:" " Invalid routing scheme (%u)" @@ -98,7 +94,6 @@ void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) sid, hdw->input_val); return; } - input = sp->def[hdw->input_val]; sd->ops->video->s_routing(sd, input, 0, 0); } } diff --git a/trunk/drivers/media/video/pxa_camera.c b/trunk/drivers/media/video/pxa_camera.c index 46e0d8ad880f..f60de40fd21f 100644 --- a/trunk/drivers/media/video/pxa_camera.c +++ b/trunk/drivers/media/video/pxa_camera.c @@ -162,6 +162,13 @@ CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \ CICR0_EOFM | CICR0_FOM) +/* + * YUV422P picture size should be a multiple of 16, so the heuristic aligns + * height, width on 4 byte boundaries to reach the 16 multiple for the size. + */ +#define YUV422P_X_Y_ALIGN 4 +#define YUV422P_SIZE_ALIGN YUV422P_X_Y_ALIGN * YUV422P_X_Y_ALIGN + /* * Structures */ @@ -1391,15 +1398,28 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, return -EINVAL; } + /* limit to pxa hardware capabilities */ + if (pix->height < 32) + pix->height = 32; + if (pix->height > 2048) + pix->height = 2048; + if (pix->width < 48) + pix->width = 48; + if (pix->width > 2048) + pix->width = 2048; + pix->width &= ~0x01; + /* - * Limit to pxa hardware capabilities. YUV422P planar format requires - * images size to be a multiple of 16 bytes. If not, zeros will be - * inserted between Y and U planes, and U and V planes, which violates - * the YUV422P standard. + * YUV422P planar format requires images size to be a 16 bytes + * multiple. If not, zeros will be inserted between Y and U planes, and + * U and V planes, and YUV422P standard would be violated. */ - v4l_bound_align_image(&pix->width, 48, 2048, 1, - &pix->height, 32, 2048, 0, - xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); + if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) { + if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN)) + pix->height = ALIGN(pix->height, YUV422P_X_Y_ALIGN); + if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN)) + pix->width = ALIGN(pix->width, YUV422P_X_Y_ALIGN); + } pix->bytesperline = pix->width * DIV_ROUND_UP(xlate->host_fmt->depth, 8); diff --git a/trunk/drivers/media/video/saa7134/saa7134-video.c b/trunk/drivers/media/video/saa7134/saa7134-video.c index ba87128542e0..e305c1674cee 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-video.c +++ b/trunk/drivers/media/video/saa7134/saa7134-video.c @@ -1640,8 +1640,15 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv, } f->fmt.pix.field = field; - v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, - &f->fmt.pix.height, 32, maxh, 0, 0); + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.height < 32) + f->fmt.pix.height = 32; + if (f->fmt.pix.width > maxw) + f->fmt.pix.width = maxw; + if (f->fmt.pix.height > maxh) + f->fmt.pix.height = maxh; + f->fmt.pix.width &= ~0x03; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = diff --git a/trunk/drivers/media/video/sh_mobile_ceu_camera.c b/trunk/drivers/media/video/sh_mobile_ceu_camera.c index 0db88a53d92c..d369e8409ab8 100644 --- a/trunk/drivers/media/video/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/video/sh_mobile_ceu_camera.c @@ -689,8 +689,16 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, /* FIXME: calculate using depth and bus width */ - v4l_bound_align_image(&f->fmt.pix.width, 2, 2560, 1, - &f->fmt.pix.height, 4, 1920, 2, 0); + if (f->fmt.pix.height < 4) + f->fmt.pix.height = 4; + if (f->fmt.pix.height > 1920) + f->fmt.pix.height = 1920; + if (f->fmt.pix.width < 2) + f->fmt.pix.width = 2; + if (f->fmt.pix.width > 2560) + f->fmt.pix.width = 2560; + f->fmt.pix.width &= ~0x01; + f->fmt.pix.height &= ~0x03; f->fmt.pix.bytesperline = f->fmt.pix.width * DIV_ROUND_UP(xlate->host_fmt->depth, 8); diff --git a/trunk/drivers/media/video/tcm825x.c b/trunk/drivers/media/video/tcm825x.c index b90e9da3167d..b30c49248217 100644 --- a/trunk/drivers/media/video/tcm825x.c +++ b/trunk/drivers/media/video/tcm825x.c @@ -878,7 +878,7 @@ static int tcm825x_probe(struct i2c_client *client, return rval; } -static int tcm825x_remove(struct i2c_client *client) +static int __exit tcm825x_remove(struct i2c_client *client) { struct tcm825x_sensor *sensor = i2c_get_clientdata(client); @@ -902,7 +902,7 @@ static struct i2c_driver tcm825x_i2c_driver = { .name = TCM825X_NAME, }, .probe = tcm825x_probe, - .remove = tcm825x_remove, + .remove = __exit_p(tcm825x_remove), .id_table = tcm825x_id, }; diff --git a/trunk/drivers/media/video/usbvideo/Kconfig b/trunk/drivers/media/video/usbvideo/Kconfig index adb1c044ad7d..e4cb99c1f94b 100644 --- a/trunk/drivers/media/video/usbvideo/Kconfig +++ b/trunk/drivers/media/video/usbvideo/Kconfig @@ -38,13 +38,10 @@ config USB_KONICAWC module will be called konicawc. config USB_QUICKCAM_MESSENGER - tristate "USB Logitech Quickcam Messenger (DEPRECATED)" + tristate "USB Logitech Quickcam Messenger" depends on VIDEO_V4L1 select VIDEO_USBVIDEO ---help--- - This driver is DEPRECATED please use the gspca stv06xx module - instead. - Say Y or M here to enable support for the USB Logitech Quickcam Messenger webcam. diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c index b91d66a767d7..f96475626da7 100644 --- a/trunk/drivers/media/video/v4l2-common.c +++ b/trunk/drivers/media/video/v4l2-common.c @@ -802,17 +802,6 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev, /* Decrease the module use count to match the first try_module_get. */ module_put(client->driver->driver.owner); - if (sd) { - /* We return errors from v4l2_subdev_call only if we have the - callback as the .s_config is not mandatory */ - int err = v4l2_subdev_call(sd, core, s_config, 0, NULL); - - if (err && err != -ENOIOCTLCMD) { - v4l2_device_unregister_subdev(sd); - sd = NULL; - } - } - error: /* If we have a client but no subdev, then something went wrong and we must unregister the client. */ @@ -863,17 +852,6 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev, /* Decrease the module use count to match the first try_module_get. */ module_put(client->driver->driver.owner); - if (sd) { - /* We return errors from v4l2_subdev_call only if we have the - callback as the .s_config is not mandatory */ - int err = v4l2_subdev_call(sd, core, s_config, 0, NULL); - - if (err && err != -ENOIOCTLCMD) { - v4l2_device_unregister_subdev(sd); - sd = NULL; - } - } - error: /* If we have a client but no subdev, then something went wrong and we must unregister the client. */ @@ -894,89 +872,6 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev } EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev_addr); -/* Load an i2c sub-device. */ -struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, - struct i2c_adapter *adapter, const char *module_name, - struct i2c_board_info *info, const unsigned short *probe_addrs) -{ - struct v4l2_subdev *sd = NULL; - struct i2c_client *client; - - BUG_ON(!v4l2_dev); - - if (module_name) - request_module(module_name); - - /* Create the i2c client */ - if (info->addr == 0 && probe_addrs) - client = i2c_new_probed_device(adapter, info, probe_addrs); - else - client = i2c_new_device(adapter, info); - - /* Note: by loading the module first we are certain that c->driver - will be set if the driver was found. If the module was not loaded - first, then the i2c core tries to delay-load the module for us, - and then c->driver is still NULL until the module is finally - loaded. This delay-load mechanism doesn't work if other drivers - want to use the i2c device, so explicitly loading the module - is the best alternative. */ - if (client == NULL || client->driver == NULL) - goto error; - - /* Lock the module so we can safely get the v4l2_subdev pointer */ - if (!try_module_get(client->driver->driver.owner)) - goto error; - sd = i2c_get_clientdata(client); - - /* Register with the v4l2_device which increases the module's - use count as well. */ - if (v4l2_device_register_subdev(v4l2_dev, sd)) - sd = NULL; - /* Decrease the module use count to match the first try_module_get. */ - module_put(client->driver->driver.owner); - - if (sd) { - /* We return errors from v4l2_subdev_call only if we have the - callback as the .s_config is not mandatory */ - int err = v4l2_subdev_call(sd, core, s_config, - info->irq, info->platform_data); - - if (err && err != -ENOIOCTLCMD) { - v4l2_device_unregister_subdev(sd); - sd = NULL; - } - } - -error: - /* If we have a client but no subdev, then something went wrong and - we must unregister the client. */ - if (client && sd == NULL) - i2c_unregister_device(client); - return sd; -} -EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board); - -struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, - struct i2c_adapter *adapter, - const char *module_name, const char *client_type, - int irq, void *platform_data, - u8 addr, const unsigned short *probe_addrs) -{ - struct i2c_board_info info; - - /* Setup the i2c board info with the device type and - the device address. */ - memset(&info, 0, sizeof(info)); - strlcpy(info.type, client_type, sizeof(info.type)); - info.addr = addr; - info.irq = irq; - info.platform_data = platform_data; - - return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, module_name, - &info, probe_addrs); -} -EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg); - /* Return i2c client address of v4l2_subdev. */ unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd) { @@ -1021,78 +916,4 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type) } EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs); -#endif /* defined(CONFIG_I2C) */ - -/* Clamp x to be between min and max, aligned to a multiple of 2^align. min - * and max don't have to be aligned, but there must be at least one valid - * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples - * of 16 between 17 and 31. */ -static unsigned int clamp_align(unsigned int x, unsigned int min, - unsigned int max, unsigned int align) -{ - /* Bits that must be zero to be aligned */ - unsigned int mask = ~((1 << align) - 1); - - /* Round to nearest aligned value */ - if (align) - x = (x + (1 << (align - 1))) & mask; - - /* Clamp to aligned value of min and max */ - if (x < min) - x = (min + ~mask) & mask; - else if (x > max) - x = max & mask; - - return x; -} - -/* Bound an image to have a width between wmin and wmax, and height between - * hmin and hmax, inclusive. Additionally, the width will be a multiple of - * 2^walign, the height will be a multiple of 2^halign, and the overall size - * (width*height) will be a multiple of 2^salign. The image may be shrunk - * or enlarged to fit the alignment constraints. - * - * The width or height maximum must not be smaller than the corresponding - * minimum. The alignments must not be so high there are no possible image - * sizes within the allowed bounds. wmin and hmin must be at least 1 - * (don't use 0). If you don't care about a certain alignment, specify 0, - * as 2^0 is 1 and one byte alignment is equivalent to no alignment. If - * you only want to adjust downward, specify a maximum that's the same as - * the initial value. - */ -void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, - unsigned int walign, - u32 *h, unsigned int hmin, unsigned int hmax, - unsigned int halign, unsigned int salign) -{ - *w = clamp_align(*w, wmin, wmax, walign); - *h = clamp_align(*h, hmin, hmax, halign); - - /* Usually we don't need to align the size and are done now. */ - if (!salign) - return; - - /* How much alignment do we have? */ - walign = __ffs(*w); - halign = __ffs(*h); - /* Enough to satisfy the image alignment? */ - if (walign + halign < salign) { - /* Max walign where there is still a valid width */ - unsigned int wmaxa = __fls(wmax ^ (wmin - 1)); - /* Max halign where there is still a valid height */ - unsigned int hmaxa = __fls(hmax ^ (hmin - 1)); - - /* up the smaller alignment until we have enough */ - do { - if (halign >= hmaxa || - (walign <= halign && walign < wmaxa)) { - *w = clamp_align(*w, wmin, wmax, walign + 1); - walign = __ffs(*w); - } else { - *h = clamp_align(*h, hmin, hmax, halign + 1); - halign = __ffs(*h); - } - } while (halign + walign < salign); - } -} -EXPORT_SYMBOL_GPL(v4l_bound_align_image); +#endif diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index cd7266858462..fbfefae7886f 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -883,8 +883,15 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, maxh = norm_maxh(); f->fmt.pix.field = field; - v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, - &f->fmt.pix.height, 32, maxh, 0, 0); + if (f->fmt.pix.height < 32) + f->fmt.pix.height = 32; + if (f->fmt.pix.height > maxh) + f->fmt.pix.height = maxh; + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.width > maxw) + f->fmt.pix.width = maxw; + f->fmt.pix.width &= ~0x03; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = diff --git a/trunk/drivers/media/video/w9968cf.c b/trunk/drivers/media/video/w9968cf.c index 6c3f23e31b5c..f59b2bd07e89 100644 --- a/trunk/drivers/media/video/w9968cf.c +++ b/trunk/drivers/media/video/w9968cf.c @@ -460,7 +460,7 @@ static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture); static int w9968cf_set_window(struct w9968cf_device*, struct video_window); static int w9968cf_postprocess_frame(struct w9968cf_device*, struct w9968cf_frame_t*); -static int w9968cf_adjust_window_size(struct w9968cf_device*, u32 *w, u32 *h); +static int w9968cf_adjust_window_size(struct w9968cf_device*, u16* w, u16* h); static void w9968cf_init_framelist(struct w9968cf_device*); static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num); static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**); @@ -1763,7 +1763,8 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) #define UNSC(x) ((x) >> 10) /* Make sure we are using a supported resolution */ - if ((err = w9968cf_adjust_window_size(cam, &win.width, &win.height))) + if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, + (u16*)&win.height))) goto error; /* Scaling factors */ @@ -1913,9 +1914,12 @@ w9968cf_set_window(struct w9968cf_device* cam, struct video_window win) Return 0 on success, -1 otherwise. --------------------------------------------------------------------------*/ static int -w9968cf_adjust_window_size(struct w9968cf_device *cam, u32 *width, u32 *height) +w9968cf_adjust_window_size(struct w9968cf_device* cam, u16* width, u16* height) { - unsigned int maxw, maxh, align; + u16 maxw, maxh; + + if ((*width < cam->minwidth) || (*height < cam->minheight)) + return -ERANGE; maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth) @@ -1923,10 +1927,16 @@ w9968cf_adjust_window_size(struct w9968cf_device *cam, u32 *width, u32 *height) maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) && w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight) : cam->maxheight; - align = (cam->vpp_flag & VPP_DECOMPRESSION) ? 4 : 0; - v4l_bound_align_image(width, cam->minwidth, maxw, align, - height, cam->minheight, maxh, align, 0); + if (*width > maxw) + *width = maxw; + if (*height > maxh) + *height = maxh; + + if (cam->vpp_flag & VPP_DECOMPRESSION) { + *width &= ~15L; /* multiple of 16 */ + *height &= ~15L; + } PDBGG("Window size adjusted w=%u, h=%u ", *width, *height) @@ -3033,8 +3043,8 @@ static long w9968cf_v4l_ioctl(struct file *filp, if (win.clipcount != 0 || win.flags != 0) return -EINVAL; - if ((err = w9968cf_adjust_window_size(cam, &win.width, - &win.height))) { + if ((err = w9968cf_adjust_window_size(cam, (u16*)&win.width, + (u16*)&win.height))) { DBG(4, "Resolution not supported (%ux%u). " "VIDIOCSWIN failed", win.width, win.height) return err; @@ -3106,7 +3116,6 @@ static long w9968cf_v4l_ioctl(struct file *filp, { struct video_mmap mmap; struct w9968cf_frame_t* fr; - u32 w, h; int err = 0; if (copy_from_user(&mmap, arg, sizeof(mmap))) @@ -3155,10 +3164,8 @@ static long w9968cf_v4l_ioctl(struct file *filp, } } - w = mmap.width; h = mmap.height; - err = w9968cf_adjust_window_size(cam, &w, &h); - mmap.width = w; mmap.height = h; - if (err) { + if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width, + (u16*)&mmap.height))) { DBG(4, "Resolution not supported (%dx%d). " "VIDIOCMCAPTURE failed", mmap.width, mmap.height) diff --git a/trunk/drivers/media/video/zoran/zoran_driver.c b/trunk/drivers/media/video/zoran/zoran_driver.c index 3d7df32a3d87..643cccaa1aab 100644 --- a/trunk/drivers/media/video/zoran/zoran_driver.c +++ b/trunk/drivers/media/video/zoran/zoran_driver.c @@ -2088,10 +2088,16 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, return -EINVAL; } - bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8); - v4l_bound_align_image( - &fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2, - &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0); + bpp = (zoran_formats[i].depth + 7) / 8; + fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3); + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) + fmt->fmt.pix.width = BUZ_MIN_WIDTH; + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) + fmt->fmt.pix.height = BUZ_MIN_HEIGHT; mutex_unlock(&zr->resource_lock); return 0; diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c index 55ff25244af4..20e0b447e8e8 100644 --- a/trunk/drivers/message/fusion/mptsas.c +++ b/trunk/drivers/message/fusion/mptsas.c @@ -3518,7 +3518,7 @@ mptsas_not_responding_devices(MPT_ADAPTER *ioc) } else mptsas_volume_delete(ioc, sas_info->fw.id); } - mutex_unlock(&ioc->sas_device_info_mutex); + mutex_lock(&ioc->sas_device_info_mutex); /* expanders */ mutex_lock(&ioc->sas_topology_mutex); @@ -3549,7 +3549,7 @@ mptsas_not_responding_devices(MPT_ADAPTER *ioc) goto redo_expander_scan; } } - mutex_unlock(&ioc->sas_topology_mutex); + mutex_lock(&ioc->sas_topology_mutex); } /** diff --git a/trunk/drivers/mfd/ezx-pcap.c b/trunk/drivers/mfd/ezx-pcap.c index c1de4afa89a6..671a7efe86a8 100644 --- a/trunk/drivers/mfd/ezx-pcap.c +++ b/trunk/drivers/mfd/ezx-pcap.c @@ -238,10 +238,8 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap) mutex_lock(&pcap->adc_mutex); req = pcap->adc_queue[pcap->adc_head]; - if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) { - mutex_unlock(&pcap->adc_mutex); + if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) return IRQ_HANDLED; - } /* read requested channels results */ ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp); diff --git a/trunk/drivers/mfd/sm501.c b/trunk/drivers/mfd/sm501.c index 0cc5eeff5ee8..4c7b7962f6b8 100644 --- a/trunk/drivers/mfd/sm501.c +++ b/trunk/drivers/mfd/sm501.c @@ -367,8 +367,7 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to) break; default: - gate = -1; - goto already; + return -1; } writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); diff --git a/trunk/drivers/mfd/twl4030-core.c b/trunk/drivers/mfd/twl4030-core.c index ca54996ffd0e..cd1008c19cd7 100644 --- a/trunk/drivers/mfd/twl4030-core.c +++ b/trunk/drivers/mfd/twl4030-core.c @@ -101,12 +101,6 @@ #define twl_has_usb() false #endif -#if defined(CONFIG_TWL4030_WATCHDOG) || \ - defined(CONFIG_TWL4030_WATCHDOG_MODULE) -#define twl_has_watchdog() true -#else -#define twl_has_watchdog() false -#endif /* Triton Core internal information (BEGIN) */ @@ -532,12 +526,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) usb_transceiver = child; } - if (twl_has_watchdog()) { - child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); - if (IS_ERR(child)) - return PTR_ERR(child); - } - if (twl_has_regulator()) { /* child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1); diff --git a/trunk/drivers/mmc/host/mmc_spi.c b/trunk/drivers/mmc/host/mmc_spi.c index a461017ce5ce..240608cc7ae9 100644 --- a/trunk/drivers/mmc/host/mmc_spi.c +++ b/trunk/drivers/mmc/host/mmc_spi.c @@ -1313,12 +1313,6 @@ static int mmc_spi_probe(struct spi_device *spi) struct mmc_spi_host *host; int status; - /* We rely on full duplex transfers, mostly to reduce - * per-transfer overheads (by making fewer transfers). - */ - if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) - return -EINVAL; - /* MMC and SD specs only seem to care that sampling is on the * rising edge ... meaning SPI modes 0 or 3. So either SPI mode * should be legit. We'll use mode 0 since the steady state is 0, diff --git a/trunk/drivers/mtd/cmdlinepart.c b/trunk/drivers/mtd/cmdlinepart.c index 1479da6d3aa6..5011fa73f918 100644 --- a/trunk/drivers/mtd/cmdlinepart.c +++ b/trunk/drivers/mtd/cmdlinepart.c @@ -194,7 +194,7 @@ static struct mtd_partition * newpart(char *s, parts[this_part].name = extra_mem; extra_mem += name_len + 1; - dbg(("partition %d: name <%s>, offset %llx, size %llx, mask flags %x\n", + dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n", this_part, parts[this_part].name, parts[this_part].offset, diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index ae5fe91867e1..59c46126a5ce 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -54,7 +54,7 @@ #define SR_SRWD 0x80 /* SR write protect */ /* Define max times to check status register before we give up. */ -#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ +#define MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */ #define CMD_SIZE 4 #ifdef CONFIG_M25PXX_USE_FAST_READ diff --git a/trunk/drivers/mtd/inftlcore.c b/trunk/drivers/mtd/inftlcore.c index d8cf29c01cc4..73f05227dc8c 100644 --- a/trunk/drivers/mtd/inftlcore.c +++ b/trunk/drivers/mtd/inftlcore.c @@ -226,7 +226,7 @@ static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate) if (!desperate && inftl->numfreeEUNs < 2) { DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free " "EUNs (%d)\n", inftl->numfreeEUNs); - return BLOCK_NIL; + return 0xffff; } /* Scan for a free block */ @@ -281,8 +281,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned silly = MAX_LOOPS; while (thisEUN < inftl->nb_blocks) { for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) { - if ((BlockMap[block] != BLOCK_NIL) || - BlockDeleted[block]) + if ((BlockMap[block] != 0xffff) || BlockDeleted[block]) continue; if (inftl_read_oob(mtd, (thisEUN * inftl->EraseSize) @@ -526,7 +525,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) if (!silly--) { printk(KERN_WARNING "INFTL: infinite loop in " "Virtual Unit Chain 0x%x\n", thisVUC); - return BLOCK_NIL; + return 0xffff; } /* Skip to next block in chain */ @@ -550,7 +549,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) * waiting to be picked up. We're going to have to fold * a chain to make room. */ - thisEUN = INFTL_makefreeblock(inftl, BLOCK_NIL); + thisEUN = INFTL_makefreeblock(inftl, 0xffff); /* * Hopefully we free something, lets try again. @@ -632,7 +631,7 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) printk(KERN_WARNING "INFTL: error folding to make room for Virtual " "Unit Chain 0x%x\n", thisVUC); - return BLOCK_NIL; + return 0xffff; } /* diff --git a/trunk/drivers/mtd/maps/integrator-flash.c b/trunk/drivers/mtd/maps/integrator-flash.c index 2aac41bde8b3..b08a798ee254 100644 --- a/trunk/drivers/mtd/maps/integrator-flash.c +++ b/trunk/drivers/mtd/maps/integrator-flash.c @@ -42,8 +42,10 @@ #include #include +#define SUBDEV_NAME_SIZE (BUS_ID_SIZE + 2) + struct armflash_subdev_info { - char *name; + char name[SUBDEV_NAME_SIZE]; struct mtd_info *mtd; struct map_info map; struct flash_platform_data *plat; @@ -132,8 +134,6 @@ static void armflash_subdev_remove(struct armflash_subdev_info *subdev) map_destroy(subdev->mtd); if (subdev->map.virt) iounmap(subdev->map.virt); - kfree(subdev->name); - subdev->name = NULL; release_mem_region(subdev->map.phys, subdev->map.size); } @@ -177,22 +177,16 @@ static int armflash_probe(struct platform_device *dev) if (nr == 1) /* No MTD concatenation, just use the default name */ - subdev->name = kstrdup(dev_name(&dev->dev), GFP_KERNEL); + snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s", + dev_name(&dev->dev)); else - subdev->name = kasprintf(GFP_KERNEL, "%s-%d", - dev_name(&dev->dev), i); - if (!subdev->name) { - err = -ENOMEM; - break; - } + snprintf(subdev->name, SUBDEV_NAME_SIZE, "%s-%d", + dev_name(&dev->dev), i); subdev->plat = plat; err = armflash_subdev_probe(subdev, res); - if (err) { - kfree(subdev->name); - subdev->name = NULL; + if (err) break; - } } info->nr_subdev = i; diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/atmel_nand.c index 20c828ba9405..2802992b39da 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/atmel_nand.c @@ -534,7 +534,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) &num_partitions); if ((!partitions) || (num_partitions == 0)) { - printk(KERN_ERR "atmel_nand: No partitions defined, or unsupported device.\n"); + printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n"); res = ENXIO; goto err_no_partitions; } diff --git a/trunk/drivers/mtd/nand/omap2.c b/trunk/drivers/mtd/nand/omap2.c index ebd07e95b814..0cd76f89f4b0 100644 --- a/trunk/drivers/mtd/nand/omap2.c +++ b/trunk/drivers/mtd/nand/omap2.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include #include @@ -543,7 +541,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); unsigned long timeo = jiffies; - int status = NAND_STATUS_FAIL, state = this->state; + int status, state = this->state; if (state == FL_ERASING) timeo += (HZ * 400) / 1000; @@ -558,9 +556,8 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) while (time_before(jiffies, timeo)) { status = __raw_readb(this->IO_ADDR_R); - if (status & NAND_STATUS_READY) + if (!(status & 0x40)) break; - cond_resched(); } return status; } diff --git a/trunk/drivers/mtd/nftlcore.c b/trunk/drivers/mtd/nftlcore.c index fb86cacd5bdb..e3f8495a94c2 100644 --- a/trunk/drivers/mtd/nftlcore.c +++ b/trunk/drivers/mtd/nftlcore.c @@ -208,7 +208,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate ) /* Normally, we force a fold to happen before we run out of free blocks completely */ if (!desperate && nftl->numfreeEUNs < 2) { DEBUG(MTD_DEBUG_LEVEL1, "NFTL_findfreeblock: there are too few free EUNs\n"); - return BLOCK_NIL; + return 0xffff; } /* Scan for a free block */ @@ -230,11 +230,11 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate ) printk("Argh! No free blocks found! LastFreeEUN = %d, " "FirstEUN = %d\n", nftl->LastFreeEUN, le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); - return BLOCK_NIL; + return 0xffff; } } while (pot != nftl->LastFreeEUN); - return BLOCK_NIL; + return 0xffff; } static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned pendingblock ) @@ -431,7 +431,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p /* add the header so that it is now a valid chain */ oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC); - oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = BLOCK_NIL; + oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; nftl_write_oob(mtd, (nftl->EraseSize * targetEUN) + 8, 8, &retlen, (char *)&oob.u); @@ -515,7 +515,7 @@ static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock) if (ChainLength < 2) { printk(KERN_WARNING "No Virtual Unit Chains available for folding. " "Failing request\n"); - return BLOCK_NIL; + return 0xffff; } return NFTL_foldchain (nftl, LongestChain, pendingblock); @@ -578,7 +578,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n", thisVUC); - return BLOCK_NIL; + return 0xffff; } /* Skip to next block in chain */ @@ -601,7 +601,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) //u16 startEUN = nftl->EUNtable[thisVUC]; //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC); - writeEUN = NFTL_makefreeblock(nftl, BLOCK_NIL); + writeEUN = NFTL_makefreeblock(nftl, 0xffff); if (writeEUN == BLOCK_NIL) { /* OK, we accept that the above comment is @@ -673,7 +673,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) printk(KERN_WARNING "Error folding to make room for Virtual Unit Chain 0x%x\n", thisVUC); - return BLOCK_NIL; + return 0xffff; } static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index c155bd3ec9f1..1dc721517e4c 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1725,7 +1725,6 @@ config TLAN config KS8842 tristate "Micrel KSZ8842" - depends on HAS_IOMEM help This platform driver is for Micrel KSZ8842 chip. diff --git a/trunk/drivers/net/atl1c/atl1c_ethtool.c b/trunk/drivers/net/atl1c/atl1c_ethtool.c index 607007d75b6f..e4afbd628c23 100644 --- a/trunk/drivers/net/atl1c/atl1c_ethtool.c +++ b/trunk/drivers/net/atl1c/atl1c_ethtool.c @@ -281,8 +281,6 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & WAKE_PHY) adapter->wol |= AT_WUFC_LNKC; - device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); - return 0; } diff --git a/trunk/drivers/net/atl1e/atl1e_ethtool.c b/trunk/drivers/net/atl1e/atl1e_ethtool.c index 4003955d7a96..619c6583e1aa 100644 --- a/trunk/drivers/net/atl1e/atl1e_ethtool.c +++ b/trunk/drivers/net/atl1e/atl1e_ethtool.c @@ -365,8 +365,6 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & WAKE_PHY) adapter->wol |= AT_WUFC_LNKC; - device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); - return 0; } diff --git a/trunk/drivers/net/benet/be.h b/trunk/drivers/net/benet/be.h index 5b4bf3d2cdc2..f703758f0a6e 100644 --- a/trunk/drivers/net/benet/be.h +++ b/trunk/drivers/net/benet/be.h @@ -73,7 +73,7 @@ static inline char *nic_name(struct pci_dev *pdev) #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) #define BE_MAX_LRO_DESCRIPTORS 16 -#define BE_MAX_FRAGS_PER_FRAME (min((u32) 16, (u32) MAX_SKB_FRAGS)) +#define BE_MAX_FRAGS_PER_FRAME 16 struct be_dma_mem { void *va; diff --git a/trunk/drivers/net/benet/be_ethtool.c b/trunk/drivers/net/benet/be_ethtool.c index cccc5419ad72..9592f22e4c8c 100644 --- a/trunk/drivers/net/benet/be_ethtool.c +++ b/trunk/drivers/net/benet/be_ethtool.c @@ -162,8 +162,8 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) return -EINVAL; adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; - if (adapter->max_rx_coal > BE_MAX_FRAGS_PER_FRAME) - adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME; + if (adapter->max_rx_coal > MAX_SKB_FRAGS) + adapter->max_rx_coal = MAX_SKB_FRAGS - 1; /* if AIC is being turned on now, start with an EQD of 0 */ if (rx_eq->enable_aic == 0 && diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index 308eb09ca56b..66c10c87f517 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -666,7 +666,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, { struct be_queue_info *rxq = &adapter->rx_obj.q; struct be_rx_page_info *page_info; - u16 rxq_idx, i, num_rcvd, j; + u16 rxq_idx, i, num_rcvd; u32 pktsize, hdr_len, curr_frag_len; u8 *start; @@ -709,33 +709,22 @@ static void skb_fill_rx_data(struct be_adapter *adapter, /* More frags present for this completion */ pktsize -= curr_frag_len; /* account for above copied frag */ - for (i = 1, j = 0; i < num_rcvd; i++) { + for (i = 1; i < num_rcvd; i++) { index_inc(&rxq_idx, rxq->len); page_info = get_rx_page_info(adapter, rxq_idx); curr_frag_len = min(pktsize, rx_frag_size); - /* Coalesce all frags from the same physical page in one slot */ - if (page_info->page_offset == 0) { - /* Fresh page */ - j++; - skb_shinfo(skb)->frags[j].page = page_info->page; - skb_shinfo(skb)->frags[j].page_offset = - page_info->page_offset; - skb_shinfo(skb)->frags[j].size = 0; - skb_shinfo(skb)->nr_frags++; - } else { - put_page(page_info->page); - } - - skb_shinfo(skb)->frags[j].size += curr_frag_len; + skb_shinfo(skb)->frags[i].page = page_info->page; + skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset; + skb_shinfo(skb)->frags[i].size = curr_frag_len; skb->len += curr_frag_len; skb->data_len += curr_frag_len; + skb_shinfo(skb)->nr_frags++; pktsize -= curr_frag_len; memset(page_info, 0, sizeof(*page_info)); } - BUG_ON(j > MAX_SKB_FRAGS); done: be_rx_stats_update(adapter, pktsize, num_rcvd); @@ -797,7 +786,7 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter, struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; struct be_queue_info *rxq = &adapter->rx_obj.q; u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; - u16 i, rxq_idx = 0, vid, j; + u16 i, rxq_idx = 0, vid; num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); @@ -805,28 +794,20 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter, rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); remaining = pkt_size; - for (i = 0, j = -1; i < num_rcvd; i++) { + for (i = 0; i < num_rcvd; i++) { page_info = get_rx_page_info(adapter, rxq_idx); curr_frag_len = min(remaining, rx_frag_size); - /* Coalesce all frags from the same physical page in one slot */ - if (i == 0 || page_info->page_offset == 0) { - /* First frag or Fresh page */ - j++; - rx_frags[j].page = page_info->page; - rx_frags[j].page_offset = page_info->page_offset; - rx_frags[j].size = 0; - } else { - put_page(page_info->page); - } - rx_frags[j].size += curr_frag_len; - + rx_frags[i].page = page_info->page; + rx_frags[i].page_offset = page_info->page_offset; + rx_frags[i].size = curr_frag_len; remaining -= curr_frag_len; + index_inc(&rxq_idx, rxq->len); + memset(page_info, 0, sizeof(*page_info)); } - BUG_ON(j > MAX_SKB_FRAGS); if (likely(!vlanf)) { lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index b70cc99962fc..38f1c3375d7f 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -6825,14 +6825,6 @@ bnx2_nway_reset(struct net_device *dev) return 0; } -static u32 -bnx2_get_link(struct net_device *dev) -{ - struct bnx2 *bp = netdev_priv(dev); - - return bp->link_up; -} - static int bnx2_get_eeprom_len(struct net_device *dev) { @@ -7400,7 +7392,7 @@ static const struct ethtool_ops bnx2_ethtool_ops = { .get_wol = bnx2_get_wol, .set_wol = bnx2_set_wol, .nway_reset = bnx2_nway_reset, - .get_link = bnx2_get_link, + .get_link = ethtool_op_get_link, .get_eeprom_len = bnx2_get_eeprom_len, .get_eeprom = bnx2_get_eeprom, .set_eeprom = bnx2_set_eeprom, diff --git a/trunk/drivers/net/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c index 951714a7f90a..fbf1352e9c1c 100644 --- a/trunk/drivers/net/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -8637,14 +8637,6 @@ static int bnx2x_nway_reset(struct net_device *dev) return 0; } -static u32 -bnx2x_get_link(struct net_device *dev) -{ - struct bnx2x *bp = netdev_priv(dev); - - return bp->link_vars.link_up; -} - static int bnx2x_get_eeprom_len(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); @@ -10042,7 +10034,7 @@ static struct ethtool_ops bnx2x_ethtool_ops = { .get_msglevel = bnx2x_get_msglevel, .set_msglevel = bnx2x_set_msglevel, .nway_reset = bnx2x_nway_reset, - .get_link = bnx2x_get_link, + .get_link = ethtool_op_get_link, .get_eeprom_len = bnx2x_get_eeprom_len, .get_eeprom = bnx2x_get_eeprom, .set_eeprom = bnx2x_set_eeprom, diff --git a/trunk/drivers/net/can/Kconfig b/trunk/drivers/net/can/Kconfig index 33821a81cbf8..d5e18812bf49 100644 --- a/trunk/drivers/net/can/Kconfig +++ b/trunk/drivers/net/can/Kconfig @@ -36,7 +36,7 @@ config CAN_CALC_BITTIMING If unsure, say Y. config CAN_SJA1000 - depends on CAN_DEV && HAS_IOMEM + depends on CAN_DEV tristate "Philips SJA1000" ---help--- Driver for the SJA1000 CAN controllers from Philips or NXP diff --git a/trunk/drivers/net/cnic.c b/trunk/drivers/net/cnic.c index 4d1515f45ba2..44f77eb1180f 100644 --- a/trunk/drivers/net/cnic.c +++ b/trunk/drivers/net/cnic.c @@ -25,6 +25,8 @@ #include #include #include +#include + #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define BCM_VLAN 1 #endif @@ -2519,9 +2521,9 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev) struct cnic_dev *cdev; struct cnic_local *cp; struct cnic_eth_dev *ethdev = NULL; - struct cnic_eth_dev *(*probe)(struct net_device *) = NULL; + struct cnic_eth_dev *(*probe)(void *) = NULL; - probe = symbol_get(bnx2_cnic_probe); + probe = __symbol_get("bnx2_cnic_probe"); if (probe) { ethdev = (*probe)(dev); symbol_put_addr(probe); diff --git a/trunk/drivers/net/cnic_if.h b/trunk/drivers/net/cnic_if.h index d1bce27ee99e..06380963a34e 100644 --- a/trunk/drivers/net/cnic_if.h +++ b/trunk/drivers/net/cnic_if.h @@ -296,6 +296,4 @@ extern int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops); extern int cnic_unregister_driver(int ulp_type); -extern struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev); - #endif diff --git a/trunk/drivers/net/cpmac.c b/trunk/drivers/net/cpmac.c index fd5e32cbcb87..58afafbd3b9c 100644 --- a/trunk/drivers/net/cpmac.c +++ b/trunk/drivers/net/cpmac.c @@ -1097,7 +1097,7 @@ static const struct net_device_ops cpmac_netdev_ops = { .ndo_start_xmit = cpmac_start_xmit, .ndo_tx_timeout = cpmac_tx_timeout, .ndo_set_multicast_list = cpmac_set_multicast_list, - .ndo_do_ioctl = cpmac_ioctl, + .ndo_so_ioctl = cpmac_ioctl, .ndo_set_config = cpmac_config, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 5b8cbdb4b520..5e3356f8eb5a 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -2185,16 +2185,12 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, /* Free all the Rx ring sk_buffs */ for (i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; - if (buffer_info->dma) { + if (buffer_info->skb) { pci_unmap_single(pdev, buffer_info->dma, buffer_info->length, PCI_DMA_FROMDEVICE); - } - - buffer_info->dma = 0; - if (buffer_info->skb) { dev_kfree_skb(buffer_info->skb); buffer_info->skb = NULL; } @@ -4037,7 +4033,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, buffer_info->dma, buffer_info->length, PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; length = le16_to_cpu(rx_desc->length); /* !EOP means multiple descriptors were used to store a single @@ -4227,7 +4222,6 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, pci_unmap_single(pdev, buffer_info->dma, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; break; /* while !buffer_info->skb */ } @@ -4823,9 +4817,6 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, netif_device_detach(netdev); - if (state == pci_channel_io_perm_failure) - return PCI_ERS_RESULT_DISCONNECT; - if (netif_running(netdev)) e1000_down(adapter); pci_disable_device(pdev); diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 63415bb6f48f..679885a122b4 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -4785,9 +4785,6 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, netif_device_detach(netdev); - if (state == pci_channel_io_perm_failure) - return PCI_ERS_RESULT_DISCONNECT; - if (netif_running(netdev)) e1000e_down(adapter); pci_disable_device(pdev); diff --git a/trunk/drivers/net/fsl_pq_mdio.c b/trunk/drivers/net/fsl_pq_mdio.c index d167090248e2..3af581303ca2 100644 --- a/trunk/drivers/net/fsl_pq_mdio.c +++ b/trunk/drivers/net/fsl_pq_mdio.c @@ -188,7 +188,7 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) } -#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) +#ifdef CONFIG_GIANFAR static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) { struct gfar __iomem *enet_regs; @@ -206,7 +206,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) #endif -#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) +#ifdef CONFIG_UCC_GETH static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) { struct device_node *np = NULL; @@ -291,7 +291,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, if (of_device_is_compatible(np, "fsl,gianfar-mdio") || of_device_is_compatible(np, "fsl,gianfar-tbi") || of_device_is_compatible(np, "gianfar")) { -#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) +#ifdef CONFIG_GIANFAR tbipa = get_gfar_tbipa(regs); #else err = -ENODEV; @@ -299,7 +299,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, #endif } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || of_device_is_compatible(np, "ucc_geth_phy")) { -#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) +#ifdef CONFIG_UCC_GETH u32 id; static u32 mii_mng_master; diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index be480292aba1..ea17319624aa 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -4549,12 +4549,11 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, cleaned = true; cleaned_count++; - /* this is the fast path for the non-packet split case */ if (!adapter->rx_ps_hdr_size) { pci_unmap_single(pdev, buffer_info->dma, - adapter->rx_buffer_len, + adapter->rx_buffer_len + + NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; skb_put(skb, length); goto send_up; } @@ -4571,9 +4570,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring, if (!skb_shinfo(skb)->nr_frags) { pci_unmap_single(pdev, buffer_info->dma, - adapter->rx_ps_hdr_size, + adapter->rx_ps_hdr_size + NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; skb_put(skb, hlen); } @@ -4715,6 +4713,7 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, bufsz = adapter->rx_ps_hdr_size; else bufsz = adapter->rx_buffer_len; + bufsz += NET_IP_ALIGN; while (cleaned_count--) { rx_desc = E1000_RX_DESC_ADV(*rx_ring, i); @@ -4738,7 +4737,7 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, } if (!buffer_info->skb) { - skb = netdev_alloc_skb(netdev, bufsz + NET_IP_ALIGN); + skb = netdev_alloc_skb(netdev, bufsz); if (!skb) { adapter->alloc_rx_buff_failed++; goto no_buffers; @@ -5339,9 +5338,6 @@ static pci_ers_result_t igb_io_error_detected(struct pci_dev *pdev, netif_device_detach(netdev); - if (state == pci_channel_io_perm_failure) - return PCI_ERS_RESULT_DISCONNECT; - if (netif_running(netdev)) igb_down(adapter); pci_disable_device(pdev); diff --git a/trunk/drivers/net/irda/bfin_sir.c b/trunk/drivers/net/irda/bfin_sir.c index 911c082cee5a..f3eed6a8fba5 100644 --- a/trunk/drivers/net/irda/bfin_sir.c +++ b/trunk/drivers/net/irda/bfin_sir.c @@ -677,14 +677,6 @@ static int bfin_sir_init_iobuf(iobuff_t *io, int size) return 0; } -static const struct net_device_ops bfin_sir_ndo = { - .ndo_open = bfin_sir_open, - .ndo_stop = bfin_sir_stop, - .ndo_start_xmit = bfin_sir_hard_xmit, - .ndo_do_ioctl = bfin_sir_ioctl, - .ndo_get_stats = bfin_sir_stats, -}; - static int __devinit bfin_sir_probe(struct platform_device *pdev) { struct net_device *dev; @@ -726,8 +718,12 @@ static int __devinit bfin_sir_probe(struct platform_device *pdev) if (err) goto err_mem_3; - dev->netdev_ops = &bfin_sir_ndo; - dev->irq = sir_port->irq; + dev->hard_start_xmit = bfin_sir_hard_xmit; + dev->open = bfin_sir_open; + dev->stop = bfin_sir_stop; + dev->do_ioctl = bfin_sir_ioctl; + dev->get_stats = bfin_sir_stats; + dev->irq = sir_port->irq; irda_init_max_qos_capabilies(&self->qos); diff --git a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c index 0f7b6a3a2e68..86f4f3e36f27 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c @@ -139,7 +139,7 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->autoneg = AUTONEG_ENABLE; ecmd->transceiver = XCVR_EXTERNAL; if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->phy.multispeed_fiber)) { + (hw->mac.type == ixgbe_mac_82599EB)) { ecmd->supported |= (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg); @@ -217,7 +217,7 @@ static int ixgbe_set_settings(struct net_device *netdev, s32 err = 0; if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->phy.multispeed_fiber)) { + (hw->mac.type == ixgbe_mac_82599EB)) { /* 10000/copper and 1000/copper must autoneg * this function does not support any duplex forcing, but can * limit the advertising of the adapter to only 10000 or 1000 */ @@ -245,7 +245,6 @@ static int ixgbe_set_settings(struct net_device *netdev, } else { /* in this case we currently only support 10Gb/FULL */ if ((ecmd->autoneg == AUTONEG_ENABLE) || - (ecmd->advertising != ADVERTISED_10000baseT_Full) || (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) return -EINVAL; } diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 5588ef493a3d..e756e220db32 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -563,6 +563,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; unsigned int i; + unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN; i = rx_ring->next_to_use; bi = &rx_ring->rx_buffer_info[i]; @@ -592,9 +593,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, if (!bi->skb) { struct sk_buff *skb; - skb = netdev_alloc_skb(adapter->netdev, - (rx_ring->rx_buf_len + - NET_IP_ALIGN)); + skb = netdev_alloc_skb(adapter->netdev, bufsz); if (!skb) { adapter->alloc_rx_buff_failed++; @@ -609,8 +608,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, skb_reserve(skb, NET_IP_ALIGN); bi->skb = skb; - bi->dma = pci_map_single(pdev, skb->data, - rx_ring->rx_buf_len, + bi->dma = pci_map_single(pdev, skb->data, bufsz, PCI_DMA_FROMDEVICE); } /* Refresh the desc even if buffer_addrs didn't change because @@ -734,7 +732,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, pci_unmap_single(pdev, rx_buffer_info->dma, rx_ring->rx_buf_len, PCI_DMA_FROMDEVICE); - rx_buffer_info->dma = 0; skb_put(skb, len); } @@ -2704,10 +2701,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) */ err = hw->phy.ops.identify(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize because " - "an unsupported SFP+ module type was detected.\n" - "Reload the driver after installing a supported " - "module.\n"); + DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err); ixgbe_down(adapter); return err; } @@ -2818,11 +2812,9 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, } if (!rx_buffer_info->page) continue; - if (rx_buffer_info->page_dma) { - pci_unmap_page(pdev, rx_buffer_info->page_dma, - PAGE_SIZE / 2, PCI_DMA_FROMDEVICE); - rx_buffer_info->page_dma = 0; - } + pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2, + PCI_DMA_FROMDEVICE); + rx_buffer_info->page_dma = 0; put_page(rx_buffer_info->page); rx_buffer_info->page = NULL; rx_buffer_info->page_offset = 0; @@ -3728,11 +3720,10 @@ static void ixgbe_sfp_task(struct work_struct *work) goto reschedule; ret = hw->phy.ops.reset(hw); if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize " - "because an unsupported SFP+ module type " - "was detected.\n" - "Reload the driver after installing a " - "supported module.\n"); + DPRINTK(PROBE, ERR, "failed to initialize because an " + "unsupported SFP+ module type was detected.\n" + "Reload the driver after installing a " + "supported module.\n"); unregister_netdev(adapter->netdev); } else { DPRINTK(PROBE, INFO, "detected SFP+: %d\n", @@ -4511,8 +4502,7 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work) u32 autoneg; adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK; - autoneg = hw->phy.autoneg_advertised; - if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) + if (hw->mac.ops.get_link_capabilities) hw->mac.ops.get_link_capabilities(hw, &autoneg, &hw->mac.autoneg); if (hw->mac.ops.setup_link_speed) @@ -4536,10 +4526,7 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK; err = hw->phy.ops.identify_sfp(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize because " - "an unsupported SFP+ module type was detected.\n" - "Reload the driver after installing a supported " - "module.\n"); + DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err); ixgbe_down(adapter); return; } @@ -5526,10 +5513,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, round_jiffies(jiffies + (2 * HZ))); err = 0; } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize because " - "an unsupported SFP+ module type was detected.\n" - "Reload the driver after installing a supported " - "module.\n"); + dev_err(&adapter->pdev->dev, "failed to load because an " + "unsupported SFP+ module type was detected.\n"); goto err_sw_init; } else if (err) { dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err); diff --git a/trunk/drivers/net/mdio.c b/trunk/drivers/net/mdio.c index 6851bdb2ce29..dc45e9856c35 100644 --- a/trunk/drivers/net/mdio.c +++ b/trunk/drivers/net/mdio.c @@ -14,10 +14,6 @@ #include #include -MODULE_DESCRIPTION("Generic support for MDIO-compatible transceivers"); -MODULE_AUTHOR("Copyright 2006-2009 Solarflare Communications Inc."); -MODULE_LICENSE("GPL"); - /** * mdio45_probe - probe for an MDIO (clause 45) device * @mdio: MDIO interface diff --git a/trunk/drivers/net/mlx4/mr.c b/trunk/drivers/net/mlx4/mr.c index f96948be0a44..5887e4764d22 100644 --- a/trunk/drivers/net/mlx4/mr.c +++ b/trunk/drivers/net/mlx4/mr.c @@ -399,14 +399,11 @@ static int mlx4_write_mtt_chunk(struct mlx4_dev *dev, struct mlx4_mtt *mtt, if (!mtts) return -ENOMEM; - dma_sync_single_for_cpu(&dev->pdev->dev, dma_handle, - npages * sizeof (u64), DMA_TO_DEVICE); - for (i = 0; i < npages; ++i) mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT); - dma_sync_single_for_device(&dev->pdev->dev, dma_handle, - npages * sizeof (u64), DMA_TO_DEVICE); + dma_sync_single_for_cpu(&dev->pdev->dev, dma_handle, + npages * sizeof (u64), DMA_TO_DEVICE); return 0; } @@ -550,14 +547,11 @@ int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list /* Make sure MPT status is visible before writing MTT entries */ wmb(); - dma_sync_single_for_cpu(&dev->pdev->dev, fmr->dma_handle, - npages * sizeof(u64), DMA_TO_DEVICE); - for (i = 0; i < npages; ++i) fmr->mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT); - dma_sync_single_for_device(&dev->pdev->dev, fmr->dma_handle, - npages * sizeof(u64), DMA_TO_DEVICE); + dma_sync_single_for_cpu(&dev->pdev->dev, fmr->dma_handle, + npages * sizeof(u64), DMA_TO_DEVICE); fmr->mpt->key = cpu_to_be32(key); fmr->mpt->lkey = cpu_to_be32(key); diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index 055bb61d6e77..bdb143d2b5c7 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -944,31 +944,28 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) u32 val = 0; int retries = 60; - if (pegtune_val) - return 0; + if (!pegtune_val) { + do { + val = NXRD32(adapter, CRB_CMDPEG_STATE); - do { - val = NXRD32(adapter, CRB_CMDPEG_STATE); + if (val == PHAN_INITIALIZE_COMPLETE || + val == PHAN_INITIALIZE_ACK) + return 0; - switch (val) { - case PHAN_INITIALIZE_COMPLETE: - case PHAN_INITIALIZE_ACK: - return 0; - case PHAN_INITIALIZE_FAILED: - goto out_err; - default: - break; - } + msleep(500); - msleep(500); + } while (--retries); - } while (--retries); - - NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED); + if (!retries) { + pegtune_val = NXRD32(adapter, + NETXEN_ROMUSB_GLB_PEGTUNE_DONE); + printk(KERN_WARNING "netxen_phantom_init: init failed, " + "pegtune_val=%x\n", pegtune_val); + return -1; + } + } -out_err: - dev_warn(&adapter->pdev->dev, "firmware init failed\n"); - return -EIO; + return 0; } static int diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 2919a2d12bf4..71daa3d5f114 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -705,7 +705,7 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw) first_driver = (adapter->ahw.pci_func == 0); if (!first_driver) - goto wait_init; + return 0; first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc)); @@ -752,7 +752,6 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw) | (_NETXEN_NIC_LINUX_SUBVERSION); NXWR32(adapter, CRB_DRIVER_VERSION, val); -wait_init: /* Handshake with the card before we register the devices. */ err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); if (err) { @@ -1179,7 +1178,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) free_netdev(netdev); } -#ifdef CONFIG_PM static int netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state) { @@ -1244,7 +1242,6 @@ netxen_nic_resume(struct pci_dev *pdev) return 0; } -#endif static int netxen_nic_open(struct net_device *netdev) { @@ -1774,10 +1771,8 @@ static struct pci_driver netxen_driver = { .id_table = netxen_pci_tbl, .probe = netxen_nic_probe, .remove = __devexit_p(netxen_nic_remove), -#ifdef CONFIG_PM .suspend = netxen_nic_suspend, .resume = netxen_nic_resume -#endif }; /* Driver Registration on NetXen card */ diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c index 3e4b67aaa6ea..bbc6d4d3cc94 100644 --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -3142,7 +3142,6 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) (void __iomem *)port_regs; u32 delay = 10; int status = 0; - unsigned long hw_flags = 0; if(ql_mii_setup(qdev)) return -1; @@ -3151,8 +3150,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) ql_write_common_reg(qdev, &port_regs->CommonRegs.serialPortInterfaceReg, (ISP_SERIAL_PORT_IF_WE | (ISP_SERIAL_PORT_IF_WE << 16))); - /* Give the PHY time to come out of reset. */ - mdelay(100); + qdev->port_link_state = LS_DOWN; netif_carrier_off(qdev->ndev); @@ -3352,9 +3350,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) value = ql_read_page0_reg(qdev, &port_regs->portStatus); if (value & PORT_STATUS_IC) break; - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); msleep(500); - spin_lock_irqsave(&qdev->hw_lock, hw_flags); } while (--delay); if (delay == 0) { diff --git a/trunk/drivers/net/sh_eth.c b/trunk/drivers/net/sh_eth.c index a2d82ddb3b4d..341882f959f3 100644 --- a/trunk/drivers/net/sh_eth.c +++ b/trunk/drivers/net/sh_eth.c @@ -865,7 +865,8 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_cpu_data *cd = mdp->cd; irqreturn_t ret = IRQ_NONE; - u32 ioaddr, intr_status = 0; + u32 ioaddr, boguscnt = RX_RING_SIZE; + u32 intr_status = 0; ioaddr = ndev->base_addr; spin_lock(&mdp->lock); @@ -900,6 +901,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) if (intr_status & cd->eesr_err_check) sh_eth_error(ndev, intr_status); + if (--boguscnt < 0) { + printk(KERN_WARNING + "%s: Too much work at interrupt, status=0x%4.4x.\n", + ndev->name, intr_status); + } + other_irq: spin_unlock(&mdp->lock); diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index daf961ab68bc..7681d28c53d7 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -2495,7 +2495,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) if (likely(status >> 16 == (status & 0xffff))) { skb = sky2->rx_ring[sky2->rx_next].skb; skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = le16_to_cpu(status); + skb->csum = status & 0xffff; } else { printk(KERN_NOTICE PFX "%s: hardware receive " "checksum problem (status = %#x)\n", diff --git a/trunk/drivers/net/usb/cdc_eem.c b/trunk/drivers/net/usb/cdc_eem.c index cd35d50e46d4..80e01778dd3b 100644 --- a/trunk/drivers/net/usb/cdc_eem.c +++ b/trunk/drivers/net/usb/cdc_eem.c @@ -319,7 +319,7 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return crc == crc2; if (unlikely(crc != crc2)) { - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; dev_kfree_skb_any(skb2); } else usbnet_skb_return(dev, skb2); diff --git a/trunk/drivers/net/usb/dm9601.c b/trunk/drivers/net/usb/dm9601.c index 1d3730d6690f..7ae82446b93a 100644 --- a/trunk/drivers/net/usb/dm9601.c +++ b/trunk/drivers/net/usb/dm9601.c @@ -513,11 +513,11 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb) len = (skb->data[1] | (skb->data[2] << 8)) - 4; if (unlikely(status & 0xbf)) { - if (status & 0x01) dev->net->stats.rx_fifo_errors++; - if (status & 0x02) dev->net->stats.rx_crc_errors++; - if (status & 0x04) dev->net->stats.rx_frame_errors++; - if (status & 0x20) dev->net->stats.rx_missed_errors++; - if (status & 0x90) dev->net->stats.rx_length_errors++; + if (status & 0x01) dev->stats.rx_fifo_errors++; + if (status & 0x02) dev->stats.rx_crc_errors++; + if (status & 0x04) dev->stats.rx_frame_errors++; + if (status & 0x20) dev->stats.rx_missed_errors++; + if (status & 0x90) dev->stats.rx_length_errors++; return 0; } diff --git a/trunk/drivers/net/usb/net1080.c b/trunk/drivers/net/usb/net1080.c index aeb1ab03a9ee..034e8a73ca6b 100644 --- a/trunk/drivers/net/usb/net1080.c +++ b/trunk/drivers/net/usb/net1080.c @@ -433,7 +433,7 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) dbg("rx framesize %d range %d..%d mtu %d", skb->len, net->hard_header_len, dev->hard_mtu, net->mtu); #endif - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; nc_ensure_sync(dev); return 0; } @@ -442,12 +442,12 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) hdr_len = le16_to_cpup(&header->hdr_len); packet_len = le16_to_cpup(&header->packet_len); if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; dbg("packet too big, %d", packet_len); nc_ensure_sync(dev); return 0; } else if (hdr_len < MIN_HEADER) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; dbg("header too short, %d", hdr_len); nc_ensure_sync(dev); return 0; @@ -465,21 +465,21 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if ((packet_len & 0x01) == 0) { if (skb->data [packet_len] != PAD_BYTE) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; dbg("bad pad"); return 0; } skb_trim(skb, skb->len - 1); } if (skb->len != packet_len) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; dbg("bad packet len %d (expected %d)", skb->len, packet_len); nc_ensure_sync(dev); return 0; } if (header->packet_id != get_unaligned(&trailer->packet_id)) { - dev->net->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x", le16_to_cpu(header->packet_id), le16_to_cpu(trailer->packet_id)); diff --git a/trunk/drivers/net/usb/rndis_host.c b/trunk/drivers/net/usb/rndis_host.c index 2232232b7989..1bf243ef950e 100644 --- a/trunk/drivers/net/usb/rndis_host.c +++ b/trunk/drivers/net/usb/rndis_host.c @@ -487,7 +487,7 @@ int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET || skb->len < msg_len || (data_offset + data_len + 8) > msg_len)) { - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d", le32_to_cpu(hdr->msg_type), msg_len, data_offset, data_len, skb->len); diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index fe045896406b..89a91f8c22de 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -1108,18 +1108,18 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if (unlikely(header & RX_STS_ES_)) { if (netif_msg_rx_err(dev)) devdbg(dev, "Error header=0x%08x", header); - dev->net->stats.rx_errors++; - dev->net->stats.rx_dropped++; + dev->stats.rx_errors++; + dev->stats.rx_dropped++; if (header & RX_STS_CRC_) { - dev->net->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; } else { if (header & (RX_STS_TL_ | RX_STS_RF_)) - dev->net->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if ((header & RX_STS_LE_) && (!(header & RX_STS_FT_))) - dev->net->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } } else { /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index edfd9e10ceba..22c0585a0319 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -234,8 +234,8 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) int status; skb->protocol = eth_type_trans (skb, dev->net); - dev->net->stats.rx_packets++; - dev->net->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; if (netif_msg_rx_status (dev)) devdbg (dev, "< rx, len %zu, type 0x%x", @@ -397,7 +397,7 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) if (netif_msg_rx_err (dev)) devdbg (dev, "drop"); error: - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; skb_queue_tail (&dev->done, skb); } } @@ -420,8 +420,8 @@ static void rx_complete (struct urb *urb) case 0: if (skb->len < dev->net->hard_header_len) { entry->state = rx_cleanup; - dev->net->stats.rx_errors++; - dev->net->stats.rx_length_errors++; + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; if (netif_msg_rx_err (dev)) devdbg (dev, "rx length %d", skb->len); } @@ -433,7 +433,7 @@ static void rx_complete (struct urb *urb) * storm, recovering as needed. */ case -EPIPE: - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; usbnet_defer_kevent (dev, EVENT_RX_HALT); // FALLTHROUGH @@ -451,7 +451,7 @@ static void rx_complete (struct urb *urb) case -EPROTO: case -ETIME: case -EILSEQ: - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; if (!timer_pending (&dev->delay)) { mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); if (netif_msg_link (dev)) @@ -465,12 +465,12 @@ static void rx_complete (struct urb *urb) /* data overrun ... flush fifo? */ case -EOVERFLOW: - dev->net->stats.rx_over_errors++; + dev->stats.rx_over_errors++; // FALLTHROUGH default: entry->state = rx_cleanup; - dev->net->stats.rx_errors++; + dev->stats.rx_errors++; if (netif_msg_rx_err (dev)) devdbg (dev, "rx status %d", urb_status); break; @@ -583,8 +583,8 @@ int usbnet_stop (struct net_device *net) if (netif_msg_ifdown (dev)) devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld", - net->stats.rx_packets, net->stats.tx_packets, - net->stats.rx_errors, net->stats.tx_errors + dev->stats.rx_packets, dev->stats.tx_packets, + dev->stats.rx_errors, dev->stats.tx_errors ); // ensure there are no more active urbs @@ -891,10 +891,10 @@ static void tx_complete (struct urb *urb) struct usbnet *dev = entry->dev; if (urb->status == 0) { - dev->net->stats.tx_packets++; - dev->net->stats.tx_bytes += entry->length; + dev->stats.tx_packets++; + dev->stats.tx_bytes += entry->length; } else { - dev->net->stats.tx_errors++; + dev->stats.tx_errors++; switch (urb->status) { case -EPIPE: @@ -1020,7 +1020,7 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) devdbg (dev, "drop, code %d", retval); drop: retval = NET_XMIT_SUCCESS; - dev->net->stats.tx_dropped++; + dev->stats.tx_dropped++; if (skb) dev_kfree_skb_any (skb); usb_free_urb (urb); diff --git a/trunk/drivers/net/veth.c b/trunk/drivers/net/veth.c index 1097c72e44d5..87197dd9c788 100644 --- a/trunk/drivers/net/veth.c +++ b/trunk/drivers/net/veth.c @@ -208,14 +208,11 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev) static struct net_device_stats *veth_get_stats(struct net_device *dev) { - struct veth_priv *priv; - struct net_device_stats *dev_stats; - int cpu; + struct veth_priv *priv = netdev_priv(dev); + struct net_device_stats *dev_stats = &dev->stats; + unsigned int cpu; struct veth_net_stats *stats; - priv = netdev_priv(dev); - dev_stats = &dev->stats; - dev_stats->rx_packets = 0; dev_stats->tx_packets = 0; dev_stats->rx_bytes = 0; @@ -223,16 +220,17 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev) dev_stats->tx_dropped = 0; dev_stats->rx_dropped = 0; - for_each_online_cpu(cpu) { - stats = per_cpu_ptr(priv->stats, cpu); + if (priv->stats) + for_each_online_cpu(cpu) { + stats = per_cpu_ptr(priv->stats, cpu); - dev_stats->rx_packets += stats->rx_packets; - dev_stats->tx_packets += stats->tx_packets; - dev_stats->rx_bytes += stats->rx_bytes; - dev_stats->tx_bytes += stats->tx_bytes; - dev_stats->tx_dropped += stats->tx_dropped; - dev_stats->rx_dropped += stats->rx_dropped; - } + dev_stats->rx_packets += stats->rx_packets; + dev_stats->tx_packets += stats->tx_packets; + dev_stats->rx_bytes += stats->rx_bytes; + dev_stats->tx_bytes += stats->tx_bytes; + dev_stats->tx_dropped += stats->tx_dropped; + dev_stats->rx_dropped += stats->rx_dropped; + } return dev_stats; } @@ -259,6 +257,8 @@ static int veth_close(struct net_device *dev) netif_carrier_off(dev); netif_carrier_off(priv->peer); + free_percpu(priv->stats); + priv->stats = NULL; return 0; } @@ -289,15 +289,6 @@ static int veth_dev_init(struct net_device *dev) return 0; } -static void veth_dev_free(struct net_device *dev) -{ - struct veth_priv *priv; - - priv = netdev_priv(dev); - free_percpu(priv->stats); - free_netdev(dev); -} - static const struct net_device_ops veth_netdev_ops = { .ndo_init = veth_dev_init, .ndo_open = veth_open, @@ -315,7 +306,7 @@ static void veth_setup(struct net_device *dev) dev->netdev_ops = &veth_netdev_ops; dev->ethtool_ops = &veth_ethtool_ops; dev->features |= NETIF_F_LLTX; - dev->destructor = veth_dev_free; + dev->destructor = free_netdev; } /* diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index 2597145a066e..1032d5fdbd42 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -2907,7 +2907,6 @@ enum parport_pc_pci_cards { netmos_9755, netmos_9805, netmos_9815, - netmos_9901, quatech_sppxp100, }; @@ -2988,7 +2987,7 @@ static struct parport_pc_pci { /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, - /* netmos_9901 */ { 1, { { 0, -1 }, } }, + /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, }; @@ -3090,8 +3089,6 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, - 0xA000, 0x2000, 0, 0, netmos_9901 }, /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, diff --git a/trunk/drivers/pci/hotplug/acpi_pcihp.c b/trunk/drivers/pci/hotplug/acpi_pcihp.c index eb159587d0bf..fbc63d5e459f 100644 --- a/trunk/drivers/pci/hotplug/acpi_pcihp.c +++ b/trunk/drivers/pci/hotplug/acpi_pcihp.c @@ -354,7 +354,7 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, status = acpi_run_hpp(handle, hpp); if (ACPI_SUCCESS(status)) break; - if (acpi_is_root_bridge(handle)) + if (acpi_root_bridge(handle)) break; status = acpi_get_parent(handle, &phandle); if (ACPI_FAILURE(status)) @@ -428,7 +428,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) status = acpi_run_oshp(handle); if (ACPI_SUCCESS(status)) goto got_one; - if (acpi_is_root_bridge(handle)) + if (acpi_root_bridge(handle)) break; chandle = handle; status = acpi_get_parent(chandle, &handle); @@ -449,6 +449,42 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) } EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); +/* acpi_root_bridge - check to see if this acpi object is a root bridge + * + * @handle - the acpi object in question. + */ +int acpi_root_bridge(acpi_handle handle) +{ + acpi_status status; + struct acpi_device_info *info; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + int i; + + status = acpi_get_object_info(handle, &buffer); + if (ACPI_SUCCESS(status)) { + info = buffer.pointer; + if ((info->valid & ACPI_VALID_HID) && + !strcmp(PCI_ROOT_HID_STRING, + info->hardware_id.value)) { + kfree(buffer.pointer); + return 1; + } + if (info->valid & ACPI_VALID_CID) { + for (i=0; i < info->compatibility_id.count; i++) { + if (!strcmp(PCI_ROOT_HID_STRING, + info->compatibility_id.id[i].value)) { + kfree(buffer.pointer); + return 1; + } + } + } + kfree(buffer.pointer); + } + return 0; +} +EXPORT_SYMBOL_GPL(acpi_root_bridge); + + static int is_ejectable(acpi_handle handle) { acpi_status status; diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 0cb0f830a993..3a6064bce561 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -678,9 +678,18 @@ static void remove_bridge(acpi_handle handle) static struct pci_dev * get_apic_pci_info(acpi_handle handle) { + struct acpi_pci_id id; + struct pci_bus *bus; struct pci_dev *dev; - dev = acpi_get_pci_dev(handle); + if (ACPI_FAILURE(acpi_get_pci_id(handle, &id))) + return NULL; + + bus = pci_find_bus(id.segment, id.bus); + if (!bus) + return NULL; + + dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function)); if (!dev) return NULL; @@ -1387,16 +1396,19 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) /* Program resources in newly inserted bridge */ static int acpiphp_configure_bridge (acpi_handle handle) { - struct pci_dev *dev; + struct acpi_pci_id pci_id; struct pci_bus *bus; - dev = acpi_get_pci_dev(handle); - if (!dev) { + if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) { err("cannot get PCI domain and bus number for bridge\n"); return -EINVAL; } - - bus = dev->bus; + bus = pci_find_bus(pci_id.segment, pci_id.bus); + if (!bus) { + err("cannot find bus %d:%d\n", + pci_id.segment, pci_id.bus); + return -EINVAL; + } pci_bus_size_bridges(bus); pci_bus_assign_resources(bus); @@ -1404,7 +1416,6 @@ static int acpiphp_configure_bridge (acpi_handle handle) acpiphp_set_hpp_values(handle, bus); pci_enable_bridges(bus); acpiphp_configure_ioapics(handle); - pci_dev_put(dev); return 0; } @@ -1620,7 +1631,7 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) { int *count = (int *)context; - if (acpi_is_root_bridge(handle)) { + if (acpi_root_bridge(handle)) { acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_bridge, NULL); (*count)++; diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c index 53075424a434..178853a07440 100644 --- a/trunk/drivers/pci/intel-iommu.c +++ b/trunk/drivers/pci/intel-iommu.c @@ -56,32 +56,14 @@ #define MAX_AGAW_WIDTH 64 #define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1) -#define DOMAIN_MAX_PFN(gaw) ((((u64)1) << (gaw-VTD_PAGE_SHIFT)) - 1) #define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) - -/* VT-d pages must always be _smaller_ than MM pages. Otherwise things - are never going to work. */ -static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn) -{ - return dma_pfn >> (PAGE_SHIFT - VTD_PAGE_SHIFT); -} - -static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn) -{ - return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT); -} -static inline unsigned long page_to_dma_pfn(struct page *pg) -{ - return mm_to_dma_pfn(page_to_pfn(pg)); -} -static inline unsigned long virt_to_dma_pfn(void *p) -{ - return page_to_dma_pfn(virt_to_page(p)); -} +#ifndef PHYSICAL_PAGE_MASK +#define PHYSICAL_PAGE_MASK PAGE_MASK +#endif /* global iommu list, set NULL for ignored DMAR units */ static struct intel_iommu **g_iommus; @@ -222,17 +204,12 @@ static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot) static inline u64 dma_pte_addr(struct dma_pte *pte) { -#ifdef CONFIG_64BIT - return pte->val & VTD_PAGE_MASK; -#else - /* Must have a full atomic 64-bit read */ - return __cmpxchg64(pte, 0ULL, 0ULL) & VTD_PAGE_MASK; -#endif + return (pte->val & VTD_PAGE_MASK); } -static inline void dma_set_pte_pfn(struct dma_pte *pte, unsigned long pfn) +static inline void dma_set_pte_addr(struct dma_pte *pte, u64 addr) { - pte->val |= (uint64_t)pfn << VTD_PAGE_SHIFT; + pte->val |= (addr & VTD_PAGE_MASK); } static inline bool dma_pte_present(struct dma_pte *pte) @@ -240,19 +217,6 @@ static inline bool dma_pte_present(struct dma_pte *pte) return (pte->val & 3) != 0; } -static inline int first_pte_in_page(struct dma_pte *pte) -{ - return !((unsigned long)pte & ~VTD_PAGE_MASK); -} - -/* - * This domain is a statically identity mapping domain. - * 1. This domain creats a static 1:1 mapping to all usable memory. - * 2. It maps to each iommu if successful. - * 3. Each iommu mapps to this domain if successful. - */ -struct dmar_domain *si_domain; - /* devices under the same p2p bridge are owned in one domain */ #define DOMAIN_FLAG_P2P_MULTIPLE_DEVICES (1 << 0) @@ -261,9 +225,6 @@ struct dmar_domain *si_domain; */ #define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 1) -/* si_domain contains mulitple devices */ -#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2) - struct dmar_domain { int id; /* domain id */ unsigned long iommu_bmp; /* bitmap of iommus this domain uses*/ @@ -272,6 +233,7 @@ struct dmar_domain { struct iova_domain iovad; /* iova's that belong to this domain */ struct dma_pte *pgd; /* virtual address */ + spinlock_t mapping_lock; /* page table lock */ int gaw; /* max guest address width */ /* adjusted guest address width, 0 is level 2 30-bit */ @@ -473,14 +435,12 @@ int iommu_calculate_agaw(struct intel_iommu *iommu) return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH); } -/* This functionin only returns single iommu in a domain */ +/* in native case, each domain is related to only one iommu */ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain) { int iommu_id; - /* si_domain and vm domain should not get here. */ BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE); - BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY); iommu_id = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); if (iommu_id < 0 || iommu_id >= g_num_of_iommus) @@ -675,78 +635,80 @@ static inline int width_to_agaw(int width) static inline unsigned int level_to_offset_bits(int level) { - return (level - 1) * LEVEL_STRIDE; + return (12 + (level - 1) * LEVEL_STRIDE); } -static inline int pfn_level_offset(unsigned long pfn, int level) +static inline int address_level_offset(u64 addr, int level) { - return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; + return ((addr >> level_to_offset_bits(level)) & LEVEL_MASK); } -static inline unsigned long level_mask(int level) +static inline u64 level_mask(int level) { - return -1UL << level_to_offset_bits(level); + return ((u64)-1 << level_to_offset_bits(level)); } -static inline unsigned long level_size(int level) +static inline u64 level_size(int level) { - return 1UL << level_to_offset_bits(level); + return ((u64)1 << level_to_offset_bits(level)); } -static inline unsigned long align_to_level(unsigned long pfn, int level) +static inline u64 align_to_level(u64 addr, int level) { - return (pfn + level_size(level) - 1) & level_mask(level); + return ((addr + level_size(level) - 1) & level_mask(level)); } -static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, - unsigned long pfn) +static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr) { - int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; + int addr_width = agaw_to_width(domain->agaw); struct dma_pte *parent, *pte = NULL; int level = agaw_to_level(domain->agaw); int offset; + unsigned long flags; BUG_ON(!domain->pgd); - BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); + + addr &= (((u64)1) << addr_width) - 1; parent = domain->pgd; + spin_lock_irqsave(&domain->mapping_lock, flags); while (level > 0) { void *tmp_page; - offset = pfn_level_offset(pfn, level); + offset = address_level_offset(addr, level); pte = &parent[offset]; if (level == 1) break; if (!dma_pte_present(pte)) { - uint64_t pteval; - tmp_page = alloc_pgtable_page(); - if (!tmp_page) + if (!tmp_page) { + spin_unlock_irqrestore(&domain->mapping_lock, + flags); return NULL; - - domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE); - pteval = (virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE; - if (cmpxchg64(&pte->val, 0ULL, pteval)) { - /* Someone else set it while we were thinking; use theirs. */ - free_pgtable_page(tmp_page); - } else { - dma_pte_addr(pte); - domain_flush_cache(domain, pte, sizeof(*pte)); } + domain_flush_cache(domain, tmp_page, PAGE_SIZE); + dma_set_pte_addr(pte, virt_to_phys(tmp_page)); + /* + * high level table always sets r/w, last level page + * table control read/write + */ + dma_set_pte_readable(pte); + dma_set_pte_writable(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); } parent = phys_to_virt(dma_pte_addr(pte)); level--; } + spin_unlock_irqrestore(&domain->mapping_lock, flags); return pte; } /* return address's pte at specific level */ -static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, - unsigned long pfn, - int level) +static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr, + int level) { struct dma_pte *parent, *pte = NULL; int total = agaw_to_level(domain->agaw); @@ -754,7 +716,7 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, parent = domain->pgd; while (level <= total) { - offset = pfn_level_offset(pfn, total); + offset = address_level_offset(addr, total); pte = &parent[offset]; if (level == total) return pte; @@ -767,82 +729,74 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, return NULL; } -/* clear last level pte, a tlb flush should be followed */ -static void dma_pte_clear_range(struct dmar_domain *domain, - unsigned long start_pfn, - unsigned long last_pfn) +/* clear one page's page table */ +static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr) { - int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; - struct dma_pte *first_pte, *pte; + struct dma_pte *pte = NULL; - BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); - BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); + /* get last level pte */ + pte = dma_addr_level_pte(domain, addr, 1); - /* we don't need lock here; nobody else touches the iova range */ - while (start_pfn <= last_pfn) { - first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1); - if (!pte) { - start_pfn = align_to_level(start_pfn + 1, 2); - continue; - } - do { - dma_clear_pte(pte); - start_pfn++; - pte++; - } while (start_pfn <= last_pfn && !first_pte_in_page(pte)); + if (pte) { + dma_clear_pte(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); + } +} + +/* clear last level pte, a tlb flush should be followed */ +static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end) +{ + int addr_width = agaw_to_width(domain->agaw); + int npages; + + start &= (((u64)1) << addr_width) - 1; + end &= (((u64)1) << addr_width) - 1; + /* in case it's partial page */ + start &= PAGE_MASK; + end = PAGE_ALIGN(end); + npages = (end - start) / VTD_PAGE_SIZE; - domain_flush_cache(domain, first_pte, - (void *)pte - (void *)first_pte); + /* we don't need lock here, nobody else touches the iova range */ + while (npages--) { + dma_pte_clear_one(domain, start); + start += VTD_PAGE_SIZE; } } /* free page table pages. last level pte should already be cleared */ static void dma_pte_free_pagetable(struct dmar_domain *domain, - unsigned long start_pfn, - unsigned long last_pfn) + u64 start, u64 end) { - int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; - struct dma_pte *first_pte, *pte; + int addr_width = agaw_to_width(domain->agaw); + struct dma_pte *pte; int total = agaw_to_level(domain->agaw); int level; - unsigned long tmp; + u64 tmp; - BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); - BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); + start &= (((u64)1) << addr_width) - 1; + end &= (((u64)1) << addr_width) - 1; - /* We don't need lock here; nobody else touches the iova range */ + /* we don't need lock here, nobody else touches the iova range */ level = 2; while (level <= total) { - tmp = align_to_level(start_pfn, level); - - /* If we can't even clear one PTE at this level, we're done */ - if (tmp + level_size(level) - 1 > last_pfn) + tmp = align_to_level(start, level); + if (tmp >= end || (tmp + level_size(level) > end)) return; - while (tmp + level_size(level) - 1 <= last_pfn) { - first_pte = pte = dma_pfn_level_pte(domain, tmp, level); - if (!pte) { - tmp = align_to_level(tmp + 1, level + 1); - continue; + while (tmp < end) { + pte = dma_addr_level_pte(domain, tmp, level); + if (pte) { + free_pgtable_page( + phys_to_virt(dma_pte_addr(pte))); + dma_clear_pte(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); } - do { - if (dma_pte_present(pte)) { - free_pgtable_page(phys_to_virt(dma_pte_addr(pte))); - dma_clear_pte(pte); - } - pte++; - tmp += level_size(level); - } while (!first_pte_in_page(pte) && - tmp + level_size(level) - 1 <= last_pfn); - - domain_flush_cache(domain, first_pte, - (void *)pte - (void *)first_pte); - + tmp += level_size(level); } level++; } /* free pgd */ - if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) { + if (start == 0 && end >= ((((u64)1) << addr_width) - 1)) { free_pgtable_page(domain->pgd); domain->pgd = NULL; } @@ -1068,11 +1022,11 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain, } static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, - unsigned long pfn, unsigned int pages) + u64 addr, unsigned int pages) { unsigned int mask = ilog2(__roundup_pow_of_two(pages)); - uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT; + BUG_ON(addr & (~VTD_PAGE_MASK)); BUG_ON(pages == 0); /* @@ -1087,12 +1041,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, else iommu->flush.flush_iotlb(iommu, did, addr, mask, DMA_TLB_PSI_FLUSH); - - /* - * In caching mode, domain ID 0 is reserved for non-present to present - * mapping flush. Device IOTLB doesn't need to be flushed in this case. - */ - if (!cap_caching_mode(iommu->cap) || did) + if (did) iommu_flush_dev_iotlb(iommu->domains[did], addr, mask); } @@ -1240,71 +1189,48 @@ void free_dmar_iommu(struct intel_iommu *iommu) free_context_table(iommu); } -static struct dmar_domain *alloc_domain(void) +static struct dmar_domain * iommu_alloc_domain(struct intel_iommu *iommu) { + unsigned long num; + unsigned long ndomains; struct dmar_domain *domain; + unsigned long flags; domain = alloc_domain_mem(); if (!domain) return NULL; - memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); - domain->flags = 0; - - return domain; -} - -static int iommu_attach_domain(struct dmar_domain *domain, - struct intel_iommu *iommu) -{ - int num; - unsigned long ndomains; - unsigned long flags; - ndomains = cap_ndoms(iommu->cap); spin_lock_irqsave(&iommu->lock, flags); - num = find_first_zero_bit(iommu->domain_ids, ndomains); if (num >= ndomains) { spin_unlock_irqrestore(&iommu->lock, flags); + free_domain_mem(domain); printk(KERN_ERR "IOMMU: no free domain ids\n"); - return -ENOMEM; + return NULL; } - domain->id = num; set_bit(num, iommu->domain_ids); + domain->id = num; + memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); set_bit(iommu->seq_id, &domain->iommu_bmp); + domain->flags = 0; iommu->domains[num] = domain; spin_unlock_irqrestore(&iommu->lock, flags); - return 0; + return domain; } -static void iommu_detach_domain(struct dmar_domain *domain, - struct intel_iommu *iommu) +static void iommu_free_domain(struct dmar_domain *domain) { unsigned long flags; - int num, ndomains; - int found = 0; + struct intel_iommu *iommu; - spin_lock_irqsave(&iommu->lock, flags); - ndomains = cap_ndoms(iommu->cap); - num = find_first_bit(iommu->domain_ids, ndomains); - for (; num < ndomains; ) { - if (iommu->domains[num] == domain) { - found = 1; - break; - } - num = find_next_bit(iommu->domain_ids, - cap_ndoms(iommu->cap), num+1); - } + iommu = domain_get_iommu(domain); - if (found) { - clear_bit(num, iommu->domain_ids); - clear_bit(iommu->seq_id, &domain->iommu_bmp); - iommu->domains[num] = NULL; - } + spin_lock_irqsave(&iommu->lock, flags); + clear_bit(domain->id, iommu->domain_ids); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -1317,6 +1243,7 @@ static void dmar_init_reserved_ranges(void) struct pci_dev *pdev = NULL; struct iova *iova; int i; + u64 addr, size; init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN); @@ -1339,9 +1266,12 @@ static void dmar_init_reserved_ranges(void) r = &pdev->resource[i]; if (!r->flags || !(r->flags & IORESOURCE_MEM)) continue; - iova = reserve_iova(&reserved_iova_list, - IOVA_PFN(r->start), - IOVA_PFN(r->end)); + addr = r->start; + addr &= PHYSICAL_PAGE_MASK; + size = r->end - addr; + size = PAGE_ALIGN(size); + iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr), + IOVA_PFN(size + addr) - 1); if (!iova) printk(KERN_ERR "Reserve iova failed\n"); } @@ -1375,6 +1305,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width) unsigned long sagaw; init_iova_domain(&domain->iovad, DMA_32BIT_PFN); + spin_lock_init(&domain->mapping_lock); spin_lock_init(&domain->iommu_lock); domain_reserve_special_ranges(domain); @@ -1419,8 +1350,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width) static void domain_exit(struct dmar_domain *domain) { - struct dmar_drhd_unit *drhd; - struct intel_iommu *iommu; + u64 end; /* Domain 0 is reserved, so dont process it */ if (!domain) @@ -1429,17 +1359,16 @@ static void domain_exit(struct dmar_domain *domain) domain_remove_dev_info(domain); /* destroy iovas */ put_iova_domain(&domain->iovad); + end = DOMAIN_MAX_ADDR(domain->gaw); + end = end & (~PAGE_MASK); /* clear ptes */ - dma_pte_clear_range(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); + dma_pte_clear_range(domain, 0, end); /* free page tables */ - dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); - - for_each_active_iommu(iommu, drhd) - if (test_bit(iommu->seq_id, &domain->iommu_bmp)) - iommu_detach_domain(domain, iommu); + dma_pte_free_pagetable(domain, 0, end); + iommu_free_domain(domain); free_domain_mem(domain); } @@ -1479,8 +1408,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, id = domain->id; pgd = domain->pgd; - if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE || - domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) { + if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) { int found = 0; /* find an available domain id for this device in iommu */ @@ -1505,7 +1433,6 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, } set_bit(num, iommu->domain_ids); - set_bit(iommu->seq_id, &domain->iommu_bmp); iommu->domains[num] = domain; id = num; } @@ -1648,86 +1575,42 @@ static int domain_context_mapped(struct pci_dev *pdev) tmp->devfn); } -static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, - struct scatterlist *sg, unsigned long phys_pfn, - unsigned long nr_pages, int prot) +static int +domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova, + u64 hpa, size_t size, int prot) { - struct dma_pte *first_pte = NULL, *pte = NULL; - phys_addr_t uninitialized_var(pteval); - int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; - unsigned long sg_res; + u64 start_pfn, end_pfn; + struct dma_pte *pte; + int index; + int addr_width = agaw_to_width(domain->agaw); - BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width); + hpa &= (((u64)1) << addr_width) - 1; if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0) return -EINVAL; - - prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP; - - if (sg) - sg_res = 0; - else { - sg_res = nr_pages + 1; - pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot; - } - - while (nr_pages--) { - uint64_t tmp; - - if (!sg_res) { - sg_res = (sg->offset + sg->length + VTD_PAGE_SIZE - 1) >> VTD_PAGE_SHIFT; - sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset; - sg->dma_length = sg->length; - pteval = page_to_phys(sg_page(sg)) | prot; - } - if (!pte) { - first_pte = pte = pfn_to_dma_pte(domain, iov_pfn); - if (!pte) - return -ENOMEM; - } + iova &= PAGE_MASK; + start_pfn = ((u64)hpa) >> VTD_PAGE_SHIFT; + end_pfn = (VTD_PAGE_ALIGN(((u64)hpa) + size)) >> VTD_PAGE_SHIFT; + index = 0; + while (start_pfn < end_pfn) { + pte = addr_to_dma_pte(domain, iova + VTD_PAGE_SIZE * index); + if (!pte) + return -ENOMEM; /* We don't need lock here, nobody else * touches the iova range */ - tmp = cmpxchg64_local(&pte->val, 0ULL, pteval); - if (tmp) { - static int dumps = 5; - printk(KERN_CRIT "ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n", - iov_pfn, tmp, (unsigned long long)pteval); - if (dumps) { - dumps--; - debug_dma_dump_mappings(NULL); - } - WARN_ON(1); - } - pte++; - if (!nr_pages || first_pte_in_page(pte)) { - domain_flush_cache(domain, first_pte, - (void *)pte - (void *)first_pte); - pte = NULL; - } - iov_pfn++; - pteval += VTD_PAGE_SIZE; - sg_res--; - if (!sg_res) - sg = sg_next(sg); + BUG_ON(dma_pte_addr(pte)); + dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT); + dma_set_pte_prot(pte, prot); + if (prot & DMA_PTE_SNP) + dma_set_pte_snp(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); + start_pfn++; + index++; } return 0; } -static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn, - struct scatterlist *sg, unsigned long nr_pages, - int prot) -{ - return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot); -} - -static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn, - unsigned long phys_pfn, unsigned long nr_pages, - int prot) -{ - return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot); -} - static void iommu_detach_dev(struct intel_iommu *iommu, u8 bus, u8 devfn) { if (!iommu) @@ -1792,7 +1675,6 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) unsigned long flags; int bus = 0, devfn = 0; int segment; - int ret; domain = find_domain(pdev); if (domain) @@ -1825,10 +1707,6 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) } } - domain = alloc_domain(); - if (!domain) - goto error; - /* Allocate new domain for the device */ drhd = dmar_find_matched_drhd_unit(pdev); if (!drhd) { @@ -1838,11 +1716,9 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) } iommu = drhd->iommu; - ret = iommu_attach_domain(domain, iommu); - if (ret) { - domain_exit(domain); + domain = iommu_alloc_domain(iommu); + if (!domain) goto error; - } if (domain_init(domain, gaw)) { domain_exit(domain); @@ -1916,63 +1792,55 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) return find_domain(pdev); } -static int iommu_identity_mapping; - -static int iommu_domain_identity_map(struct dmar_domain *domain, - unsigned long long start, - unsigned long long end) -{ - unsigned long first_vpfn = start >> VTD_PAGE_SHIFT; - unsigned long last_vpfn = end >> VTD_PAGE_SHIFT; - - if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn), - dma_to_mm_pfn(last_vpfn))) { - printk(KERN_ERR "IOMMU: reserve iova failed\n"); - return -ENOMEM; - } - - pr_debug("Mapping reserved region %llx-%llx for domain %d\n", - start, end, domain->id); - /* - * RMRR range might have overlap with physical memory range, - * clear it first - */ - dma_pte_clear_range(domain, first_vpfn, last_vpfn); - - return domain_pfn_mapping(domain, first_vpfn, first_vpfn, - last_vpfn - first_vpfn + 1, - DMA_PTE_READ|DMA_PTE_WRITE); -} - static int iommu_prepare_identity_map(struct pci_dev *pdev, unsigned long long start, unsigned long long end) { struct dmar_domain *domain; + unsigned long size; + unsigned long long base; int ret; printk(KERN_INFO - "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", - pci_name(pdev), start, end); - + "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", + pci_name(pdev), start, end); + /* page table init */ domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); if (!domain) return -ENOMEM; - ret = iommu_domain_identity_map(domain, start, end); - if (ret) + /* The address might not be aligned */ + base = start & PAGE_MASK; + size = end - base; + size = PAGE_ALIGN(size); + if (!reserve_iova(&domain->iovad, IOVA_PFN(base), + IOVA_PFN(base + size) - 1)) { + printk(KERN_ERR "IOMMU: reserve iova failed\n"); + ret = -ENOMEM; goto error; + } - /* context entry init */ - ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL); + pr_debug("Mapping reserved region %lx@%llx for %s\n", + size, base, pci_name(pdev)); + /* + * RMRR range might have overlap with physical memory range, + * clear it first + */ + dma_pte_clear_range(domain, base, base + size); + + ret = domain_page_mapping(domain, base, base, size, + DMA_PTE_READ|DMA_PTE_WRITE); if (ret) goto error; - return 0; - - error: + /* context entry init */ + ret = domain_context_mapping(domain, pdev, CONTEXT_TT_MULTI_LEVEL); + if (!ret) + return 0; +error: domain_exit(domain); return ret; + } static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, @@ -1984,165 +1852,107 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, rmrr->end_address + 1); } -#ifdef CONFIG_DMAR_FLOPPY_WA -static inline void iommu_prepare_isa(void) -{ +#ifdef CONFIG_DMAR_GFX_WA +struct iommu_prepare_data { struct pci_dev *pdev; int ret; +}; - pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); - if (!pdev) - return; +static int __init iommu_prepare_work_fn(unsigned long start_pfn, + unsigned long end_pfn, void *datax) +{ + struct iommu_prepare_data *data; - printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); - ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); + data = (struct iommu_prepare_data *)datax; - if (ret) - printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " - "floppy might not work\n"); + data->ret = iommu_prepare_identity_map(data->pdev, + start_pfn<ret; } -#else -static inline void iommu_prepare_isa(void) + +static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev) { - return; + int nid; + struct iommu_prepare_data data; + + data.pdev = pdev; + data.ret = 0; + + for_each_online_node(nid) { + work_with_active_regions(nid, iommu_prepare_work_fn, &data); + if (data.ret) + return data.ret; + } + return data.ret; } -#endif /* !CONFIG_DMAR_FLPY_WA */ -/* Initialize each context entry as pass through.*/ -static int __init init_context_pass_through(void) +static void __init iommu_prepare_gfx_mapping(void) { struct pci_dev *pdev = NULL; - struct dmar_domain *domain; int ret; for_each_pci_dev(pdev) { - domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); - ret = domain_context_mapping(domain, pdev, - CONTEXT_TT_PASS_THROUGH); + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO || + !IS_GFX_DEVICE(pdev)) + continue; + printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n", + pci_name(pdev)); + ret = iommu_prepare_with_active_regions(pdev); if (ret) - return ret; + printk(KERN_ERR "IOMMU: mapping reserved region failed\n"); } - return 0; } - -static int md_domain_init(struct dmar_domain *domain, int guest_width); - -static int __init si_domain_work_fn(unsigned long start_pfn, - unsigned long end_pfn, void *datax) +#else /* !CONFIG_DMAR_GFX_WA */ +static inline void iommu_prepare_gfx_mapping(void) { - int *ret = datax; - - *ret = iommu_domain_identity_map(si_domain, - (uint64_t)start_pfn << PAGE_SHIFT, - (uint64_t)end_pfn << PAGE_SHIFT); - return *ret; - + return; } +#endif -static int si_domain_init(void) +#ifdef CONFIG_DMAR_FLOPPY_WA +static inline void iommu_prepare_isa(void) { - struct dmar_drhd_unit *drhd; - struct intel_iommu *iommu; - int nid, ret = 0; - - si_domain = alloc_domain(); - if (!si_domain) - return -EFAULT; - - pr_debug("Identity mapping domain is domain %d\n", si_domain->id); - - for_each_active_iommu(iommu, drhd) { - ret = iommu_attach_domain(si_domain, iommu); - if (ret) { - domain_exit(si_domain); - return -EFAULT; - } - } - - if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) { - domain_exit(si_domain); - return -EFAULT; - } - - si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY; - - for_each_online_node(nid) { - work_with_active_regions(nid, si_domain_work_fn, &ret); - if (ret) - return ret; - } - - return 0; -} + struct pci_dev *pdev; + int ret; -static void domain_remove_one_dev_info(struct dmar_domain *domain, - struct pci_dev *pdev); -static int identity_mapping(struct pci_dev *pdev) -{ - struct device_domain_info *info; + pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); + if (!pdev) + return; - if (likely(!iommu_identity_mapping)) - return 0; + printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n"); + ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); + if (ret) + printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, " + "floppy might not work\n"); - list_for_each_entry(info, &si_domain->devices, link) - if (info->dev == pdev) - return 1; - return 0; } - -static int domain_add_dev_info(struct dmar_domain *domain, - struct pci_dev *pdev) +#else +static inline void iommu_prepare_isa(void) { - struct device_domain_info *info; - unsigned long flags; - - info = alloc_devinfo_mem(); - if (!info) - return -ENOMEM; - - info->segment = pci_domain_nr(pdev->bus); - info->bus = pdev->bus->number; - info->devfn = pdev->devfn; - info->dev = pdev; - info->domain = domain; - - spin_lock_irqsave(&device_domain_lock, flags); - list_add(&info->link, &domain->devices); - list_add(&info->global, &device_domain_list); - pdev->dev.archdata.iommu = info; - spin_unlock_irqrestore(&device_domain_lock, flags); - - return 0; + return; } +#endif /* !CONFIG_DMAR_FLPY_WA */ -static int iommu_prepare_static_identity_mapping(void) +/* Initialize each context entry as pass through.*/ +static int __init init_context_pass_through(void) { struct pci_dev *pdev = NULL; + struct dmar_domain *domain; int ret; - ret = si_domain_init(); - if (ret) - return -EFAULT; - for_each_pci_dev(pdev) { - printk(KERN_INFO "IOMMU: identity mapping for device %s\n", - pci_name(pdev)); - - ret = domain_context_mapping(si_domain, pdev, - CONTEXT_TT_MULTI_LEVEL); - if (ret) - return ret; - ret = domain_add_dev_info(si_domain, pdev); + domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); + ret = domain_context_mapping(domain, pdev, + CONTEXT_TT_PASS_THROUGH); if (ret) return ret; } - return 0; } -int __init init_dmars(void) +static int __init init_dmars(void) { struct dmar_drhd_unit *drhd; struct dmar_rmrr_unit *rmrr; @@ -2151,13 +1961,6 @@ int __init init_dmars(void) int i, ret; int pass_through = 1; - /* - * In case pass through can not be enabled, iommu tries to use identity - * mapping. - */ - if (iommu_pass_through) - iommu_identity_mapping = 1; - /* * for each drhd * allocate root @@ -2287,12 +2090,9 @@ int __init init_dmars(void) /* * If pass through is not set or not enabled, setup context entries for - * identity mappings for rmrr, gfx, and isa and may fall back to static - * identity mapping if iommu_identity_mapping is set. + * identity mappings for rmrr, gfx, and isa. */ if (!iommu_pass_through) { - if (iommu_identity_mapping) - iommu_prepare_static_identity_mapping(); /* * For each rmrr * for each dev attached to rmrr @@ -2307,7 +2107,6 @@ int __init init_dmars(void) * endfor * endfor */ - printk(KERN_INFO "IOMMU: Setting RMRR:\n"); for_each_rmrr_units(rmrr) { for (i = 0; i < rmrr->devices_cnt; i++) { pdev = rmrr->devices[i]; @@ -2324,6 +2123,8 @@ int __init init_dmars(void) } } + iommu_prepare_gfx_mapping(); + iommu_prepare_isa(); } @@ -2368,40 +2169,50 @@ int __init init_dmars(void) return ret; } -static inline unsigned long aligned_nrpages(unsigned long host_addr, - size_t size) +static inline u64 aligned_size(u64 host_addr, size_t size) { - host_addr &= ~PAGE_MASK; - host_addr += size + PAGE_SIZE - 1; + u64 addr; + addr = (host_addr & (~PAGE_MASK)) + size; + return PAGE_ALIGN(addr); +} + +struct iova * +iommu_alloc_iova(struct dmar_domain *domain, size_t size, u64 end) +{ + struct iova *piova; - return host_addr >> VTD_PAGE_SHIFT; + /* Make sure it's in range */ + end = min_t(u64, DOMAIN_MAX_ADDR(domain->gaw), end); + if (!size || (IOVA_START_ADDR + size > end)) + return NULL; + + piova = alloc_iova(&domain->iovad, + size >> PAGE_SHIFT, IOVA_PFN(end), 1); + return piova; } -static struct iova *intel_alloc_iova(struct device *dev, - struct dmar_domain *domain, - unsigned long nrpages, uint64_t dma_mask) +static struct iova * +__intel_alloc_iova(struct device *dev, struct dmar_domain *domain, + size_t size, u64 dma_mask) { struct pci_dev *pdev = to_pci_dev(dev); struct iova *iova = NULL; - /* Restrict dma_mask to the width that the iommu can handle */ - dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask); - - if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) { + if (dma_mask <= DMA_BIT_MASK(32) || dmar_forcedac) + iova = iommu_alloc_iova(domain, size, dma_mask); + else { /* * First try to allocate an io virtual address in * DMA_BIT_MASK(32) and if that fails then try allocating * from higher range */ - iova = alloc_iova(&domain->iovad, nrpages, - IOVA_PFN(DMA_BIT_MASK(32)), 1); - if (iova) - return iova; - } - iova = alloc_iova(&domain->iovad, nrpages, IOVA_PFN(dma_mask), 1); - if (unlikely(!iova)) { - printk(KERN_ERR "Allocating %ld-page iova for %s failed", - nrpages, pci_name(pdev)); + iova = iommu_alloc_iova(domain, size, DMA_BIT_MASK(32)); + if (!iova) + iova = iommu_alloc_iova(domain, size, dma_mask); + } + + if (!iova) { + printk(KERN_ERR"Allocating iova for %s failed", pci_name(pdev)); return NULL; } @@ -2437,52 +2248,6 @@ get_valid_domain_for_dev(struct pci_dev *pdev) return domain; } -static int iommu_dummy(struct pci_dev *pdev) -{ - return pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO; -} - -/* Check if the pdev needs to go through non-identity map and unmap process.*/ -static int iommu_no_mapping(struct pci_dev *pdev) -{ - int found; - - if (!iommu_identity_mapping) - return iommu_dummy(pdev); - - found = identity_mapping(pdev); - if (found) { - if (pdev->dma_mask > DMA_BIT_MASK(32)) - return 1; - else { - /* - * 32 bit DMA is removed from si_domain and fall back - * to non-identity mapping. - */ - domain_remove_one_dev_info(si_domain, pdev); - printk(KERN_INFO "32bit %s uses non-identity mapping\n", - pci_name(pdev)); - return 0; - } - } else { - /* - * In case of a detached 64 bit DMA device from vm, the device - * is put into si_domain for identity mapping. - */ - if (pdev->dma_mask > DMA_BIT_MASK(32)) { - int ret; - ret = domain_add_dev_info(si_domain, pdev); - if (!ret) { - printk(KERN_INFO "64bit %s uses identity mapping\n", - pci_name(pdev)); - return 1; - } - } - } - - return iommu_dummy(pdev); -} - static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, int dir, u64 dma_mask) { @@ -2495,8 +2260,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, struct intel_iommu *iommu; BUG_ON(dir == DMA_NONE); - - if (iommu_no_mapping(pdev)) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return paddr; domain = get_valid_domain_for_dev(pdev); @@ -2504,12 +2268,14 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, return 0; iommu = domain_get_iommu(domain); - size = aligned_nrpages(paddr, size); + size = aligned_size((u64)paddr, size); - iova = intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); + iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); if (!iova) goto error; + start_paddr = (phys_addr_t)iova->pfn_lo << PAGE_SHIFT; + /* * Check if DMAR supports zero-length reads on write only * mappings.. @@ -2525,20 +2291,20 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, * might have two guest_addr mapping to the same host paddr, but this * is not a big problem */ - ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova->pfn_lo), - paddr >> VTD_PAGE_SHIFT, size, prot); + ret = domain_page_mapping(domain, start_paddr, + ((u64)paddr) & PHYSICAL_PAGE_MASK, + size, prot); if (ret) goto error; /* it's a non-present to present mapping. Only flush if caching mode */ if (cap_caching_mode(iommu->cap)) - iommu_flush_iotlb_psi(iommu, 0, mm_to_dma_pfn(iova->pfn_lo), size); + iommu_flush_iotlb_psi(iommu, 0, start_paddr, + size >> VTD_PAGE_SHIFT); else iommu_flush_write_buffer(iommu); - start_paddr = (phys_addr_t)iova->pfn_lo << PAGE_SHIFT; - start_paddr += paddr & ~PAGE_MASK; - return start_paddr; + return start_paddr + ((u64)paddr & (~PAGE_MASK)); error: if (iova) @@ -2631,38 +2397,34 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, { struct pci_dev *pdev = to_pci_dev(dev); struct dmar_domain *domain; - unsigned long start_pfn, last_pfn; + unsigned long start_addr; struct iova *iova; struct intel_iommu *iommu; - if (iommu_no_mapping(pdev)) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return; - domain = find_domain(pdev); BUG_ON(!domain); iommu = domain_get_iommu(domain); iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr)); - if (WARN_ONCE(!iova, "Driver unmaps unmatched page at PFN %llx\n", - (unsigned long long)dev_addr)) + if (!iova) return; - start_pfn = mm_to_dma_pfn(iova->pfn_lo); - last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1; + start_addr = iova->pfn_lo << PAGE_SHIFT; + size = aligned_size((u64)dev_addr, size); - pr_debug("Device %s unmapping: pfn %lx-%lx\n", - pci_name(pdev), start_pfn, last_pfn); + pr_debug("Device %s unmapping: %zx@%llx\n", + pci_name(pdev), size, (unsigned long long)start_addr); /* clear the whole page */ - dma_pte_clear_range(domain, start_pfn, last_pfn); - + dma_pte_clear_range(domain, start_addr, start_addr + size); /* free page tables */ - dma_pte_free_pagetable(domain, start_pfn, last_pfn); - + dma_pte_free_pagetable(domain, start_addr, start_addr + size); if (intel_iommu_strict) { - iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, - last_pfn - start_pfn + 1); + iommu_flush_iotlb_psi(iommu, domain->id, start_addr, + size >> VTD_PAGE_SHIFT); /* free iova */ __free_iova(&domain->iovad, iova); } else { @@ -2720,13 +2482,17 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, enum dma_data_direction dir, struct dma_attrs *attrs) { + int i; struct pci_dev *pdev = to_pci_dev(hwdev); struct dmar_domain *domain; - unsigned long start_pfn, last_pfn; + unsigned long start_addr; struct iova *iova; + size_t size = 0; + phys_addr_t addr; + struct scatterlist *sg; struct intel_iommu *iommu; - if (iommu_no_mapping(pdev)) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return; domain = find_domain(pdev); @@ -2735,21 +2501,22 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, iommu = domain_get_iommu(domain); iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address)); - if (WARN_ONCE(!iova, "Driver unmaps unmatched sglist at PFN %llx\n", - (unsigned long long)sglist[0].dma_address)) + if (!iova) return; + for_each_sg(sglist, sg, nelems, i) { + addr = page_to_phys(sg_page(sg)) + sg->offset; + size += aligned_size((u64)addr, sg->length); + } - start_pfn = mm_to_dma_pfn(iova->pfn_lo); - last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1; + start_addr = iova->pfn_lo << PAGE_SHIFT; /* clear the whole page */ - dma_pte_clear_range(domain, start_pfn, last_pfn); - + dma_pte_clear_range(domain, start_addr, start_addr + size); /* free page tables */ - dma_pte_free_pagetable(domain, start_pfn, last_pfn); + dma_pte_free_pagetable(domain, start_addr, start_addr + size); - iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, - (last_pfn - start_pfn + 1)); + iommu_flush_iotlb_psi(iommu, domain->id, start_addr, + size >> VTD_PAGE_SHIFT); /* free iova */ __free_iova(&domain->iovad, iova); @@ -2772,20 +2539,21 @@ static int intel_nontranslate_map_sg(struct device *hddev, static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, enum dma_data_direction dir, struct dma_attrs *attrs) { + phys_addr_t addr; int i; struct pci_dev *pdev = to_pci_dev(hwdev); struct dmar_domain *domain; size_t size = 0; int prot = 0; - size_t offset_pfn = 0; + size_t offset = 0; struct iova *iova = NULL; int ret; struct scatterlist *sg; - unsigned long start_vpfn; + unsigned long start_addr; struct intel_iommu *iommu; BUG_ON(dir == DMA_NONE); - if (iommu_no_mapping(pdev)) + if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir); domain = get_valid_domain_for_dev(pdev); @@ -2794,10 +2562,12 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne iommu = domain_get_iommu(domain); - for_each_sg(sglist, sg, nelems, i) - size += aligned_nrpages(sg->offset, sg->length); + for_each_sg(sglist, sg, nelems, i) { + addr = page_to_phys(sg_page(sg)) + sg->offset; + size += aligned_size((u64)addr, sg->length); + } - iova = intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); + iova = __intel_alloc_iova(hwdev, domain, size, pdev->dma_mask); if (!iova) { sglist->dma_length = 0; return 0; @@ -2813,24 +2583,35 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) prot |= DMA_PTE_WRITE; - start_vpfn = mm_to_dma_pfn(iova->pfn_lo); - - ret = domain_sg_mapping(domain, start_vpfn, sglist, mm_to_dma_pfn(size), prot); - if (unlikely(ret)) { - /* clear the page */ - dma_pte_clear_range(domain, start_vpfn, - start_vpfn + size - 1); - /* free page tables */ - dma_pte_free_pagetable(domain, start_vpfn, - start_vpfn + size - 1); - /* free iova */ - __free_iova(&domain->iovad, iova); - return 0; + start_addr = iova->pfn_lo << PAGE_SHIFT; + offset = 0; + for_each_sg(sglist, sg, nelems, i) { + addr = page_to_phys(sg_page(sg)) + sg->offset; + size = aligned_size((u64)addr, sg->length); + ret = domain_page_mapping(domain, start_addr + offset, + ((u64)addr) & PHYSICAL_PAGE_MASK, + size, prot); + if (ret) { + /* clear the page */ + dma_pte_clear_range(domain, start_addr, + start_addr + offset); + /* free page tables */ + dma_pte_free_pagetable(domain, start_addr, + start_addr + offset); + /* free iova */ + __free_iova(&domain->iovad, iova); + return 0; + } + sg->dma_address = start_addr + offset + + ((u64)addr & (~PAGE_MASK)); + sg->dma_length = sg->length; + offset += size; } /* it's a non-present to present mapping. Only flush if caching mode */ if (cap_caching_mode(iommu->cap)) - iommu_flush_iotlb_psi(iommu, 0, start_vpfn, offset_pfn); + iommu_flush_iotlb_psi(iommu, 0, start_addr, + offset >> VTD_PAGE_SHIFT); else iommu_flush_write_buffer(iommu); @@ -3170,6 +2951,31 @@ int __init intel_iommu_init(void) return 0; } +static int vm_domain_add_dev_info(struct dmar_domain *domain, + struct pci_dev *pdev) +{ + struct device_domain_info *info; + unsigned long flags; + + info = alloc_devinfo_mem(); + if (!info) + return -ENOMEM; + + info->segment = pci_domain_nr(pdev->bus); + info->bus = pdev->bus->number; + info->devfn = pdev->devfn; + info->dev = pdev; + info->domain = domain; + + spin_lock_irqsave(&device_domain_lock, flags); + list_add(&info->link, &domain->devices); + list_add(&info->global, &device_domain_list); + pdev->dev.archdata.iommu = info; + spin_unlock_irqrestore(&device_domain_lock, flags); + + return 0; +} + static void iommu_detach_dependent_devices(struct intel_iommu *iommu, struct pci_dev *pdev) { @@ -3197,7 +3003,7 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu, } } -static void domain_remove_one_dev_info(struct dmar_domain *domain, +static void vm_domain_remove_one_dev_info(struct dmar_domain *domain, struct pci_dev *pdev) { struct device_domain_info *info; @@ -3330,11 +3136,12 @@ static struct dmar_domain *iommu_alloc_vm_domain(void) return domain; } -static int md_domain_init(struct dmar_domain *domain, int guest_width) +static int vm_domain_init(struct dmar_domain *domain, int guest_width) { int adjust_width; init_iova_domain(&domain->iovad, DMA_32BIT_PFN); + spin_lock_init(&domain->mapping_lock); spin_lock_init(&domain->iommu_lock); domain_reserve_special_ranges(domain); @@ -3388,6 +3195,8 @@ static void iommu_free_vm_domain(struct dmar_domain *domain) static void vm_domain_exit(struct dmar_domain *domain) { + u64 end; + /* Domain 0 is reserved, so dont process it */ if (!domain) return; @@ -3395,12 +3204,14 @@ static void vm_domain_exit(struct dmar_domain *domain) vm_domain_remove_all_dev_info(domain); /* destroy iovas */ put_iova_domain(&domain->iovad); + end = DOMAIN_MAX_ADDR(domain->gaw); + end = end & (~VTD_PAGE_MASK); /* clear ptes */ - dma_pte_clear_range(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); + dma_pte_clear_range(domain, 0, end); /* free page tables */ - dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); + dma_pte_free_pagetable(domain, 0, end); iommu_free_vm_domain(domain); free_domain_mem(domain); @@ -3416,7 +3227,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain) "intel_iommu_domain_init: dmar_domain == NULL\n"); return -ENOMEM; } - if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) { + if (vm_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) { printk(KERN_ERR "intel_iommu_domain_init() failed\n"); vm_domain_exit(dmar_domain); @@ -3451,9 +3262,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, old_domain = find_domain(pdev); if (old_domain) { - if (dmar_domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE || - dmar_domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) - domain_remove_one_dev_info(old_domain, pdev); + if (dmar_domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) + vm_domain_remove_one_dev_info(old_domain, pdev); else domain_remove_dev_info(old_domain); } @@ -3475,7 +3285,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, return -EFAULT; } - ret = domain_add_dev_info(dmar_domain, pdev); + ret = vm_domain_add_dev_info(dmar_domain, pdev); if (ret) return ret; @@ -3489,7 +3299,7 @@ static void intel_iommu_detach_device(struct iommu_domain *domain, struct dmar_domain *dmar_domain = domain->priv; struct pci_dev *pdev = to_pci_dev(dev); - domain_remove_one_dev_info(dmar_domain, pdev); + vm_domain_remove_one_dev_info(dmar_domain, pdev); } static int intel_iommu_map_range(struct iommu_domain *domain, @@ -3509,7 +3319,7 @@ static int intel_iommu_map_range(struct iommu_domain *domain, if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) prot |= DMA_PTE_SNP; - max_addr = iova + size; + max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size); if (dmar_domain->max_addr < max_addr) { int min_agaw; u64 end; @@ -3527,11 +3337,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain, } dmar_domain->max_addr = max_addr; } - /* Round up size to next multiple of PAGE_SIZE, if it and - the low bits of hpa would take us onto the next page */ - size = aligned_nrpages(hpa, size); - ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT, - hpa >> VTD_PAGE_SHIFT, size, prot); + + ret = domain_page_mapping(dmar_domain, iova, hpa, size, prot); return ret; } @@ -3539,12 +3346,15 @@ static void intel_iommu_unmap_range(struct iommu_domain *domain, unsigned long iova, size_t size) { struct dmar_domain *dmar_domain = domain->priv; + dma_addr_t base; - dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT, - (iova + size - 1) >> VTD_PAGE_SHIFT); + /* The address might not be aligned */ + base = iova & VTD_PAGE_MASK; + size = VTD_PAGE_ALIGN(size); + dma_pte_clear_range(dmar_domain, base, base + size); - if (dmar_domain->max_addr == iova + size) - dmar_domain->max_addr = iova; + if (dmar_domain->max_addr == base + size) + dmar_domain->max_addr = base; } static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, @@ -3554,7 +3364,7 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, struct dma_pte *pte; u64 phys = 0; - pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT); + pte = addr_to_dma_pte(dmar_domain, iova); if (pte) phys = dma_pte_addr(pte); diff --git a/trunk/drivers/pci/intr_remapping.c b/trunk/drivers/pci/intr_remapping.c index 4f5b8712931f..1e83c8c5f985 100644 --- a/trunk/drivers/pci/intr_remapping.c +++ b/trunk/drivers/pci/intr_remapping.c @@ -10,8 +10,6 @@ #include #include "intr_remapping.h" #include -#include -#include "pci.h" static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; static int ir_ioapic_num; @@ -316,8 +314,7 @@ int modify_irte(int irq, struct irte *irte_modified) index = irq_iommu->irte_index + irq_iommu->sub_handle; irte = &iommu->ir_table->base[index]; - set_64bit((unsigned long *)&irte->low, irte_modified->low); - set_64bit((unsigned long *)&irte->high, irte_modified->high); + set_64bit((unsigned long *)irte, irte_modified->low); __iommu_flush_cache(iommu, irte, sizeof(*irte)); rc = qi_flush_iec(iommu, index, 0); @@ -372,32 +369,12 @@ struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) return drhd->iommu; } -static int clear_entries(struct irq_2_iommu *irq_iommu) -{ - struct irte *start, *entry, *end; - struct intel_iommu *iommu; - int index; - - if (irq_iommu->sub_handle) - return 0; - - iommu = irq_iommu->iommu; - index = irq_iommu->irte_index + irq_iommu->sub_handle; - - start = iommu->ir_table->base + index; - end = start + (1 << irq_iommu->irte_mask); - - for (entry = start; entry < end; entry++) { - set_64bit((unsigned long *)&entry->low, 0); - set_64bit((unsigned long *)&entry->high, 0); - } - - return qi_flush_iec(iommu, index, irq_iommu->irte_mask); -} - int free_irte(int irq) { int rc = 0; + int index, i; + struct irte *irte; + struct intel_iommu *iommu; struct irq_2_iommu *irq_iommu; unsigned long flags; @@ -408,7 +385,16 @@ int free_irte(int irq) return -1; } - rc = clear_entries(irq_iommu); + iommu = irq_iommu->iommu; + + index = irq_iommu->irte_index + irq_iommu->sub_handle; + irte = &iommu->ir_table->base[index]; + + if (!irq_iommu->sub_handle) { + for (i = 0; i < (1 << irq_iommu->irte_mask); i++) + set_64bit((unsigned long *)(irte + i), 0); + rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask); + } irq_iommu->iommu = NULL; irq_iommu->irte_index = 0; @@ -420,91 +406,6 @@ int free_irte(int irq) return rc; } -/* - * source validation type - */ -#define SVT_NO_VERIFY 0x0 /* no verification is required */ -#define SVT_VERIFY_SID_SQ 0x1 /* verify using SID and SQ fiels */ -#define SVT_VERIFY_BUS 0x2 /* verify bus of request-id */ - -/* - * source-id qualifier - */ -#define SQ_ALL_16 0x0 /* verify all 16 bits of request-id */ -#define SQ_13_IGNORE_1 0x1 /* verify most significant 13 bits, ignore - * the third least significant bit - */ -#define SQ_13_IGNORE_2 0x2 /* verify most significant 13 bits, ignore - * the second and third least significant bits - */ -#define SQ_13_IGNORE_3 0x3 /* verify most significant 13 bits, ignore - * the least three significant bits - */ - -/* - * set SVT, SQ and SID fields of irte to verify - * source ids of interrupt requests - */ -static void set_irte_sid(struct irte *irte, unsigned int svt, - unsigned int sq, unsigned int sid) -{ - irte->svt = svt; - irte->sq = sq; - irte->sid = sid; -} - -int set_ioapic_sid(struct irte *irte, int apic) -{ - int i; - u16 sid = 0; - - if (!irte) - return -1; - - for (i = 0; i < MAX_IO_APICS; i++) { - if (ir_ioapic[i].id == apic) { - sid = (ir_ioapic[i].bus << 8) | ir_ioapic[i].devfn; - break; - } - } - - if (sid == 0) { - pr_warning("Failed to set source-id of IOAPIC (%d)\n", apic); - return -1; - } - - set_irte_sid(irte, 1, 0, sid); - - return 0; -} - -int set_msi_sid(struct irte *irte, struct pci_dev *dev) -{ - struct pci_dev *bridge; - - if (!irte || !dev) - return -1; - - /* PCIe device or Root Complex integrated PCI device */ - if (dev->is_pcie || !dev->bus->parent) { - set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, - (dev->bus->number << 8) | dev->devfn); - return 0; - } - - bridge = pci_find_upstream_pcie_bridge(dev); - if (bridge) { - if (bridge->is_pcie) /* this is a PCIE-to-PCI/PCIX bridge */ - set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, - (bridge->bus->number << 8) | dev->bus->number); - else /* this is a legacy PCI bridge */ - set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, - (bridge->bus->number << 8) | bridge->devfn); - } - - return 0; -} - static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode) { u64 addr; @@ -711,35 +612,6 @@ int __init enable_intr_remapping(int eim) return -1; } -static void ir_parse_one_ioapic_scope(struct acpi_dmar_device_scope *scope, - struct intel_iommu *iommu) -{ - struct acpi_dmar_pci_path *path; - u8 bus; - int count; - - bus = scope->bus; - path = (struct acpi_dmar_pci_path *)(scope + 1); - count = (scope->length - sizeof(struct acpi_dmar_device_scope)) - / sizeof(struct acpi_dmar_pci_path); - - while (--count > 0) { - /* - * Access PCI directly due to the PCI - * subsystem isn't initialized yet. - */ - bus = read_pci_config_byte(bus, path->dev, path->fn, - PCI_SECONDARY_BUS); - path++; - } - - ir_ioapic[ir_ioapic_num].bus = bus; - ir_ioapic[ir_ioapic_num].devfn = PCI_DEVFN(path->dev, path->fn); - ir_ioapic[ir_ioapic_num].iommu = iommu; - ir_ioapic[ir_ioapic_num].id = scope->enumeration_id; - ir_ioapic_num++; -} - static int ir_parse_ioapic_scope(struct acpi_dmar_header *header, struct intel_iommu *iommu) { @@ -764,7 +636,9 @@ static int ir_parse_ioapic_scope(struct acpi_dmar_header *header, " 0x%Lx\n", scope->enumeration_id, drhd->address); - ir_parse_one_ioapic_scope(scope, iommu); + ir_ioapic[ir_ioapic_num].iommu = iommu; + ir_ioapic[ir_ioapic_num].id = scope->enumeration_id; + ir_ioapic_num++; } start += scope->length; } diff --git a/trunk/drivers/pci/intr_remapping.h b/trunk/drivers/pci/intr_remapping.h index 63a263c18415..ca48f0df8ac9 100644 --- a/trunk/drivers/pci/intr_remapping.h +++ b/trunk/drivers/pci/intr_remapping.h @@ -3,8 +3,6 @@ struct ioapic_scope { struct intel_iommu *iommu; unsigned int id; - unsigned int bus; /* PCI bus number */ - unsigned int devfn; /* PCI devfn number */ }; #define IR_X2APIC_MODE(mode) (mode ? (1 << 11) : 0) diff --git a/trunk/drivers/pci/iova.c b/trunk/drivers/pci/iova.c index 46dd440e2315..2287116e9822 100644 --- a/trunk/drivers/pci/iova.c +++ b/trunk/drivers/pci/iova.c @@ -1,19 +1,9 @@ /* - * Copyright © 2006-2009, Intel Corporation. + * Copyright (c) 2006, 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., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. + * This file is released under the GPLv2. * + * Copyright (C) 2006-2008 Intel Corporation * Author: Anil S Keshavamurthy */ @@ -133,15 +123,7 @@ static int __alloc_and_insert_iova_range(struct iova_domain *iovad, /* Insert the new_iova into domain rbtree by holding writer lock */ /* Add new node and rebalance tree. */ { - struct rb_node **entry, *parent = NULL; - - /* If we have 'prev', it's a valid place to start the - insertion. Otherwise, start from the root. */ - if (prev) - entry = &prev; - else - entry = &iovad->rbroot.rb_node; - + struct rb_node **entry = &((prev)), *parent = NULL; /* Figure out where to put new node */ while (*entry) { struct iova *this = container_of(*entry, diff --git a/trunk/drivers/pcmcia/vrc4171_card.c b/trunk/drivers/pcmcia/vrc4171_card.c index d4ad50d737b0..659421d0ca46 100644 --- a/trunk/drivers/pcmcia/vrc4171_card.c +++ b/trunk/drivers/pcmcia/vrc4171_card.c @@ -1,7 +1,7 @@ /* * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services. * - * Copyright (C) 2003-2005 Yoichi Yuasa + * Copyright (C) 2003-2005 Yoichi Yuasa * * 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 @@ -32,7 +32,7 @@ #include "i82365.h" MODULE_DESCRIPTION("NEC VRC4171 Card Controllers driver for Socket Services"); -MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_AUTHOR("Yoichi Yuasa "); MODULE_LICENSE("GPL"); #define CARD_MAX_SLOTS 2 diff --git a/trunk/drivers/pcmcia/vrc4173_cardu.c b/trunk/drivers/pcmcia/vrc4173_cardu.c index 9b3c15827e5c..812f038e9bda 100644 --- a/trunk/drivers/pcmcia/vrc4173_cardu.c +++ b/trunk/drivers/pcmcia/vrc4173_cardu.c @@ -6,7 +6,7 @@ * NEC VRC4173 CARDU driver for Socket Services * (This device doesn't support CardBus. it is supporting only 16bit PC Card.) * - * Copyright 2002,2003 Yoichi Yuasa + * Copyright 2002,2003 Yoichi Yuasa * * 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 @@ -41,7 +41,7 @@ #include "vrc4173_cardu.h" MODULE_DESCRIPTION("NEC VRC4173 CARDU driver for Socket Services"); -MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_AUTHOR("Yoichi Yuasa "); MODULE_LICENSE("GPL"); static int vrc4173_cardu_slots; diff --git a/trunk/drivers/pcmcia/vrc4173_cardu.h b/trunk/drivers/pcmcia/vrc4173_cardu.h index a7d96018ed8d..7d77c74120c1 100644 --- a/trunk/drivers/pcmcia/vrc4173_cardu.h +++ b/trunk/drivers/pcmcia/vrc4173_cardu.h @@ -5,7 +5,7 @@ * BRIEF MODULE DESCRIPTION * Include file for NEC VRC4173 CARDU. * - * Copyright 2002 Yoichi Yuasa + * Copyright 2002 Yoichi Yuasa * * 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 diff --git a/trunk/drivers/platform/x86/Kconfig b/trunk/drivers/platform/x86/Kconfig index 46dad12f952f..c682ac536415 100644 --- a/trunk/drivers/platform/x86/Kconfig +++ b/trunk/drivers/platform/x86/Kconfig @@ -34,27 +34,10 @@ config ACER_WMI If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M here. -config ACERHDF - tristate "Acer Aspire One temperature and fan driver" - depends on THERMAL && THERMAL_HWMON && ACPI - ---help--- - This is a driver for Acer Aspire One netbooks. It allows to access - the temperature sensor and to control the fan. - - After loading this driver the BIOS is still in control of the fan. - To let the kernel handle the fan, do: - echo -n enabled > /sys/class/thermal/thermal_zone0/mode - - For more information about this driver see - - - If you have an Acer Aspire One netbook, say Y or M - here. - config ASUS_LAPTOP - tristate "Asus Laptop Extras" + tristate "Asus Laptop Extras (EXPERIMENTAL)" depends on ACPI - depends on !ACPI_ASUS + depends on EXPERIMENTAL && !ACPI_ASUS select LEDS_CLASS select NEW_LEDS select BACKLIGHT_CLASS_DEVICE @@ -62,12 +45,12 @@ config ASUS_LAPTOP ---help--- This is the new Linux driver for Asus laptops. It may also support some MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate - standard ACPI events and input events. It also adds + standard ACPI events that go through /proc/acpi/events. It also adds support for video output switching, LCD backlight control, Bluetooth and Wlan control, and most importantly, allows you to blink those fancy LEDs. For more information and a userspace daemon for handling the extra - buttons see . + buttons see . If you have an ACPI-compatible ASUS laptop, say Y or M here. @@ -355,15 +338,11 @@ config EEEPC_LAPTOP depends on INPUT depends on EXPERIMENTAL depends on RFKILL || RFKILL = n - depends on HOTPLUG_PCI select BACKLIGHT_CLASS_DEVICE select HWMON ---help--- This driver supports the Fn-Fx keys on Eee PC laptops. - - It also gives access to some extra laptop functionalities like - Bluetooth, backlight and allows powering on/off some other - devices. + It also adds the ability to switch camera/wlan on/off. If you have an Eee PC laptop, say Y or M here. @@ -390,7 +369,7 @@ config ACPI_WMI any ACPI-WMI devices. config ACPI_ASUS - tristate "ASUS/Medion Laptop Extras (DEPRECATED)" + tristate "ASUS/Medion Laptop Extras" depends on ACPI select BACKLIGHT_CLASS_DEVICE ---help--- @@ -411,7 +390,7 @@ config ACPI_ASUS parameters. More information and a userspace daemon for handling the extra buttons - at . + at . If you have an ACPI-compatible ASUS laptop, say Y or M here. This driver is still under development, so if your laptop is unsupported or diff --git a/trunk/drivers/platform/x86/Makefile b/trunk/drivers/platform/x86/Makefile index 641b8bfa5538..e40c7bd1b87e 100644 --- a/trunk/drivers/platform/x86/Makefile +++ b/trunk/drivers/platform/x86/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_DELL_WMI) += dell-wmi.o obj-$(CONFIG_ACER_WMI) += acer-wmi.o -obj-$(CONFIG_ACERHDF) += acerhdf.o obj-$(CONFIG_HP_WMI) += hp-wmi.o obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o diff --git a/trunk/drivers/platform/x86/acerhdf.c b/trunk/drivers/platform/x86/acerhdf.c deleted file mode 100644 index bdfee177eefb..000000000000 --- a/trunk/drivers/platform/x86/acerhdf.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * acerhdf - A driver which monitors the temperature - * of the aspire one netbook, turns on/off the fan - * as soon as the upper/lower threshold is reached. - * - * (C) 2009 - Peter Feuerer peter (a) piie.net - * http://piie.net - * 2009 Borislav Petkov - * - * Inspired by and many thanks to: - * o acerfand - Rachel Greenham - * o acer_ec.pl - Michael Kurz michi.kurz (at) googlemail.com - * - Petr Tomasek tomasek (#) etf,cuni,cz - * - Carlos Corbacho cathectic (at) gmail.com - * o lkml - Matthew Garrett - * - Borislav Petkov - * - Andreas Mohr - * - * 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 - */ - -#define pr_fmt(fmt) "acerhdf: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * The driver is started with "kernel mode off" by default. That means, the BIOS - * is still in control of the fan. In this mode the driver allows to read the - * temperature of the cpu and a userspace tool may take over control of the fan. - * If the driver is switched to "kernel mode" (e.g. via module parameter) the - * driver is in full control of the fan. If you want the module to be started in - * kernel mode by default, define the following: - */ -#undef START_IN_KERNEL_MODE - -#define DRV_VER "0.5.13" - -/* - * According to the Atom N270 datasheet, - * (http://download.intel.com/design/processor/datashts/320032.pdf) the - * CPU's optimal operating limits denoted in junction temperature as - * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So, - * assume 89°C is critical temperature. - */ -#define ACERHDF_TEMP_CRIT 89 -#define ACERHDF_FAN_OFF 0 -#define ACERHDF_FAN_AUTO 1 - -/* - * No matter what value the user puts into the fanon variable, turn on the fan - * at 80 degree Celsius to prevent hardware damage - */ -#define ACERHDF_MAX_FANON 80 - -/* - * Maximum interval between two temperature checks is 15 seconds, as the die - * can get hot really fast under heavy load (plus we shouldn't forget about - * possible impact of _external_ aggressive sources such as heaters, sun etc.) - */ -#define ACERHDF_MAX_INTERVAL 15 - -#ifdef START_IN_KERNEL_MODE -static int kernelmode = 1; -#else -static int kernelmode; -#endif - -static unsigned int interval = 10; -static unsigned int fanon = 63; -static unsigned int fanoff = 58; -static unsigned int verbose; -static unsigned int fanstate = ACERHDF_FAN_AUTO; -static char force_bios[16]; -static unsigned int prev_interval; -struct thermal_zone_device *thz_dev; -struct thermal_cooling_device *cl_dev; -struct platform_device *acerhdf_dev; - -module_param(kernelmode, uint, 0); -MODULE_PARM_DESC(kernelmode, "Kernel mode fan control on / off"); -module_param(interval, uint, 0600); -MODULE_PARM_DESC(interval, "Polling interval of temperature check"); -module_param(fanon, uint, 0600); -MODULE_PARM_DESC(fanon, "Turn the fan on above this temperature"); -module_param(fanoff, uint, 0600); -MODULE_PARM_DESC(fanoff, "Turn the fan off below this temperature"); -module_param(verbose, uint, 0600); -MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); -module_param_string(force_bios, force_bios, 16, 0); -MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check"); - -/* BIOS settings */ -struct bios_settings_t { - const char *vendor; - const char *version; - unsigned char fanreg; - unsigned char tempreg; - unsigned char fancmd[2]; /* fan off and auto commands */ -}; - -/* Register addresses and values for different BIOS versions */ -static const struct bios_settings_t bios_tbl[] = { - {"Acer", "v0.3109", 0x55, 0x58, {0x1f, 0x00} }, - {"Acer", "v0.3114", 0x55, 0x58, {0x1f, 0x00} }, - {"Acer", "v0.3301", 0x55, 0x58, {0xaf, 0x00} }, - {"Acer", "v0.3304", 0x55, 0x58, {0xaf, 0x00} }, - {"Acer", "v0.3305", 0x55, 0x58, {0xaf, 0x00} }, - {"Acer", "v0.3308", 0x55, 0x58, {0x21, 0x00} }, - {"Acer", "v0.3309", 0x55, 0x58, {0x21, 0x00} }, - {"Acer", "v0.3310", 0x55, 0x58, {0x21, 0x00} }, - {"Gateway", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, - {"Packard Bell", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, - {"", "", 0, 0, {0, 0} } -}; - -static const struct bios_settings_t *bios_cfg __read_mostly; - - -static int acerhdf_get_temp(int *temp) -{ - u8 read_temp; - - if (ec_read(bios_cfg->tempreg, &read_temp)) - return -EINVAL; - - *temp = read_temp; - - return 0; -} - -static int acerhdf_get_fanstate(int *state) -{ - u8 fan; - bool tmp; - - if (ec_read(bios_cfg->fanreg, &fan)) - return -EINVAL; - - tmp = (fan == bios_cfg->fancmd[ACERHDF_FAN_OFF]); - *state = tmp ? ACERHDF_FAN_OFF : ACERHDF_FAN_AUTO; - - return 0; -} - -static void acerhdf_change_fanstate(int state) -{ - unsigned char cmd; - - if (verbose) - pr_notice("fan %s\n", (state == ACERHDF_FAN_OFF) ? - "OFF" : "ON"); - - if ((state != ACERHDF_FAN_OFF) && (state != ACERHDF_FAN_AUTO)) { - pr_err("invalid fan state %d requested, setting to auto!\n", - state); - state = ACERHDF_FAN_AUTO; - } - - cmd = bios_cfg->fancmd[state]; - fanstate = state; - - ec_write(bios_cfg->fanreg, cmd); -} - -static void acerhdf_check_param(struct thermal_zone_device *thermal) -{ - if (fanon > ACERHDF_MAX_FANON) { - pr_err("fanon temperature too high, set to %d\n", - ACERHDF_MAX_FANON); - fanon = ACERHDF_MAX_FANON; - } - - if (kernelmode && prev_interval != interval) { - if (interval > ACERHDF_MAX_INTERVAL) { - pr_err("interval too high, set to %d\n", - ACERHDF_MAX_INTERVAL); - interval = ACERHDF_MAX_INTERVAL; - } - if (verbose) - pr_notice("interval changed to: %d\n", - interval); - thermal->polling_delay = interval*1000; - prev_interval = interval; - } -} - -/* - * This is the thermal zone callback which does the delayed polling of the fan - * state. We do check /sysfs-originating settings here in acerhdf_check_param() - * as late as the polling interval is since we can't do that in the respective - * accessors of the module parameters. - */ -static int acerhdf_get_ec_temp(struct thermal_zone_device *thermal, - unsigned long *t) -{ - int temp, err = 0; - - acerhdf_check_param(thermal); - - err = acerhdf_get_temp(&temp); - if (err) - return err; - - if (verbose) - pr_notice("temp %d\n", temp); - - *t = temp; - return 0; -} - -static int acerhdf_bind(struct thermal_zone_device *thermal, - struct thermal_cooling_device *cdev) -{ - /* if the cooling device is the one from acerhdf bind it */ - if (cdev != cl_dev) - return 0; - - if (thermal_zone_bind_cooling_device(thermal, 0, cdev)) { - pr_err("error binding cooling dev\n"); - return -EINVAL; - } - return 0; -} - -static int acerhdf_unbind(struct thermal_zone_device *thermal, - struct thermal_cooling_device *cdev) -{ - if (cdev != cl_dev) - return 0; - - if (thermal_zone_unbind_cooling_device(thermal, 0, cdev)) { - pr_err("error unbinding cooling dev\n"); - return -EINVAL; - } - return 0; -} - -static inline void acerhdf_revert_to_bios_mode(void) -{ - acerhdf_change_fanstate(ACERHDF_FAN_AUTO); - kernelmode = 0; - if (thz_dev) - thz_dev->polling_delay = 0; - pr_notice("kernel mode fan control OFF\n"); -} -static inline void acerhdf_enable_kernelmode(void) -{ - kernelmode = 1; - - thz_dev->polling_delay = interval*1000; - thermal_zone_device_update(thz_dev); - pr_notice("kernel mode fan control ON\n"); -} - -static int acerhdf_get_mode(struct thermal_zone_device *thermal, - enum thermal_device_mode *mode) -{ - if (verbose) - pr_notice("kernel mode fan control %d\n", kernelmode); - - *mode = (kernelmode) ? THERMAL_DEVICE_ENABLED - : THERMAL_DEVICE_DISABLED; - - return 0; -} - -/* - * set operation mode; - * enabled: the thermal layer of the kernel takes care about - * the temperature and the fan. - * disabled: the BIOS takes control of the fan. - */ -static int acerhdf_set_mode(struct thermal_zone_device *thermal, - enum thermal_device_mode mode) -{ - if (mode == THERMAL_DEVICE_DISABLED && kernelmode) - acerhdf_revert_to_bios_mode(); - else if (mode == THERMAL_DEVICE_ENABLED && !kernelmode) - acerhdf_enable_kernelmode(); - - return 0; -} - -static int acerhdf_get_trip_type(struct thermal_zone_device *thermal, int trip, - enum thermal_trip_type *type) -{ - if (trip == 0) - *type = THERMAL_TRIP_ACTIVE; - - return 0; -} - -static int acerhdf_get_trip_temp(struct thermal_zone_device *thermal, int trip, - unsigned long *temp) -{ - if (trip == 0) - *temp = fanon; - - return 0; -} - -static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal, - unsigned long *temperature) -{ - *temperature = ACERHDF_TEMP_CRIT; - return 0; -} - -/* bind callback functions to thermalzone */ -struct thermal_zone_device_ops acerhdf_dev_ops = { - .bind = acerhdf_bind, - .unbind = acerhdf_unbind, - .get_temp = acerhdf_get_ec_temp, - .get_mode = acerhdf_get_mode, - .set_mode = acerhdf_set_mode, - .get_trip_type = acerhdf_get_trip_type, - .get_trip_temp = acerhdf_get_trip_temp, - .get_crit_temp = acerhdf_get_crit_temp, -}; - - -/* - * cooling device callback functions - * get maximal fan cooling state - */ -static int acerhdf_get_max_state(struct thermal_cooling_device *cdev, - unsigned long *state) -{ - *state = 1; - - return 0; -} - -static int acerhdf_get_cur_state(struct thermal_cooling_device *cdev, - unsigned long *state) -{ - int err = 0, tmp; - - err = acerhdf_get_fanstate(&tmp); - if (err) - return err; - - *state = (tmp == ACERHDF_FAN_AUTO) ? 1 : 0; - return 0; -} - -/* change current fan state - is overwritten when running in kernel mode */ -static int acerhdf_set_cur_state(struct thermal_cooling_device *cdev, - unsigned long state) -{ - int cur_temp, cur_state, err = 0; - - if (!kernelmode) - return 0; - - err = acerhdf_get_temp(&cur_temp); - if (err) { - pr_err("error reading temperature, hand off control to BIOS\n"); - goto err_out; - } - - err = acerhdf_get_fanstate(&cur_state); - if (err) { - pr_err("error reading fan state, hand off control to BIOS\n"); - goto err_out; - } - - if (state == 0) { - /* turn fan off only if below fanoff temperature */ - if ((cur_state == ACERHDF_FAN_AUTO) && - (cur_temp < fanoff)) - acerhdf_change_fanstate(ACERHDF_FAN_OFF); - } else { - if (cur_state == ACERHDF_FAN_OFF) - acerhdf_change_fanstate(ACERHDF_FAN_AUTO); - } - return 0; - -err_out: - acerhdf_revert_to_bios_mode(); - return -EINVAL; -} - -/* bind fan callbacks to fan device */ -struct thermal_cooling_device_ops acerhdf_cooling_ops = { - .get_max_state = acerhdf_get_max_state, - .get_cur_state = acerhdf_get_cur_state, - .set_cur_state = acerhdf_set_cur_state, -}; - -/* suspend / resume functionality */ -static int acerhdf_suspend(struct platform_device *dev, pm_message_t state) -{ - if (kernelmode) - acerhdf_change_fanstate(ACERHDF_FAN_AUTO); - - if (verbose) - pr_notice("going suspend\n"); - - return 0; -} - -static int acerhdf_resume(struct platform_device *device) -{ - if (verbose) - pr_notice("resuming\n"); - - return 0; -} - -static int __devinit acerhdf_probe(struct platform_device *device) -{ - return 0; -} - -static int acerhdf_remove(struct platform_device *device) -{ - return 0; -} - -struct platform_driver acerhdf_drv = { - .driver = { - .name = "acerhdf", - .owner = THIS_MODULE, - }, - .probe = acerhdf_probe, - .remove = acerhdf_remove, - .suspend = acerhdf_suspend, - .resume = acerhdf_resume, -}; - - -/* check hardware */ -static int acerhdf_check_hardware(void) -{ - char const *vendor, *version, *product; - int i; - - /* get BIOS data */ - vendor = dmi_get_system_info(DMI_SYS_VENDOR); - version = dmi_get_system_info(DMI_BIOS_VERSION); - product = dmi_get_system_info(DMI_PRODUCT_NAME); - - pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER); - - if (!force_bios[0]) { - if (strncmp(product, "AO", 2)) { - pr_err("no Aspire One hardware found\n"); - return -EINVAL; - } - } else { - pr_info("forcing BIOS version: %s\n", version); - version = force_bios; - kernelmode = 0; - } - - if (verbose) - pr_info("BIOS info: %s %s, product: %s\n", - vendor, version, product); - - /* search BIOS version and vendor in BIOS settings table */ - for (i = 0; bios_tbl[i].version[0]; i++) { - if (!strcmp(bios_tbl[i].vendor, vendor) && - !strcmp(bios_tbl[i].version, version)) { - bios_cfg = &bios_tbl[i]; - break; - } - } - - if (!bios_cfg) { - pr_err("unknown (unsupported) BIOS version %s/%s, " - "please report, aborting!\n", vendor, version); - return -EINVAL; - } - - /* - * if started with kernel mode off, prevent the kernel from switching - * off the fan - */ - if (!kernelmode) { - pr_notice("Fan control off, to enable do:\n"); - pr_notice("echo -n \"enabled\" > " - "/sys/class/thermal/thermal_zone0/mode\n"); - } - - return 0; -} - -static int acerhdf_register_platform(void) -{ - int err = 0; - - err = platform_driver_register(&acerhdf_drv); - if (err) - return err; - - acerhdf_dev = platform_device_alloc("acerhdf", -1); - platform_device_add(acerhdf_dev); - - return 0; -} - -static void acerhdf_unregister_platform(void) -{ - if (!acerhdf_dev) - return; - - platform_device_del(acerhdf_dev); - platform_driver_unregister(&acerhdf_drv); -} - -static int acerhdf_register_thermal(void) -{ - cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL, - &acerhdf_cooling_ops); - - if (IS_ERR(cl_dev)) - return -EINVAL; - - thz_dev = thermal_zone_device_register("acerhdf", 1, NULL, - &acerhdf_dev_ops, 0, 0, 0, - (kernelmode) ? interval*1000 : 0); - if (IS_ERR(thz_dev)) - return -EINVAL; - - return 0; -} - -static void acerhdf_unregister_thermal(void) -{ - if (cl_dev) { - thermal_cooling_device_unregister(cl_dev); - cl_dev = NULL; - } - - if (thz_dev) { - thermal_zone_device_unregister(thz_dev); - thz_dev = NULL; - } -} - -static int __init acerhdf_init(void) -{ - int err = 0; - - err = acerhdf_check_hardware(); - if (err) - goto out_err; - - err = acerhdf_register_platform(); - if (err) - goto err_unreg; - - err = acerhdf_register_thermal(); - if (err) - goto err_unreg; - - return 0; - -err_unreg: - acerhdf_unregister_thermal(); - acerhdf_unregister_platform(); - -out_err: - return -ENODEV; -} - -static void __exit acerhdf_exit(void) -{ - acerhdf_change_fanstate(ACERHDF_FAN_AUTO); - acerhdf_unregister_thermal(); - acerhdf_unregister_platform(); -} - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Peter Feuerer"); -MODULE_DESCRIPTION("Aspire One temperature and fan driver"); -MODULE_ALIAS("dmi:*:*Acer*:*:"); -MODULE_ALIAS("dmi:*:*Gateway*:*:"); -MODULE_ALIAS("dmi:*:*Packard Bell*:*:"); - -module_init(acerhdf_init); -module_exit(acerhdf_exit); diff --git a/trunk/drivers/platform/x86/asus-laptop.c b/trunk/drivers/platform/x86/asus-laptop.c index db657bbeec90..bfc1a8892a32 100644 --- a/trunk/drivers/platform/x86/asus-laptop.c +++ b/trunk/drivers/platform/x86/asus-laptop.c @@ -33,8 +33,6 @@ * Sam Lin - GPS support */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -55,10 +53,9 @@ #define ASUS_HOTK_NAME "Asus Laptop Support" #define ASUS_HOTK_CLASS "hotkey" #define ASUS_HOTK_DEVICE_NAME "Hotkey" -#define ASUS_HOTK_FILE KBUILD_MODNAME +#define ASUS_HOTK_FILE "asus-laptop" #define ASUS_HOTK_PREFIX "\\_SB.ATKD." - /* * Some events we use, same for all Asus */ @@ -210,17 +207,13 @@ MODULE_DEVICE_TABLE(acpi, asus_device_ids); static int asus_hotk_add(struct acpi_device *device); static int asus_hotk_remove(struct acpi_device *device, int type); -static void asus_hotk_notify(struct acpi_device *device, u32 event); - static struct acpi_driver asus_hotk_driver = { .name = ASUS_HOTK_NAME, .class = ASUS_HOTK_CLASS, .ids = asus_device_ids, - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = asus_hotk_add, .remove = asus_hotk_remove, - .notify = asus_hotk_notify, }, }; @@ -330,7 +323,7 @@ static int read_wireless_status(int mask) rv = acpi_evaluate_integer(wireless_status_handle, NULL, NULL, &status); if (ACPI_FAILURE(rv)) - pr_warning("Error reading Wireless status\n"); + printk(ASUS_WARNING "Error reading Wireless status\n"); else return (status & mask) ? 1 : 0; @@ -344,7 +337,7 @@ static int read_gps_status(void) rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status); if (ACPI_FAILURE(rv)) - pr_warning("Error reading GPS status\n"); + printk(ASUS_WARNING "Error reading GPS status\n"); else return status ? 1 : 0; @@ -384,7 +377,7 @@ static void write_status(acpi_handle handle, int out, int mask) } if (write_acpi_int(handle, NULL, out, NULL)) - pr_warning(" write failed %x\n", mask); + printk(ASUS_WARNING " write failed %x\n", mask); } /* /sys/class/led handlers */ @@ -427,7 +420,7 @@ static int set_lcd_state(int value) NULL, NULL, NULL); if (ACPI_FAILURE(status)) - pr_warning("Error switching LCD\n"); + printk(ASUS_WARNING "Error switching LCD\n"); } write_status(NULL, lcd, LCD_ON); @@ -451,7 +444,7 @@ static int read_brightness(struct backlight_device *bd) rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value); if (ACPI_FAILURE(rv)) - pr_warning("Error reading brightness\n"); + printk(ASUS_WARNING "Error reading brightness\n"); return value; } @@ -464,7 +457,7 @@ static int set_brightness(struct backlight_device *bd, int value) /* 0 <= value <= 15 */ if (write_acpi_int(brightness_set_handle, NULL, value, NULL)) { - pr_warning("Error changing brightness\n"); + printk(ASUS_WARNING "Error changing brightness\n"); ret = -EIO; } @@ -594,7 +587,7 @@ static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, rv = parse_arg(buf, count, &value); if (rv > 0) { if (write_acpi_int(ledd_set_handle, NULL, value, NULL)) - pr_warning("LED display write failed\n"); + printk(ASUS_WARNING "LED display write failed\n"); else hotk->ledd_status = (u32) value; } @@ -639,7 +632,7 @@ static void set_display(int value) { /* no sanity check needed for now */ if (write_acpi_int(display_set_handle, NULL, value, NULL)) - pr_warning("Error setting display\n"); + printk(ASUS_WARNING "Error setting display\n"); return; } @@ -654,7 +647,7 @@ static int read_display(void) rv = acpi_evaluate_integer(display_get_handle, NULL, NULL, &value); if (ACPI_FAILURE(rv)) - pr_warning("Error reading display status\n"); + printk(ASUS_WARNING "Error reading display status\n"); } value &= 0x0F; /* needed for some models, shouldn't hurt others */ @@ -696,7 +689,7 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr, static void set_light_sens_switch(int value) { if (write_acpi_int(ls_switch_handle, NULL, value, NULL)) - pr_warning("Error setting light sensor switch\n"); + printk(ASUS_WARNING "Error setting light sensor switch\n"); hotk->light_switch = value; } @@ -721,7 +714,7 @@ static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, static void set_light_sens_level(int value) { if (write_acpi_int(ls_level_handle, NULL, value, NULL)) - pr_warning("Error setting light sensor level\n"); + printk(ASUS_WARNING "Error setting light sensor level\n"); hotk->light_level = value; } @@ -819,7 +812,7 @@ static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode) return -EINVAL; } -static void asus_hotk_notify(struct acpi_device *device, u32 event) +static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) { static struct key_entry *key; u16 count; @@ -982,11 +975,11 @@ static int asus_hotk_get_info(void) */ status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); if (ACPI_FAILURE(status)) - pr_warning("Couldn't get the DSDT table header\n"); + printk(ASUS_WARNING "Couldn't get the DSDT table header\n"); /* We have to write 0 on init this far for all ASUS models */ if (write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { - pr_err("Hotkey initialization failed\n"); + printk(ASUS_ERR "Hotkey initialization failed\n"); return -ENODEV; } @@ -994,9 +987,9 @@ static int asus_hotk_get_info(void) status = acpi_evaluate_integer(hotk->handle, "BSTS", NULL, &bsts_result); if (ACPI_FAILURE(status)) - pr_warning("Error calling BSTS\n"); + printk(ASUS_WARNING "Error calling BSTS\n"); else if (bsts_result) - pr_notice("BSTS called, 0x%02x returned\n", + printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n", (uint) bsts_result); /* This too ... */ @@ -1027,7 +1020,7 @@ static int asus_hotk_get_info(void) return -ENOMEM; if (*string) - pr_notice(" %s model detected\n", string); + printk(ASUS_NOTICE " %s model detected\n", string); ASUS_HANDLE_INIT(mled_set); ASUS_HANDLE_INIT(tled_set); @@ -1084,7 +1077,7 @@ static int asus_input_init(void) hotk->inputdev = input_allocate_device(); if (!hotk->inputdev) { - pr_info("Unable to allocate input device\n"); + printk(ASUS_INFO "Unable to allocate input device\n"); return 0; } hotk->inputdev->name = "Asus Laptop extra buttons"; @@ -1103,7 +1096,7 @@ static int asus_input_init(void) } result = input_register_device(hotk->inputdev); if (result) { - pr_info("Unable to register input device\n"); + printk(ASUS_INFO "Unable to register input device\n"); input_free_device(hotk->inputdev); } return result; @@ -1120,7 +1113,7 @@ static int asus_hotk_check(void) if (hotk->device->status.present) { result = asus_hotk_get_info(); } else { - pr_err("Hotkey device not present, aborting\n"); + printk(ASUS_ERR "Hotkey device not present, aborting\n"); return -EINVAL; } @@ -1131,12 +1124,13 @@ static int asus_hotk_found; static int asus_hotk_add(struct acpi_device *device) { + acpi_status status = AE_OK; int result; if (!device) return -EINVAL; - pr_notice("Asus Laptop Support version %s\n", + printk(ASUS_NOTICE "Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); @@ -1155,6 +1149,15 @@ static int asus_hotk_add(struct acpi_device *device) asus_hotk_add_fs(); + /* + * We install the handler, it will receive the hotk in parameter, so, we + * could add other data to the hotk struct + */ + status = acpi_install_notify_handler(hotk->handle, ACPI_ALL_NOTIFY, + asus_hotk_notify, hotk); + if (ACPI_FAILURE(status)) + printk(ASUS_ERR "Error installing notify handler\n"); + asus_hotk_found = 1; /* WLED and BLED are on by default */ @@ -1195,9 +1198,16 @@ static int asus_hotk_add(struct acpi_device *device) static int asus_hotk_remove(struct acpi_device *device, int type) { + acpi_status status = 0; + if (!device || !acpi_driver_data(device)) return -EINVAL; + status = acpi_remove_notify_handler(hotk->handle, ACPI_ALL_NOTIFY, + asus_hotk_notify); + if (ACPI_FAILURE(status)) + printk(ASUS_ERR "Error removing notify handler\n"); + kfree(hotk->name); kfree(hotk); @@ -1250,7 +1260,8 @@ static int asus_backlight_init(struct device *dev) bd = backlight_device_register(ASUS_HOTK_FILE, dev, NULL, &asusbl_ops); if (IS_ERR(bd)) { - pr_err("Could not register asus backlight device\n"); + printk(ASUS_ERR + "Could not register asus backlight device\n"); asus_backlight_device = NULL; return PTR_ERR(bd); } @@ -1323,6 +1334,7 @@ static int asus_led_init(struct device *dev) static int __init asus_laptop_init(void) { + struct device *dev; int result; if (acpi_disabled) @@ -1344,10 +1356,24 @@ static int __init asus_laptop_init(void) return -ENODEV; } + dev = acpi_get_physical_device(hotk->device->handle); + + if (!acpi_video_backlight_support()) { + result = asus_backlight_init(dev); + if (result) + goto fail_backlight; + } else + printk(ASUS_INFO "Brightness ignored, must be controlled by " + "ACPI video driver\n"); + result = asus_input_init(); if (result) goto fail_input; + result = asus_led_init(dev); + if (result) + goto fail_led; + /* Register platform stuff */ result = platform_driver_register(&asuspf_driver); if (result) @@ -1368,27 +1394,8 @@ static int __init asus_laptop_init(void) if (result) goto fail_sysfs; - result = asus_led_init(&asuspf_device->dev); - if (result) - goto fail_led; - - if (!acpi_video_backlight_support()) { - result = asus_backlight_init(&asuspf_device->dev); - if (result) - goto fail_backlight; - } else - pr_info("Brightness ignored, must be controlled by " - "ACPI video driver\n"); - return 0; -fail_backlight: - asus_led_exit(); - -fail_led: - sysfs_remove_group(&asuspf_device->dev.kobj, - &asuspf_attribute_group); - fail_sysfs: platform_device_del(asuspf_device); @@ -1399,9 +1406,15 @@ static int __init asus_laptop_init(void) platform_driver_unregister(&asuspf_driver); fail_platform_driver: + asus_led_exit(); + +fail_led: asus_input_exit(); fail_input: + asus_backlight_exit(); + +fail_backlight: return result; } diff --git a/trunk/drivers/platform/x86/asus_acpi.c b/trunk/drivers/platform/x86/asus_acpi.c index ddf5240ade8c..ba1f7497e4b9 100644 --- a/trunk/drivers/platform/x86/asus_acpi.c +++ b/trunk/drivers/platform/x86/asus_acpi.c @@ -455,8 +455,6 @@ static struct asus_hotk *hotk; */ static int asus_hotk_add(struct acpi_device *device); static int asus_hotk_remove(struct acpi_device *device, int type); -static void asus_hotk_notify(struct acpi_device *device, u32 event); - static const struct acpi_device_id asus_device_ids[] = { {"ATK0100", 0}, {"", 0}, @@ -467,11 +465,9 @@ static struct acpi_driver asus_hotk_driver = { .name = "asus_acpi", .class = ACPI_HOTK_CLASS, .ids = asus_device_ids, - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = asus_hotk_add, .remove = asus_hotk_remove, - .notify = asus_hotk_notify, }, }; @@ -1105,20 +1101,12 @@ static int asus_hotk_remove_fs(struct acpi_device *device) return 0; } -static void asus_hotk_notify(struct acpi_device *device, u32 event) +static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) { /* TODO Find a better way to handle events count. */ if (!hotk) return; - /* - * The BIOS *should* be sending us device events, but apparently - * Asus uses system events instead, so just ignore any device - * events we get. - */ - if (event > ACPI_MAX_SYS_NOTIFY) - return; - if ((event & ~((u32) BR_UP)) < 16) hotk->brightness = (event & ~((u32) BR_UP)); else if ((event & ~((u32) BR_DOWN)) < 16) @@ -1358,6 +1346,15 @@ static int asus_hotk_add(struct acpi_device *device) if (result) goto end; + /* + * We install the handler, it will receive the hotk in parameter, so, we + * could add other data to the hotk struct + */ + status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY, + asus_hotk_notify, hotk); + if (ACPI_FAILURE(status)) + printk(KERN_ERR " Error installing notify handler\n"); + /* For laptops without GPLV: init the hotk->brightness value */ if ((!hotk->methods->brightness_get) && (!hotk->methods->brightness_status) @@ -1392,9 +1389,16 @@ static int asus_hotk_add(struct acpi_device *device) static int asus_hotk_remove(struct acpi_device *device, int type) { + acpi_status status = 0; + if (!device || !acpi_driver_data(device)) return -EINVAL; + status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY, + asus_hotk_notify); + if (ACPI_FAILURE(status)) + printk(KERN_ERR "Asus ACPI: Error removing notify handler\n"); + asus_hotk_remove_fs(device); kfree(hotk); diff --git a/trunk/drivers/platform/x86/dell-wmi.c b/trunk/drivers/platform/x86/dell-wmi.c index 0f900cc9fa7a..2fab94162147 100644 --- a/trunk/drivers/platform/x86/dell-wmi.c +++ b/trunk/drivers/platform/x86/dell-wmi.c @@ -46,53 +46,10 @@ struct key_entry { u16 keycode; }; -enum { KE_KEY, KE_SW, KE_IGNORE, KE_END }; - -/* - * Certain keys are flagged as KE_IGNORE. All of these are either - * notifications (rather than requests for change) or are also sent - * via the keyboard controller so should not be sent again. - */ +enum { KE_KEY, KE_SW, KE_END }; static struct key_entry dell_wmi_keymap[] = { {KE_KEY, 0xe045, KEY_PROG1}, - {KE_KEY, 0xe009, KEY_EJECTCD}, - - /* These also contain the brightness level at offset 6 */ - {KE_KEY, 0xe006, KEY_BRIGHTNESSUP}, - {KE_KEY, 0xe005, KEY_BRIGHTNESSDOWN}, - - /* Battery health status button */ - {KE_KEY, 0xe007, KEY_BATTERY}, - - /* This is actually for all radios. Although physically a - * switch, the notification does not provide an indication of - * state and so it should be reported as a key */ - {KE_KEY, 0xe008, KEY_WLAN}, - - /* The next device is at offset 6, the active devices are at - offset 8 and the attached devices at offset 10 */ - {KE_KEY, 0xe00b, KEY_DISPLAYTOGGLE}, - - {KE_IGNORE, 0xe00c, KEY_KBDILLUMTOGGLE}, - - /* BIOS error detected */ - {KE_IGNORE, 0xe00d, KEY_RESERVED}, - - /* Wifi Catcher */ - {KE_KEY, 0xe011, KEY_PROG2}, - - /* Ambient light sensor toggle */ - {KE_IGNORE, 0xe013, KEY_RESERVED}, - - {KE_IGNORE, 0xe020, KEY_MUTE}, - {KE_IGNORE, 0xe02e, KEY_VOLUMEDOWN}, - {KE_IGNORE, 0xe030, KEY_VOLUMEUP}, - {KE_IGNORE, 0xe033, KEY_KBDILLUMUP}, - {KE_IGNORE, 0xe034, KEY_KBDILLUMDOWN}, - {KE_IGNORE, 0xe03a, KEY_CAPSLOCK}, - {KE_IGNORE, 0xe045, KEY_NUMLOCK}, - {KE_IGNORE, 0xe046, KEY_SCROLLLOCK}, {KE_END, 0} }; @@ -165,20 +122,15 @@ static void dell_wmi_notify(u32 value, void *context) if (obj && obj->type == ACPI_TYPE_BUFFER) { int *buffer = (int *)obj->buffer.pointer; - /* - * The upper bytes of the event may contain - * additional information, so mask them off for the - * scancode lookup - */ - key = dell_wmi_get_entry_by_scancode(buffer[1] & 0xFFFF); + key = dell_wmi_get_entry_by_scancode(buffer[1]); if (key) { input_report_key(dell_wmi_input_dev, key->keycode, 1); input_sync(dell_wmi_input_dev); input_report_key(dell_wmi_input_dev, key->keycode, 0); input_sync(dell_wmi_input_dev); - } else if (buffer[1] & 0xFFFF) + } else printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n", - buffer[1] & 0xFFFF); + buffer[1]); } } diff --git a/trunk/drivers/platform/x86/eeepc-laptop.c b/trunk/drivers/platform/x86/eeepc-laptop.c index ec560f16d720..8153b3e59189 100644 --- a/trunk/drivers/platform/x86/eeepc-laptop.c +++ b/trunk/drivers/platform/x86/eeepc-laptop.c @@ -16,8 +16,6 @@ * GNU General Public License for more details. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -33,7 +31,6 @@ #include #include #include -#include #define EEEPC_LAPTOP_VERSION "0.1" @@ -43,6 +40,11 @@ #define EEEPC_HOTK_DEVICE_NAME "Hotkey" #define EEEPC_HOTK_HID "ASUS010" +#define EEEPC_LOG EEEPC_HOTK_FILE ": " +#define EEEPC_ERR KERN_ERR EEEPC_LOG +#define EEEPC_WARNING KERN_WARNING EEEPC_LOG +#define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG +#define EEEPC_INFO KERN_INFO EEEPC_LOG /* * Definitions for Asus EeePC @@ -60,10 +62,7 @@ enum { DISABLE_ASL_GPS = 0x0020, DISABLE_ASL_DISPLAYSWITCH = 0x0040, DISABLE_ASL_MODEM = 0x0080, - DISABLE_ASL_CARDREADER = 0x0100, - DISABLE_ASL_3G = 0x0200, - DISABLE_ASL_WIMAX = 0x0400, - DISABLE_ASL_HWCF = 0x0800 + DISABLE_ASL_CARDREADER = 0x0100 }; enum { @@ -88,13 +87,7 @@ enum { CM_ASL_USBPORT3, CM_ASL_MODEM, CM_ASL_CARDREADER, - CM_ASL_3G, - CM_ASL_WIMAX, - CM_ASL_HWCF, - CM_ASL_LID, - CM_ASL_TYPE, - CM_ASL_PANELPOWER, /*P901*/ - CM_ASL_TPD + CM_ASL_LID }; static const char *cm_getv[] = { @@ -103,8 +96,7 @@ static const char *cm_getv[] = { NULL, "PBLG", NULL, NULL, "CFVG", NULL, NULL, NULL, "USBG", NULL, NULL, "MODG", - "CRDG", "M3GG", "WIMG", "HWCF", - "LIDG", "TYPE", "PBPG", "TPDG" + "CRDG", "LIDG" }; static const char *cm_setv[] = { @@ -113,8 +105,7 @@ static const char *cm_setv[] = { "SDSP", "PBLS", "HDPS", NULL, "CFVS", NULL, NULL, NULL, "USBG", NULL, NULL, "MODS", - "CRDS", "M3GS", "WIMS", NULL, - NULL, NULL, "PBPS", "TPDS" + "CRDS", NULL }; #define EEEPC_EC "\\_SB.PCI0.SBRG.EC0." @@ -139,10 +130,8 @@ struct eeepc_hotk { u16 event_count[128]; /* count for each event */ struct input_dev *inputdev; u16 *keycode_map; - struct rfkill *wlan_rfkill; - struct rfkill *bluetooth_rfkill; - struct rfkill *wwan3g_rfkill; - struct hotplug_slot *hotplug_slot; + struct rfkill *eeepc_wlan_rfkill; + struct rfkill *eeepc_bluetooth_rfkill; }; /* The actual device the driver binds to */ @@ -192,7 +181,6 @@ static struct key_entry eeepc_keymap[] = { static int eeepc_hotk_add(struct acpi_device *device); static int eeepc_hotk_remove(struct acpi_device *device, int type); static int eeepc_hotk_resume(struct acpi_device *device); -static void eeepc_hotk_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id eeepc_device_ids[] = { {EEEPC_HOTK_HID, 0}, @@ -204,24 +192,13 @@ static struct acpi_driver eeepc_hotk_driver = { .name = EEEPC_HOTK_NAME, .class = EEEPC_HOTK_CLASS, .ids = eeepc_device_ids, - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { .add = eeepc_hotk_add, .remove = eeepc_hotk_remove, .resume = eeepc_hotk_resume, - .notify = eeepc_hotk_notify, }, }; -/* PCI hotplug ops */ -static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value); - -static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { - .owner = THIS_MODULE, - .get_adapter_status = eeepc_get_adapter_status, - .get_power_status = eeepc_get_adapter_status, -}; - /* The backlight device /sys/class/backlight */ static struct backlight_device *eeepc_backlight_device; @@ -283,20 +260,20 @@ static int set_acpi(int cm, int value) if (method == NULL) return -ENODEV; if (write_acpi_int(ehotk->handle, method, value, NULL)) - pr_warning("Error writing %s\n", method); + printk(EEEPC_WARNING "Error writing %s\n", method); } return 0; } static int get_acpi(int cm) { - int value = -ENODEV; + int value = -1; if ((ehotk->cm_supported & (0x1 << cm))) { const char *method = cm_getv[cm]; if (method == NULL) return -ENODEV; if (read_acpi_int(ehotk->handle, method, &value)) - pr_warning("Error reading %s\n", method); + printk(EEEPC_WARNING "Error reading %s\n", method); } return value; } @@ -341,15 +318,6 @@ static const struct rfkill_ops eeepc_rfkill_ops = { .set_block = eeepc_rfkill_set, }; -static void __init eeepc_enable_camera(void) -{ - /* - * If the following call to set_acpi() fails, it's because there's no - * camera so we can ignore the error. - */ - set_acpi(CM_ASL_CAMERA, 1); -} - /* * Sys helpers */ @@ -368,19 +336,13 @@ static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) rv = parse_arg(buf, count, &value); if (rv > 0) - value = set_acpi(cm, value); - if (value < 0) - return value; + set_acpi(cm, value); return rv; } static ssize_t show_sys_acpi(int cm, char *buf) { - int value = get_acpi(cm); - - if (value < 0) - return value; - return sprintf(buf, "%d\n", value); + return sprintf(buf, "%d\n", get_acpi(cm)); } #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ @@ -407,88 +369,13 @@ static ssize_t show_sys_acpi(int cm, char *buf) EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); - -struct eeepc_cpufv { - int num; - int cur; -}; - -static int get_cpufv(struct eeepc_cpufv *c) -{ - c->cur = get_acpi(CM_ASL_CPUFV); - c->num = (c->cur >> 8) & 0xff; - c->cur &= 0xff; - if (c->cur < 0 || c->num <= 0 || c->num > 12) - return -ENODEV; - return 0; -} - -static ssize_t show_available_cpufv(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct eeepc_cpufv c; - int i; - ssize_t len = 0; - - if (get_cpufv(&c)) - return -ENODEV; - for (i = 0; i < c.num; i++) - len += sprintf(buf + len, "%d ", i); - len += sprintf(buf + len, "\n"); - return len; -} - -static ssize_t show_cpufv(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct eeepc_cpufv c; - - if (get_cpufv(&c)) - return -ENODEV; - return sprintf(buf, "%#x\n", (c.num << 8) | c.cur); -} - -static ssize_t store_cpufv(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct eeepc_cpufv c; - int rv, value; - - if (get_cpufv(&c)) - return -ENODEV; - rv = parse_arg(buf, count, &value); - if (rv < 0) - return rv; - if (!rv || value < 0 || value >= c.num) - return -EINVAL; - set_acpi(CM_ASL_CPUFV, value); - return rv; -} - -static struct device_attribute dev_attr_cpufv = { - .attr = { - .name = "cpufv", - .mode = 0644 }, - .show = show_cpufv, - .store = store_cpufv -}; - -static struct device_attribute dev_attr_available_cpufv = { - .attr = { - .name = "available_cpufv", - .mode = 0444 }, - .show = show_available_cpufv -}; +EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV); static struct attribute *platform_attributes[] = { &dev_attr_camera.attr, &dev_attr_cardr.attr, &dev_attr_disp.attr, &dev_attr_cpufv.attr, - &dev_attr_available_cpufv.attr, NULL }; @@ -554,28 +441,6 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) return -EINVAL; } -static void cmsg_quirk(int cm, const char *name) -{ - int dummy; - - /* Some BIOSes do not report cm although it is avaliable. - Check if cm_getv[cm] works and, if yes, assume cm should be set. */ - if (!(ehotk->cm_supported & (1 << cm)) - && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) { - pr_info("%s (%x) not reported by BIOS," - " enabling anyway\n", name, 1 << cm); - ehotk->cm_supported |= 1 << cm; - } -} - -static void cmsg_quirks(void) -{ - cmsg_quirk(CM_ASL_LID, "LID"); - cmsg_quirk(CM_ASL_TYPE, "TYPE"); - cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER"); - cmsg_quirk(CM_ASL_TPD, "TPD"); -} - static int eeepc_hotk_check(void) { const struct key_entry *key; @@ -588,24 +453,26 @@ static int eeepc_hotk_check(void) if (ehotk->device->status.present) { if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, &buffer)) { - pr_err("Hotkey initialization failed\n"); + printk(EEEPC_ERR "Hotkey initialization failed\n"); return -ENODEV; } else { - pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag); + printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", + ehotk->init_flag); } /* get control methods supported */ if (read_acpi_int(ehotk->handle, "CMSG" , &ehotk->cm_supported)) { - pr_err("Get control methods supported failed\n"); + printk(EEEPC_ERR + "Get control methods supported failed\n"); return -ENODEV; } else { - cmsg_quirks(); - pr_info("Get control methods supported: 0x%x\n", - ehotk->cm_supported); + printk(EEEPC_INFO + "Get control methods supported: 0x%x\n", + ehotk->cm_supported); } ehotk->inputdev = input_allocate_device(); if (!ehotk->inputdev) { - pr_info("Unable to allocate input device\n"); + printk(EEEPC_INFO "Unable to allocate input device\n"); return 0; } ehotk->inputdev->name = "Asus EeePC extra buttons"; @@ -624,12 +491,12 @@ static int eeepc_hotk_check(void) } result = input_register_device(ehotk->inputdev); if (result) { - pr_info("Unable to register input device\n"); + printk(EEEPC_INFO "Unable to register input device\n"); input_free_device(ehotk->inputdev); return 0; } } else { - pr_err("Hotkey device not present, aborting\n"); + printk(EEEPC_ERR "Hotkey device not present, aborting\n"); return -EINVAL; } return 0; @@ -647,19 +514,6 @@ static int notify_brn(void) return -1; } -static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, - u8 *value) -{ - int val = get_acpi(CM_ASL_WLAN); - - if (val == 1 || val == 0) - *value = val; - else - return -EINVAL; - - return 0; -} - static void eeepc_rfkill_hotplug(void) { struct pci_dev *dev; @@ -667,7 +521,7 @@ static void eeepc_rfkill_hotplug(void) bool blocked; if (!bus) { - pr_warning("Unable to find PCI bus 1?\n"); + printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); return; } @@ -683,7 +537,7 @@ static void eeepc_rfkill_hotplug(void) if (dev) { pci_bus_assign_resources(bus); if (pci_bus_add_device(dev)) - pr_err("Unable to hotplug wifi\n"); + printk(EEEPC_ERR "Unable to hotplug wifi\n"); } } else { dev = pci_get_slot(bus, 0); @@ -693,7 +547,7 @@ static void eeepc_rfkill_hotplug(void) } } - rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); + rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); } static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) @@ -704,7 +558,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) eeepc_rfkill_hotplug(); } -static void eeepc_hotk_notify(struct acpi_device *device, u32 event) +static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) { static struct key_entry *key; u16 count; @@ -712,8 +566,6 @@ static void eeepc_hotk_notify(struct acpi_device *device, u32 event) if (!ehotk) return; - if (event > ACPI_MAX_SYS_NOTIFY) - return; if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) brn = notify_brn(); count = ehotk->event_count[event % 128]++; @@ -766,7 +618,8 @@ static int eeepc_register_rfkill_notifier(char *node) eeepc_rfkill_notify, NULL); if (ACPI_FAILURE(status)) - pr_warning("Failed to register notify on %s\n", node); + printk(EEEPC_WARNING + "Failed to register notify on %s\n", node); } else return -ENODEV; @@ -785,66 +638,20 @@ static void eeepc_unregister_rfkill_notifier(char *node) ACPI_SYSTEM_NOTIFY, eeepc_rfkill_notify); if (ACPI_FAILURE(status)) - pr_err("Error removing rfkill notify handler %s\n", + printk(EEEPC_ERR + "Error removing rfkill notify handler %s\n", node); } } -static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) -{ - kfree(hotplug_slot->info); - kfree(hotplug_slot); -} - -static int eeepc_setup_pci_hotplug(void) -{ - int ret = -ENOMEM; - struct pci_bus *bus = pci_find_bus(0, 1); - - if (!bus) { - pr_err("Unable to find wifi PCI bus\n"); - return -ENODEV; - } - - ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); - if (!ehotk->hotplug_slot) - goto error_slot; - - ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), - GFP_KERNEL); - if (!ehotk->hotplug_slot->info) - goto error_info; - - ehotk->hotplug_slot->private = ehotk; - ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug; - ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops; - eeepc_get_adapter_status(ehotk->hotplug_slot, - &ehotk->hotplug_slot->info->adapter_status); - - ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi"); - if (ret) { - pr_err("Unable to register hotplug slot - %d\n", ret); - goto error_register; - } - - return 0; - -error_register: - kfree(ehotk->hotplug_slot->info); -error_info: - kfree(ehotk->hotplug_slot); - ehotk->hotplug_slot = NULL; -error_slot: - return ret; -} - static int eeepc_hotk_add(struct acpi_device *device) { + acpi_status status = AE_OK; int result; if (!device) return -EINVAL; - pr_notice(EEEPC_HOTK_NAME "\n"); + printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); if (!ehotk) return -ENOMEM; @@ -857,9 +664,58 @@ static int eeepc_hotk_add(struct acpi_device *device) result = eeepc_hotk_check(); if (result) goto ehotk_fail; + status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, + eeepc_hotk_notify, ehotk); + if (ACPI_FAILURE(status)) + printk(EEEPC_ERR "Error installing notify handler\n"); + + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); + + if (get_acpi(CM_ASL_WLAN) != -1) { + ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan", + &device->dev, + RFKILL_TYPE_WLAN, + &eeepc_rfkill_ops, + (void *)CM_ASL_WLAN); + + if (!ehotk->eeepc_wlan_rfkill) + goto wlan_fail; + + rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill, + get_acpi(CM_ASL_WLAN) != 1); + result = rfkill_register(ehotk->eeepc_wlan_rfkill); + if (result) + goto wlan_fail; + } + + if (get_acpi(CM_ASL_BLUETOOTH) != -1) { + ehotk->eeepc_bluetooth_rfkill = + rfkill_alloc("eeepc-bluetooth", + &device->dev, + RFKILL_TYPE_BLUETOOTH, + &eeepc_rfkill_ops, + (void *)CM_ASL_BLUETOOTH); + + if (!ehotk->eeepc_bluetooth_rfkill) + goto bluetooth_fail; + + rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill, + get_acpi(CM_ASL_BLUETOOTH) != 1); + result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); + if (result) + goto bluetooth_fail; + } return 0; + bluetooth_fail: + rfkill_destroy(ehotk->eeepc_bluetooth_rfkill); + rfkill_unregister(ehotk->eeepc_wlan_rfkill); + wlan_fail: + rfkill_destroy(ehotk->eeepc_wlan_rfkill); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); ehotk_fail: kfree(ehotk); ehotk = NULL; @@ -869,8 +725,17 @@ static int eeepc_hotk_add(struct acpi_device *device) static int eeepc_hotk_remove(struct acpi_device *device, int type) { + acpi_status status = 0; + if (!device || !acpi_driver_data(device)) return -EINVAL; + status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, + eeepc_hotk_notify); + if (ACPI_FAILURE(status)) + printk(EEEPC_ERR "Error removing notify handler\n"); + + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); kfree(ehotk); return 0; @@ -878,7 +743,7 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) static int eeepc_hotk_resume(struct acpi_device *device) { - if (ehotk->wlan_rfkill) { + if (ehotk->eeepc_wlan_rfkill) { bool wlan; /* Workaround - it seems that _PTS disables the wireless @@ -890,13 +755,14 @@ static int eeepc_hotk_resume(struct acpi_device *device) wlan = get_acpi(CM_ASL_WLAN); set_acpi(CM_ASL_WLAN, wlan); - rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); + rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, + wlan != 1); eeepc_rfkill_hotplug(); } - if (ehotk->bluetooth_rfkill) - rfkill_set_sw_state(ehotk->bluetooth_rfkill, + if (ehotk->eeepc_bluetooth_rfkill) + rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, get_acpi(CM_ASL_BLUETOOTH) != 1); return 0; @@ -1018,16 +884,10 @@ static void eeepc_backlight_exit(void) static void eeepc_rfkill_exit(void) { - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); - if (ehotk->wlan_rfkill) - rfkill_unregister(ehotk->wlan_rfkill); - if (ehotk->bluetooth_rfkill) - rfkill_unregister(ehotk->bluetooth_rfkill); - if (ehotk->wwan3g_rfkill) - rfkill_unregister(ehotk->wwan3g_rfkill); - if (ehotk->hotplug_slot) - pci_hp_deregister(ehotk->hotplug_slot); + if (ehotk->eeepc_wlan_rfkill) + rfkill_unregister(ehotk->eeepc_wlan_rfkill); + if (ehotk->eeepc_bluetooth_rfkill) + rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); } static void eeepc_input_exit(void) @@ -1062,75 +922,6 @@ static void __exit eeepc_laptop_exit(void) platform_driver_unregister(&platform_driver); } -static int eeepc_new_rfkill(struct rfkill **rfkill, - const char *name, struct device *dev, - enum rfkill_type type, int cm) -{ - int result; - - result = get_acpi(cm); - if (result < 0) - return result; - - *rfkill = rfkill_alloc(name, dev, type, - &eeepc_rfkill_ops, (void *)(unsigned long)cm); - - if (!*rfkill) - return -EINVAL; - - rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); - result = rfkill_register(*rfkill); - if (result) { - rfkill_destroy(*rfkill); - *rfkill = NULL; - return result; - } - return 0; -} - - -static int eeepc_rfkill_init(struct device *dev) -{ - int result = 0; - - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); - - result = eeepc_new_rfkill(&ehotk->wlan_rfkill, - "eeepc-wlan", dev, - RFKILL_TYPE_WLAN, CM_ASL_WLAN); - - if (result && result != -ENODEV) - goto exit; - - result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, - "eeepc-bluetooth", dev, - RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); - - if (result && result != -ENODEV) - goto exit; - - result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill, - "eeepc-wwan3g", dev, - RFKILL_TYPE_WWAN, CM_ASL_3G); - - if (result && result != -ENODEV) - goto exit; - - result = eeepc_setup_pci_hotplug(); - /* - * If we get -EBUSY then something else is handling the PCI hotplug - - * don't fail in this case - */ - if (result == -EBUSY) - result = 0; - -exit: - if (result && result != -ENODEV) - eeepc_rfkill_exit(); - return result; -} - static int eeepc_backlight_init(struct device *dev) { struct backlight_device *bd; @@ -1138,7 +929,8 @@ static int eeepc_backlight_init(struct device *dev) bd = backlight_device_register(EEEPC_HOTK_FILE, dev, NULL, &eeepcbl_ops); if (IS_ERR(bd)) { - pr_err("Could not register eeepc backlight device\n"); + printk(EEEPC_ERR + "Could not register eeepc backlight device\n"); eeepc_backlight_device = NULL; return PTR_ERR(bd); } @@ -1157,7 +949,8 @@ static int eeepc_hwmon_init(struct device *dev) hwmon = hwmon_device_register(dev); if (IS_ERR(hwmon)) { - pr_err("Could not register eeepc hwmon device\n"); + printk(EEEPC_ERR + "Could not register eeepc hwmon device\n"); eeepc_hwmon_device = NULL; return PTR_ERR(hwmon); } @@ -1183,9 +976,19 @@ static int __init eeepc_laptop_init(void) acpi_bus_unregister_driver(&eeepc_hotk_driver); return -ENODEV; } + dev = acpi_get_physical_device(ehotk->device->handle); - eeepc_enable_camera(); + if (!acpi_video_backlight_support()) { + result = eeepc_backlight_init(dev); + if (result) + goto fail_backlight; + } else + printk(EEEPC_INFO "Backlight controlled by ACPI video " + "driver\n"); + result = eeepc_hwmon_init(dev); + if (result) + goto fail_hwmon; /* Register platform stuff */ result = platform_driver_register(&platform_driver); if (result) @@ -1202,33 +1005,7 @@ static int __init eeepc_laptop_init(void) &platform_attribute_group); if (result) goto fail_sysfs; - - dev = &platform_device->dev; - - if (!acpi_video_backlight_support()) { - result = eeepc_backlight_init(dev); - if (result) - goto fail_backlight; - } else - pr_info("Backlight controlled by ACPI video " - "driver\n"); - - result = eeepc_hwmon_init(dev); - if (result) - goto fail_hwmon; - - result = eeepc_rfkill_init(dev); - if (result) - goto fail_rfkill; - return 0; -fail_rfkill: - eeepc_hwmon_exit(); -fail_hwmon: - eeepc_backlight_exit(); -fail_backlight: - sysfs_remove_group(&platform_device->dev.kobj, - &platform_attribute_group); fail_sysfs: platform_device_del(platform_device); fail_platform_device2: @@ -1236,7 +1013,12 @@ static int __init eeepc_laptop_init(void) fail_platform_device1: platform_driver_unregister(&platform_driver); fail_platform_driver: + eeepc_hwmon_exit(); +fail_hwmon: + eeepc_backlight_exit(); +fail_backlight: eeepc_input_exit(); + eeepc_rfkill_exit(); return result; } diff --git a/trunk/drivers/platform/x86/hp-wmi.c b/trunk/drivers/platform/x86/hp-wmi.c index 4ac2311c00af..16fffe44e333 100644 --- a/trunk/drivers/platform/x86/hp-wmi.c +++ b/trunk/drivers/platform/x86/hp-wmi.c @@ -47,7 +47,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); #define HPWMI_DISPLAY_QUERY 0x1 #define HPWMI_HDDTEMP_QUERY 0x2 #define HPWMI_ALS_QUERY 0x3 -#define HPWMI_HARDWARE_QUERY 0x4 +#define HPWMI_DOCK_QUERY 0x4 #define HPWMI_WIRELESS_QUERY 0x5 #define HPWMI_HOTKEY_QUERY 0xc @@ -75,9 +75,10 @@ struct key_entry { u16 keycode; }; -enum { KE_KEY, KE_END }; +enum { KE_KEY, KE_SW, KE_END }; static struct key_entry hp_wmi_keymap[] = { + {KE_SW, 0x01, SW_DOCK}, {KE_KEY, 0x02, KEY_BRIGHTNESSUP}, {KE_KEY, 0x03, KEY_BRIGHTNESSDOWN}, {KE_KEY, 0x20e6, KEY_PROG1}, @@ -150,22 +151,7 @@ static int hp_wmi_als_state(void) static int hp_wmi_dock_state(void) { - int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, 0); - - if (ret < 0) - return ret; - - return ret & 0x1; -} - -static int hp_wmi_tablet_state(void) -{ - int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, 0); - - if (ret < 0) - return ret; - - return (ret & 0x4) ? 1 : 0; + return hp_wmi_perform_query(HPWMI_DOCK_QUERY, 0, 0); } static int hp_wmi_set_block(void *data, bool blocked) @@ -246,15 +232,6 @@ static ssize_t show_dock(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%d\n", value); } -static ssize_t show_tablet(struct device *dev, struct device_attribute *attr, - char *buf) -{ - int value = hp_wmi_tablet_state(); - if (value < 0) - return -EINVAL; - return sprintf(buf, "%d\n", value); -} - static ssize_t set_als(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -267,7 +244,6 @@ static DEVICE_ATTR(display, S_IRUGO, show_display, NULL); static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL); static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als); static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); -static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL); static struct key_entry *hp_wmi_get_entry_by_scancode(int code) { @@ -350,13 +326,13 @@ static void hp_wmi_notify(u32 value, void *context) key->keycode, 0); input_sync(hp_wmi_input_dev); break; + case KE_SW: + input_report_switch(hp_wmi_input_dev, + key->keycode, + hp_wmi_dock_state()); + input_sync(hp_wmi_input_dev); + break; } - } else if (eventcode == 0x1) { - input_report_switch(hp_wmi_input_dev, SW_DOCK, - hp_wmi_dock_state()); - input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, - hp_wmi_tablet_state()); - input_sync(hp_wmi_input_dev); } else if (eventcode == 0x5) { if (wifi_rfkill) rfkill_set_sw_state(wifi_rfkill, @@ -393,19 +369,18 @@ static int __init hp_wmi_input_setup(void) set_bit(EV_KEY, hp_wmi_input_dev->evbit); set_bit(key->keycode, hp_wmi_input_dev->keybit); break; + case KE_SW: + set_bit(EV_SW, hp_wmi_input_dev->evbit); + set_bit(key->keycode, hp_wmi_input_dev->swbit); + + /* Set initial dock state */ + input_report_switch(hp_wmi_input_dev, key->keycode, + hp_wmi_dock_state()); + input_sync(hp_wmi_input_dev); + break; } } - set_bit(EV_SW, hp_wmi_input_dev->evbit); - set_bit(SW_DOCK, hp_wmi_input_dev->swbit); - set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit); - - /* Set initial hardware state */ - input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state()); - input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, - hp_wmi_tablet_state()); - input_sync(hp_wmi_input_dev); - err = input_register_device(hp_wmi_input_dev); if (err) { @@ -422,7 +397,6 @@ static void cleanup_sysfs(struct platform_device *device) device_remove_file(&device->dev, &dev_attr_hddtemp); device_remove_file(&device->dev, &dev_attr_als); device_remove_file(&device->dev, &dev_attr_dock); - device_remove_file(&device->dev, &dev_attr_tablet); } static int __init hp_wmi_bios_setup(struct platform_device *device) @@ -440,9 +414,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) if (err) goto add_sysfs_error; err = device_create_file(&device->dev, &dev_attr_dock); - if (err) - goto add_sysfs_error; - err = device_create_file(&device->dev, &dev_attr_tablet); if (err) goto add_sysfs_error; @@ -514,17 +485,23 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device) static int hp_wmi_resume_handler(struct platform_device *device) { + struct key_entry *key; + /* - * Hardware state may have changed while suspended, so trigger - * input events for the current state. As this is a switch, + * Docking state may have changed while suspended, so trigger + * an input event for the current state. As this is a switch, * the input layer will only actually pass it on if the state * changed. */ - - input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state()); - input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, - hp_wmi_tablet_state()); - input_sync(hp_wmi_input_dev); + for (key = hp_wmi_keymap; key->type != KE_END; key++) { + switch (key->type) { + case KE_SW: + input_report_switch(hp_wmi_input_dev, key->keycode, + hp_wmi_dock_state()); + input_sync(hp_wmi_input_dev); + break; + } + } return 0; } diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index a463fd72c495..40d64c03278c 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -22,7 +22,7 @@ */ #define TPACPI_VERSION "0.23" -#define TPACPI_SYSFS_VERSION 0x020400 +#define TPACPI_SYSFS_VERSION 0x020300 /* * Changelog: @@ -257,8 +257,6 @@ static struct { u32 wan:1; u32 uwb:1; u32 fan_ctrl_status_undef:1; - u32 second_fan:1; - u32 beep_needs_two_args:1; u32 input_device_registered:1; u32 platform_drv_registered:1; u32 platform_drv_attrs_registered:1; @@ -279,10 +277,8 @@ struct thinkpad_id_data { char *bios_version_str; /* Something like 1ZET51WW (1.03z) */ char *ec_version_str; /* Something like 1ZHT51WW-1.04a */ - u16 bios_model; /* 1Y = 0x5931, 0 = unknown */ + u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ u16 ec_model; - u16 bios_release; /* 1ZETK1WW = 0x314b, 0 = unknown */ - u16 ec_release; char *model_str; /* ThinkPad T43 */ char *nummodel_str; /* 9384A9C for a 9384-A9C model */ @@ -359,73 +355,6 @@ static void tpacpi_log_usertask(const char * const what) } \ } while (0) -/* - * Quirk handling helpers - * - * ThinkPad IDs and versions seen in the field so far - * are two-characters from the set [0-9A-Z], i.e. base 36. - * - * We use values well outside that range as specials. - */ - -#define TPACPI_MATCH_ANY 0xffffU -#define TPACPI_MATCH_UNKNOWN 0U - -/* TPID('1', 'Y') == 0x5931 */ -#define TPID(__c1, __c2) (((__c2) << 8) | (__c1)) - -#define TPACPI_Q_IBM(__id1, __id2, __quirk) \ - { .vendor = PCI_VENDOR_ID_IBM, \ - .bios = TPID(__id1, __id2), \ - .ec = TPACPI_MATCH_ANY, \ - .quirks = (__quirk) } - -#define TPACPI_Q_LNV(__id1, __id2, __quirk) \ - { .vendor = PCI_VENDOR_ID_LENOVO, \ - .bios = TPID(__id1, __id2), \ - .ec = TPACPI_MATCH_ANY, \ - .quirks = (__quirk) } - -struct tpacpi_quirk { - unsigned int vendor; - u16 bios; - u16 ec; - unsigned long quirks; -}; - -/** - * tpacpi_check_quirks() - search BIOS/EC version on a list - * @qlist: array of &struct tpacpi_quirk - * @qlist_size: number of elements in @qlist - * - * Iterates over a quirks list until one is found that matches the - * ThinkPad's vendor, BIOS and EC model. - * - * Returns 0 if nothing matches, otherwise returns the quirks field of - * the matching &struct tpacpi_quirk entry. - * - * The match criteria is: vendor, ec and bios much match. - */ -static unsigned long __init tpacpi_check_quirks( - const struct tpacpi_quirk *qlist, - unsigned int qlist_size) -{ - while (qlist_size) { - if ((qlist->vendor == thinkpad_id.vendor || - qlist->vendor == TPACPI_MATCH_ANY) && - (qlist->bios == thinkpad_id.bios_model || - qlist->bios == TPACPI_MATCH_ANY) && - (qlist->ec == thinkpad_id.ec_model || - qlist->ec == TPACPI_MATCH_ANY)) - return qlist->quirks; - - qlist_size--; - qlist++; - } - return 0; -} - - /**************************************************************************** **************************************************************************** * @@ -2951,7 +2880,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) /* update bright_acpimode... */ tpacpi_check_std_acpi_brightness_support(); - if (tp_features.bright_acpimode && acpi_video_backlight_support()) { + if (tp_features.bright_acpimode) { printk(TPACPI_INFO "This ThinkPad has standard ACPI backlight " "brightness control, supported by the ACPI " @@ -4844,7 +4773,7 @@ TPACPI_HANDLE(led, ec, "SLED", /* 570 */ "LED", /* all others */ ); /* R30, R31 */ -#define TPACPI_LED_NUMLEDS 16 +#define TPACPI_LED_NUMLEDS 8 static struct tpacpi_led_classdev *tpacpi_leds; static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS]; static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { @@ -4857,20 +4786,15 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { "tpacpi::dock_batt", "tpacpi::unknown_led", "tpacpi::standby", - "tpacpi::dock_status1", - "tpacpi::dock_status2", - "tpacpi::unknown_led2", - "tpacpi::unknown_led3", - "tpacpi::thinkvantage", }; -#define TPACPI_SAFE_LEDS 0x1081U +#define TPACPI_SAFE_LEDS 0x0081U static inline bool tpacpi_is_led_restricted(const unsigned int led) { #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS return false; #else - return (1U & (TPACPI_SAFE_LEDS >> led)) == 0; + return (TPACPI_SAFE_LEDS & (1 << led)) == 0; #endif } @@ -5032,10 +4956,6 @@ static int __init tpacpi_init_led(unsigned int led) tpacpi_leds[led].led = led; - /* LEDs with no name don't get registered */ - if (!tpacpi_led_names[led]) - return 0; - tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set; tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set; if (led_supported == TPACPI_LED_570) @@ -5054,59 +4974,10 @@ static int __init tpacpi_init_led(unsigned int led) return rc; } -static const struct tpacpi_quirk led_useful_qtable[] __initconst = { - TPACPI_Q_IBM('1', 'E', 0x009f), /* A30 */ - TPACPI_Q_IBM('1', 'N', 0x009f), /* A31 */ - TPACPI_Q_IBM('1', 'G', 0x009f), /* A31 */ - - TPACPI_Q_IBM('1', 'I', 0x0097), /* T30 */ - TPACPI_Q_IBM('1', 'R', 0x0097), /* T40, T41, T42, R50, R51 */ - TPACPI_Q_IBM('7', '0', 0x0097), /* T43, R52 */ - TPACPI_Q_IBM('1', 'Y', 0x0097), /* T43 */ - TPACPI_Q_IBM('1', 'W', 0x0097), /* R50e */ - TPACPI_Q_IBM('1', 'V', 0x0097), /* R51 */ - TPACPI_Q_IBM('7', '8', 0x0097), /* R51e */ - TPACPI_Q_IBM('7', '6', 0x0097), /* R52 */ - - TPACPI_Q_IBM('1', 'K', 0x00bf), /* X30 */ - TPACPI_Q_IBM('1', 'Q', 0x00bf), /* X31, X32 */ - TPACPI_Q_IBM('1', 'U', 0x00bf), /* X40 */ - TPACPI_Q_IBM('7', '4', 0x00bf), /* X41 */ - TPACPI_Q_IBM('7', '5', 0x00bf), /* X41t */ - - TPACPI_Q_IBM('7', '9', 0x1f97), /* T60 (1) */ - TPACPI_Q_IBM('7', '7', 0x1f97), /* Z60* (1) */ - TPACPI_Q_IBM('7', 'F', 0x1f97), /* Z61* (1) */ - TPACPI_Q_IBM('7', 'B', 0x1fb7), /* X60 (1) */ - - /* (1) - may have excess leds enabled on MSB */ - - /* Defaults (order matters, keep last, don't reorder!) */ - { /* Lenovo */ - .vendor = PCI_VENDOR_ID_LENOVO, - .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY, - .quirks = 0x1fffU, - }, - { /* IBM ThinkPads with no EC version string */ - .vendor = PCI_VENDOR_ID_IBM, - .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_UNKNOWN, - .quirks = 0x00ffU, - }, - { /* IBM ThinkPads with EC version string */ - .vendor = PCI_VENDOR_ID_IBM, - .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY, - .quirks = 0x00bfU, - }, -}; - -#undef TPACPI_LEDQ_IBM -#undef TPACPI_LEDQ_LNV - static int __init led_init(struct ibm_init_struct *iibm) { unsigned int i; int rc; - unsigned long useful_leds; vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); @@ -5128,9 +4999,6 @@ static int __init led_init(struct ibm_init_struct *iibm) vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", str_supported(led_supported), led_supported); - if (led_supported == TPACPI_LED_NONE) - return 1; - tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, GFP_KERNEL); if (!tpacpi_leds) { @@ -5138,12 +5006,8 @@ static int __init led_init(struct ibm_init_struct *iibm) return -ENOMEM; } - useful_leds = tpacpi_check_quirks(led_useful_qtable, - ARRAY_SIZE(led_useful_qtable)); - for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { - if (!tpacpi_is_led_restricted(i) && - test_bit(i, &useful_leds)) { + if (!tpacpi_is_led_restricted(i)) { rc = tpacpi_init_led(i); if (rc < 0) { led_exit(); @@ -5153,11 +5017,12 @@ static int __init led_init(struct ibm_init_struct *iibm) } #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS - printk(TPACPI_NOTICE - "warning: userspace override of important " - "firmware LEDs is enabled\n"); + if (led_supported != TPACPI_LED_NONE) + printk(TPACPI_NOTICE + "warning: userspace override of important " + "firmware LEDs is enabled\n"); #endif - return 0; + return (led_supported != TPACPI_LED_NONE)? 0 : 1; } #define str_led_status(s) \ @@ -5187,7 +5052,7 @@ static int led_read(char *p) } len += sprintf(p + len, "commands:\t" - " on, off, blink ( is 0-15)\n"); + " on, off, blink ( is 0-7)\n"); return len; } @@ -5202,7 +5067,7 @@ static int led_write(char *buf) return -ENODEV; while ((cmd = next_cmd(&buf))) { - if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 15) + if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 7) return -EINVAL; if (strstr(cmd, "off")) { @@ -5236,17 +5101,8 @@ static struct ibm_struct led_driver_data = { TPACPI_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ -#define TPACPI_BEEP_Q1 0x0001 - -static const struct tpacpi_quirk beep_quirk_table[] __initconst = { - TPACPI_Q_IBM('I', 'M', TPACPI_BEEP_Q1), /* 570 */ - TPACPI_Q_IBM('I', 'U', TPACPI_BEEP_Q1), /* 570E - unverified */ -}; - static int __init beep_init(struct ibm_init_struct *iibm) { - unsigned long quirks; - vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n"); TPACPI_ACPIHANDLE_INIT(beep); @@ -5254,11 +5110,6 @@ static int __init beep_init(struct ibm_init_struct *iibm) vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n", str_supported(beep_handle != NULL)); - quirks = tpacpi_check_quirks(beep_quirk_table, - ARRAY_SIZE(beep_quirk_table)); - - tp_features.beep_needs_two_args = !!(quirks & TPACPI_BEEP_Q1); - return (beep_handle)? 0 : 1; } @@ -5290,15 +5141,8 @@ static int beep_write(char *buf) /* beep_cmd set */ } else return -EINVAL; - if (tp_features.beep_needs_two_args) { - if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", - beep_cmd, 0)) - return -EIO; - } else { - if (!acpi_evalf(beep_handle, NULL, NULL, "vd", - beep_cmd)) - return -EIO; - } + if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0)) + return -EIO; } return 0; @@ -5725,10 +5569,6 @@ static struct ibm_struct ecdump_driver_data = { * Bit 3-0: backlight brightness level * * brightness_get_raw returns status data in the HBRV layout - * - * WARNING: The X61 has been verified to use HBRV for something else, so - * this should be used _only_ on IBM ThinkPads, and maybe with some careful - * testing on the very early *60 Lenovo models... */ enum { @@ -6029,12 +5869,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm) brightness_mode); } - /* Safety */ - if (thinkpad_id.vendor != PCI_VENDOR_ID_IBM && - (brightness_mode == TPACPI_BRGHT_MODE_ECNVRAM || - brightness_mode == TPACPI_BRGHT_MODE_EC)) - return -EINVAL; - if (tpacpi_brightness_get_raw(&b) < 0) return 1; @@ -6327,21 +6161,6 @@ static struct ibm_struct volume_driver_data = { * For firmware bugs, refer to: * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues * - * ---- - * - * ThinkPad EC register 0x31 bit 0 (only on select models) - * - * When bit 0 of EC register 0x31 is zero, the tachometer registers - * show the speed of the main fan. When bit 0 of EC register 0x31 - * is one, the tachometer registers show the speed of the auxiliary - * fan. - * - * Fan control seems to affect both fans, regardless of the state - * of this bit. - * - * So far, only the firmware for the X60/X61 non-tablet versions - * seem to support this (firmware TP-7M). - * * TPACPI_FAN_WR_ACPI_FANS: * ThinkPad X31, X40, X41. Not available in the X60. * @@ -6368,8 +6187,6 @@ enum { /* Fan control constants */ fan_status_offset = 0x2f, /* EC register 0x2f */ fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) * 0x84 must be read before 0x85 */ - fan_select_offset = 0x31, /* EC register 0x31 (Firmware 7M) - bit 0 selects which fan is active */ TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */ TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */ @@ -6432,18 +6249,30 @@ TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */ * We assume 0x07 really means auto mode while this quirk is active, * as this is far more likely than the ThinkPad being in level 7, * which is only used by the firmware during thermal emergencies. - * - * Enable for TP-1Y (T43), TP-78 (R51e), TP-76 (R52), - * TP-70 (T43, R52), which are known to be buggy. */ -static void fan_quirk1_setup(void) +static void fan_quirk1_detect(void) { + /* In some ThinkPads, neither the EC nor the ACPI + * DSDT initialize the HFSP register, and it ends up + * being initially set to 0x07 when it *could* be + * either 0x07 or 0x80. + * + * Enable for TP-1Y (T43), TP-78 (R51e), + * TP-76 (R52), TP-70 (T43, R52), which are known + * to be buggy. */ if (fan_control_initial_status == 0x07) { - printk(TPACPI_NOTICE - "fan_init: initial fan status is unknown, " - "assuming it is in auto mode\n"); - tp_features.fan_ctrl_status_undef = 1; + switch (thinkpad_id.ec_model) { + case 0x5931: /* TP-1Y */ + case 0x3837: /* TP-78 */ + case 0x3637: /* TP-76 */ + case 0x3037: /* TP-70 */ + printk(TPACPI_NOTICE + "fan_init: initial fan status is unknown, " + "assuming it is in auto mode\n"); + tp_features.fan_ctrl_status_undef = 1; + ;; + } } } @@ -6463,38 +6292,6 @@ static void fan_quirk1_handle(u8 *fan_status) } } -/* Select main fan on X60/X61, NOOP on others */ -static bool fan_select_fan1(void) -{ - if (tp_features.second_fan) { - u8 val; - - if (ec_read(fan_select_offset, &val) < 0) - return false; - val &= 0xFEU; - if (ec_write(fan_select_offset, val) < 0) - return false; - } - return true; -} - -/* Select secondary fan on X60/X61 */ -static bool fan_select_fan2(void) -{ - u8 val; - - if (!tp_features.second_fan) - return false; - - if (ec_read(fan_select_offset, &val) < 0) - return false; - val |= 0x01U; - if (ec_write(fan_select_offset, val) < 0) - return false; - - return true; -} - /* * Call with fan_mutex held */ @@ -6572,8 +6369,6 @@ static int fan_get_speed(unsigned int *speed) switch (fan_status_access_mode) { case TPACPI_FAN_RD_TPEC: /* all except 570, 600e/x, 770e, 770x */ - if (unlikely(!fan_select_fan1())) - return -EIO; if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || !acpi_ec_read(fan_rpm_offset + 1, &hi))) return -EIO; @@ -6590,34 +6385,6 @@ static int fan_get_speed(unsigned int *speed) return 0; } -static int fan2_get_speed(unsigned int *speed) -{ - u8 hi, lo; - bool rc; - - switch (fan_status_access_mode) { - case TPACPI_FAN_RD_TPEC: - /* all except 570, 600e/x, 770e, 770x */ - if (unlikely(!fan_select_fan2())) - return -EIO; - rc = !acpi_ec_read(fan_rpm_offset, &lo) || - !acpi_ec_read(fan_rpm_offset + 1, &hi); - fan_select_fan1(); /* play it safe */ - if (rc) - return -EIO; - - if (likely(speed)) - *speed = (hi << 8) | lo; - - break; - - default: - return -ENXIO; - } - - return 0; -} - static int fan_set_level(int level) { if (!fan_control_allowed) @@ -7023,25 +6790,6 @@ static struct device_attribute dev_attr_fan_fan1_input = __ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL); -/* sysfs fan fan2_input ------------------------------------------------ */ -static ssize_t fan_fan2_input_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int res; - unsigned int speed; - - res = fan2_get_speed(&speed); - if (res < 0) - return res; - - return snprintf(buf, PAGE_SIZE, "%u\n", speed); -} - -static struct device_attribute dev_attr_fan_fan2_input = - __ATTR(fan2_input, S_IRUGO, - fan_fan2_input_show, NULL); - /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ static ssize_t fan_fan_watchdog_show(struct device_driver *drv, char *buf) @@ -7075,7 +6823,6 @@ static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO, static struct attribute *fan_attributes[] = { &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr, &dev_attr_fan_fan1_input.attr, - NULL, /* for fan2_input */ NULL }; @@ -7083,36 +6830,9 @@ static const struct attribute_group fan_attr_group = { .attrs = fan_attributes, }; -#define TPACPI_FAN_Q1 0x0001 /* Unitialized HFSP */ -#define TPACPI_FAN_2FAN 0x0002 /* EC 0x31 bit 0 selects fan2 */ - -#define TPACPI_FAN_QI(__id1, __id2, __quirks) \ - { .vendor = PCI_VENDOR_ID_IBM, \ - .bios = TPACPI_MATCH_ANY, \ - .ec = TPID(__id1, __id2), \ - .quirks = __quirks } - -#define TPACPI_FAN_QL(__id1, __id2, __quirks) \ - { .vendor = PCI_VENDOR_ID_LENOVO, \ - .bios = TPACPI_MATCH_ANY, \ - .ec = TPID(__id1, __id2), \ - .quirks = __quirks } - -static const struct tpacpi_quirk fan_quirk_table[] __initconst = { - TPACPI_FAN_QI('1', 'Y', TPACPI_FAN_Q1), - TPACPI_FAN_QI('7', '8', TPACPI_FAN_Q1), - TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1), - TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1), - TPACPI_FAN_QL('7', 'M', TPACPI_FAN_2FAN), -}; - -#undef TPACPI_FAN_QL -#undef TPACPI_FAN_QI - static int __init fan_init(struct ibm_init_struct *iibm) { int rc; - unsigned long quirks; vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, "initializing fan subdriver\n"); @@ -7123,16 +6843,12 @@ static int __init fan_init(struct ibm_init_struct *iibm) fan_control_commands = 0; fan_watchdog_maxinterval = 0; tp_features.fan_ctrl_status_undef = 0; - tp_features.second_fan = 0; fan_control_desired_level = 7; TPACPI_ACPIHANDLE_INIT(fans); TPACPI_ACPIHANDLE_INIT(gfan); TPACPI_ACPIHANDLE_INIT(sfan); - quirks = tpacpi_check_quirks(fan_quirk_table, - ARRAY_SIZE(fan_quirk_table)); - if (gfan_handle) { /* 570, 600e/x, 770e, 770x */ fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN; @@ -7142,13 +6858,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) if (likely(acpi_ec_read(fan_status_offset, &fan_control_initial_status))) { fan_status_access_mode = TPACPI_FAN_RD_TPEC; - if (quirks & TPACPI_FAN_Q1) - fan_quirk1_setup(); - if (quirks & TPACPI_FAN_2FAN) { - tp_features.second_fan = 1; - dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, - "secondary fan support enabled\n"); - } + fan_quirk1_detect(); } else { printk(TPACPI_ERR "ThinkPad ACPI EC access misbehaving, " @@ -7204,11 +6914,6 @@ static int __init fan_init(struct ibm_init_struct *iibm) if (fan_status_access_mode != TPACPI_FAN_NONE || fan_control_access_mode != TPACPI_FAN_WR_NONE) { - if (tp_features.second_fan) { - /* attach second fan tachometer */ - fan_attributes[ARRAY_SIZE(fan_attributes)-2] = - &dev_attr_fan_fan2_input.attr; - } rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); if (rc < 0) @@ -7680,24 +7385,6 @@ static int __init ibm_init(struct ibm_init_struct *iibm) /* Probing */ -static bool __pure __init tpacpi_is_fw_digit(const char c) -{ - return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z'); -} - -/* Most models: xxyTkkWW (#.##c); Ancient 570/600 and -SL lacks (#.##c) */ -static bool __pure __init tpacpi_is_valid_fw_id(const char* const s, - const char t) -{ - return s && strlen(s) >= 8 && - tpacpi_is_fw_digit(s[0]) && - tpacpi_is_fw_digit(s[1]) && - s[2] == t && s[3] == 'T' && - tpacpi_is_fw_digit(s[4]) && - tpacpi_is_fw_digit(s[5]) && - s[6] == 'W' && s[7] == 'W'; -} - /* returns 0 - probe ok, or < 0 - probe error. * Probe ok doesn't mean thinkpad found. * On error, kfree() cleanup on tp->* is not performed, caller must do it */ @@ -7724,15 +7411,10 @@ static int __must_check __init get_thinkpad_model_data( tp->bios_version_str = kstrdup(s, GFP_KERNEL); if (s && !tp->bios_version_str) return -ENOMEM; - - /* Really ancient ThinkPad 240X will fail this, which is fine */ - if (!tpacpi_is_valid_fw_id(tp->bios_version_str, 'E')) + if (!tp->bios_version_str) return 0; - tp->bios_model = tp->bios_version_str[0] | (tp->bios_version_str[1] << 8); - tp->bios_release = (tp->bios_version_str[4] << 8) - | tp->bios_version_str[5]; /* * ThinkPad T23 or newer, A31 or newer, R50e or newer, @@ -7751,21 +7433,8 @@ static int __must_check __init get_thinkpad_model_data( tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); if (!tp->ec_version_str) return -ENOMEM; - - if (tpacpi_is_valid_fw_id(ec_fw_string, 'H')) { - tp->ec_model = ec_fw_string[0] - | (ec_fw_string[1] << 8); - tp->ec_release = (ec_fw_string[4] << 8) - | ec_fw_string[5]; - } else { - printk(TPACPI_NOTICE - "ThinkPad firmware release %s " - "doesn't match the known patterns\n", - ec_fw_string); - printk(TPACPI_NOTICE - "please report this to %s\n", - TPACPI_MAIL); - } + tp->ec_model = ec_fw_string[0] + | (ec_fw_string[1] << 8); break; } } diff --git a/trunk/drivers/pnp/pnpacpi/rsparser.c b/trunk/drivers/pnp/pnpacpi/rsparser.c index ef3a2cd3a7a0..7f207f335bec 100644 --- a/trunk/drivers/pnp/pnpacpi/rsparser.c +++ b/trunk/drivers/pnp/pnpacpi/rsparser.c @@ -287,25 +287,6 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, ACPI_DECODE_16); } -static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, - struct acpi_resource *res) -{ - struct acpi_resource_extended_address64 *p = &res->data.ext_address64; - - if (p->producer_consumer == ACPI_PRODUCER) - return; - - if (p->resource_type == ACPI_MEMORY_RANGE) - pnpacpi_parse_allocated_memresource(dev, - p->minimum, p->address_length, - p->info.mem.write_protect); - else if (p->resource_type == ACPI_IO_RANGE) - pnpacpi_parse_allocated_ioresource(dev, - p->minimum, p->address_length, - p->granularity == 0xfff ? ACPI_DECODE_10 : - ACPI_DECODE_16); -} - static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, void *data) { @@ -419,7 +400,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, break; case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: - pnpacpi_parse_allocated_ext_address_space(dev, res); + if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER) + return AE_OK; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: @@ -648,28 +630,6 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, IORESOURCE_IO_FIXED); } -static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev, - unsigned int option_flags, - struct acpi_resource *r) -{ - struct acpi_resource_extended_address64 *p = &r->data.ext_address64; - unsigned char flags = 0; - - if (p->address_length == 0) - return; - - if (p->resource_type == ACPI_MEMORY_RANGE) { - if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY) - flags = IORESOURCE_MEM_WRITEABLE; - pnp_register_mem_resource(dev, option_flags, p->minimum, - p->minimum, 0, p->address_length, - flags); - } else if (p->resource_type == ACPI_IO_RANGE) - pnp_register_port_resource(dev, option_flags, p->minimum, - p->minimum, 0, p->address_length, - IORESOURCE_IO_FIXED); -} - struct acpipnp_parse_option_s { struct pnp_dev *dev; unsigned int option_flags; @@ -751,7 +711,6 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, break; case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: - pnpacpi_parse_ext_address_option(dev, option_flags, res); break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: @@ -806,7 +765,6 @@ static int pnpacpi_supported_resource(struct acpi_resource *res) case ACPI_RESOURCE_TYPE_ADDRESS16: case ACPI_RESOURCE_TYPE_ADDRESS32: case ACPI_RESOURCE_TYPE_ADDRESS64: - case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: return 1; } diff --git a/trunk/drivers/power/Kconfig b/trunk/drivers/power/Kconfig index 7eda34838bfe..33da1127992a 100644 --- a/trunk/drivers/power/Kconfig +++ b/trunk/drivers/power/Kconfig @@ -82,14 +82,6 @@ config BATTERY_DA9030 Say Y here to enable support for batteries charger integrated into DA9030 PMIC. -config BATTERY_MAX17040 - tristate "Maxim MAX17040 Fuel Gauge" - depends on I2C - help - MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries - in handheld and portable equipment. The MAX17040 is configured - to operate with a single lithium cell - config CHARGER_PCF50633 tristate "NXP PCF50633 MBC" depends on MFD_PCF50633 diff --git a/trunk/drivers/power/Makefile b/trunk/drivers/power/Makefile index daf3179689aa..2fcf41d13e5c 100644 --- a/trunk/drivers/power/Makefile +++ b/trunk/drivers/power/Makefile @@ -25,5 +25,4 @@ obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o -obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o -obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o +obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o \ No newline at end of file diff --git a/trunk/drivers/power/da9030_battery.c b/trunk/drivers/power/da9030_battery.c index 3364198134a1..1662bb0f23a5 100644 --- a/trunk/drivers/power/da9030_battery.c +++ b/trunk/drivers/power/da9030_battery.c @@ -22,6 +22,8 @@ #include #include +#define DA9030_STATUS_CHDET (1 << 3) + #define DA9030_FAULT_LOG 0x0a #define DA9030_FAULT_LOG_OVER_TEMP (1 << 7) #define DA9030_FAULT_LOG_VBAT_OVER (1 << 4) @@ -242,8 +244,6 @@ static void da9030_set_charge(struct da9030_charger *charger, int on) } da903x_write(charger->master, DA9030_CHARGE_CONTROL, val); - - power_supply_changed(&charger->psy); } static void da9030_charger_check_state(struct da9030_charger *charger) @@ -258,12 +258,6 @@ static void da9030_charger_check_state(struct da9030_charger *charger) da9030_set_charge(charger, 1); } } else { - /* Charger has been pulled out */ - if (!charger->chdet) { - da9030_set_charge(charger, 0); - return; - } - if (charger->adc.vbat_res >= charger->thresholds.vbat_charge_stop) { da9030_set_charge(charger, 0); @@ -401,11 +395,13 @@ static int da9030_battery_event(struct notifier_block *nb, unsigned long event, { struct da9030_charger *charger = container_of(nb, struct da9030_charger, nb); + int status; switch (event) { case DA9030_EVENT_CHDET: - cancel_delayed_work_sync(&charger->work); - schedule_work(&charger->work.work); + status = da903x_query_status(charger->master, + DA9030_STATUS_CHDET); + da9030_set_charge(charger, status); break; case DA9030_EVENT_VBATMON: da9030_battery_vbat_event(charger); @@ -569,8 +565,7 @@ static int da9030_battery_remove(struct platform_device *dev) da903x_unregister_notifier(charger->master, &charger->nb, DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON | DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT); - cancel_delayed_work_sync(&charger->work); - da9030_set_charge(charger, 0); + cancel_delayed_work(&charger->work); power_supply_unregister(&charger->psy); kfree(charger); diff --git a/trunk/drivers/power/ds2760_battery.c b/trunk/drivers/power/ds2760_battery.c index 520b5c49ff30..a52d4a11652d 100644 --- a/trunk/drivers/power/ds2760_battery.c +++ b/trunk/drivers/power/ds2760_battery.c @@ -62,10 +62,6 @@ static unsigned int cache_time = 1000; module_param(cache_time, uint, 0644); MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); -static unsigned int pmod_enabled; -module_param(pmod_enabled, bool, 0644); -MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit"); - /* Some batteries have their rated capacity stored a N * 10 mAh, while * others use an index into this table. */ static int rated_capacities[] = { @@ -263,17 +259,6 @@ static void ds2760_battery_update_status(struct ds2760_device_info *di) power_supply_changed(&di->bat); } -static void ds2760_battery_write_status(struct ds2760_device_info *di, - char status) -{ - if (status == di->raw[DS2760_STATUS_REG]) - return; - - w1_ds2760_write(di->w1_dev, &status, DS2760_STATUS_WRITE_REG, 1); - w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); - w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); -} - static void ds2760_battery_work(struct work_struct *work) { struct ds2760_device_info *di = container_of(work, @@ -357,9 +342,9 @@ static enum power_supply_property ds2760_battery_props[] = { static int ds2760_battery_probe(struct platform_device *pdev) { - char status; int retval = 0; struct ds2760_device_info *di; + struct ds2760_platform_data *pdata; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) { @@ -369,13 +354,14 @@ static int ds2760_battery_probe(struct platform_device *pdev) platform_set_drvdata(pdev, di); - di->dev = &pdev->dev; - di->w1_dev = pdev->dev.parent; - di->bat.name = dev_name(&pdev->dev); - di->bat.type = POWER_SUPPLY_TYPE_BATTERY; - di->bat.properties = ds2760_battery_props; - di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props); - di->bat.get_property = ds2760_battery_get_property; + pdata = pdev->dev.platform_data; + di->dev = &pdev->dev; + di->w1_dev = pdev->dev.parent; + di->bat.name = dev_name(&pdev->dev); + di->bat.type = POWER_SUPPLY_TYPE_BATTERY; + di->bat.properties = ds2760_battery_props; + di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props); + di->bat.get_property = ds2760_battery_get_property; di->bat.external_power_changed = ds2760_battery_external_power_changed; @@ -387,16 +373,6 @@ static int ds2760_battery_probe(struct platform_device *pdev) goto batt_failed; } - /* enable sleep mode feature */ - ds2760_battery_read_status(di); - status = di->raw[DS2760_STATUS_REG]; - if (pmod_enabled) - status |= DS2760_STATUS_PMOD; - else - status &= ~DS2760_STATUS_PMOD; - - ds2760_battery_write_status(di, status); - INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); if (!di->monitor_wqueue) { diff --git a/trunk/drivers/power/max17040_battery.c b/trunk/drivers/power/max17040_battery.c deleted file mode 100644 index 87b98bf27ae1..000000000000 --- a/trunk/drivers/power/max17040_battery.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * max17040_battery.c - * fuel-gauge systems for lithium-ion (Li+) batteries - * - * Copyright (C) 2009 Samsung Electronics - * Minkyu Kang - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX17040_VCELL_MSB 0x02 -#define MAX17040_VCELL_LSB 0x03 -#define MAX17040_SOC_MSB 0x04 -#define MAX17040_SOC_LSB 0x05 -#define MAX17040_MODE_MSB 0x06 -#define MAX17040_MODE_LSB 0x07 -#define MAX17040_VER_MSB 0x08 -#define MAX17040_VER_LSB 0x09 -#define MAX17040_RCOMP_MSB 0x0C -#define MAX17040_RCOMP_LSB 0x0D -#define MAX17040_CMD_MSB 0xFE -#define MAX17040_CMD_LSB 0xFF - -#define MAX17040_DELAY 1000 -#define MAX17040_BATTERY_FULL 95 - -struct max17040_chip { - struct i2c_client *client; - struct delayed_work work; - struct power_supply battery; - struct max17040_platform_data *pdata; - - /* State Of Connect */ - int online; - /* battery voltage */ - int vcell; - /* battery capacity */ - int soc; - /* State Of Charge */ - int status; -}; - -static int max17040_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct max17040_chip *chip = container_of(psy, - struct max17040_chip, battery); - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - val->intval = chip->status; - break; - case POWER_SUPPLY_PROP_ONLINE: - val->intval = chip->online; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = chip->vcell; - break; - case POWER_SUPPLY_PROP_CAPACITY: - val->intval = chip->soc; - break; - default: - return -EINVAL; - } - return 0; -} - -static int max17040_write_reg(struct i2c_client *client, int reg, u8 value) -{ - int ret; - - ret = i2c_smbus_write_byte_data(client, reg, value); - - if (ret < 0) - dev_err(&client->dev, "%s: err %d\n", __func__, ret); - - return ret; -} - -static int max17040_read_reg(struct i2c_client *client, int reg) -{ - int ret; - - ret = i2c_smbus_read_byte_data(client, reg); - - if (ret < 0) - dev_err(&client->dev, "%s: err %d\n", __func__, ret); - - return ret; -} - -static void max17040_reset(struct i2c_client *client) -{ - max17040_write_reg(client, MAX17040_CMD_MSB, 0x54); - max17040_write_reg(client, MAX17040_CMD_LSB, 0x00); -} - -static void max17040_get_vcell(struct i2c_client *client) -{ - struct max17040_chip *chip = i2c_get_clientdata(client); - u8 msb; - u8 lsb; - - msb = max17040_read_reg(client, MAX17040_VCELL_MSB); - lsb = max17040_read_reg(client, MAX17040_VCELL_LSB); - - chip->vcell = (msb << 4) + (lsb >> 4); -} - -static void max17040_get_soc(struct i2c_client *client) -{ - struct max17040_chip *chip = i2c_get_clientdata(client); - u8 msb; - u8 lsb; - - msb = max17040_read_reg(client, MAX17040_SOC_MSB); - lsb = max17040_read_reg(client, MAX17040_SOC_LSB); - - chip->soc = msb; -} - -static void max17040_get_version(struct i2c_client *client) -{ - u8 msb; - u8 lsb; - - msb = max17040_read_reg(client, MAX17040_VER_MSB); - lsb = max17040_read_reg(client, MAX17040_VER_LSB); - - dev_info(&client->dev, "MAX17040 Fuel-Gauge Ver %d%d\n", msb, lsb); -} - -static void max17040_get_online(struct i2c_client *client) -{ - struct max17040_chip *chip = i2c_get_clientdata(client); - - if (chip->pdata->battery_online) - chip->online = chip->pdata->battery_online(); - else - chip->online = 1; -} - -static void max17040_get_status(struct i2c_client *client) -{ - struct max17040_chip *chip = i2c_get_clientdata(client); - - if (!chip->pdata->charger_online || !chip->pdata->charger_enable) { - chip->status = POWER_SUPPLY_STATUS_UNKNOWN; - return; - } - - if (chip->pdata->charger_online()) { - if (chip->pdata->charger_enable()) - chip->status = POWER_SUPPLY_STATUS_CHARGING; - else - chip->status = POWER_SUPPLY_STATUS_NOT_CHARGING; - } else { - chip->status = POWER_SUPPLY_STATUS_DISCHARGING; - } - - if (chip->soc > MAX17040_BATTERY_FULL) - chip->status = POWER_SUPPLY_STATUS_FULL; -} - -static void max17040_work(struct work_struct *work) -{ - struct max17040_chip *chip; - - chip = container_of(work, struct max17040_chip, work.work); - - max17040_get_vcell(chip->client); - max17040_get_soc(chip->client); - max17040_get_online(chip->client); - max17040_get_status(chip->client); - - schedule_delayed_work(&chip->work, MAX17040_DELAY); -} - -static enum power_supply_property max17040_battery_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CAPACITY, -}; - -static int __devinit max17040_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct max17040_chip *chip; - int ret; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) - return -EIO; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->client = client; - chip->pdata = client->dev.platform_data; - - i2c_set_clientdata(client, chip); - - chip->battery.name = "battery"; - chip->battery.type = POWER_SUPPLY_TYPE_BATTERY; - chip->battery.get_property = max17040_get_property; - chip->battery.properties = max17040_battery_props; - chip->battery.num_properties = ARRAY_SIZE(max17040_battery_props); - - ret = power_supply_register(&client->dev, &chip->battery); - if (ret) { - dev_err(&client->dev, "failed: power supply register\n"); - i2c_set_clientdata(client, NULL); - kfree(chip); - return ret; - } - - max17040_reset(client); - max17040_get_version(client); - - INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17040_work); - schedule_delayed_work(&chip->work, MAX17040_DELAY); - - return 0; -} - -static int __devexit max17040_remove(struct i2c_client *client) -{ - struct max17040_chip *chip = i2c_get_clientdata(client); - - power_supply_unregister(&chip->battery); - cancel_delayed_work(&chip->work); - i2c_set_clientdata(client, NULL); - kfree(chip); - return 0; -} - -#ifdef CONFIG_PM - -static int max17040_suspend(struct i2c_client *client, - pm_message_t state) -{ - struct max17040_chip *chip = i2c_get_clientdata(client); - - cancel_delayed_work(&chip->work); - return 0; -} - -static int max17040_resume(struct i2c_client *client) -{ - struct max17040_chip *chip = i2c_get_clientdata(client); - - schedule_delayed_work(&chip->work, MAX17040_DELAY); - return 0; -} - -#else - -#define max17040_suspend NULL -#define max17040_resume NULL - -#endif /* CONFIG_PM */ - -static const struct i2c_device_id max17040_id[] = { - { "max17040", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, max17040_id); - -static struct i2c_driver max17040_i2c_driver = { - .driver = { - .name = "max17040", - }, - .probe = max17040_probe, - .remove = __devexit_p(max17040_remove), - .suspend = max17040_suspend, - .resume = max17040_resume, - .id_table = max17040_id, -}; - -static int __init max17040_init(void) -{ - return i2c_add_driver(&max17040_i2c_driver); -} -module_init(max17040_init); - -static void __exit max17040_exit(void) -{ - i2c_del_driver(&max17040_i2c_driver); -} -module_exit(max17040_exit); - -MODULE_AUTHOR("Minkyu Kang "); -MODULE_DESCRIPTION("MAX17040 Fuel Gauge"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-bfin.c b/trunk/drivers/rtc/rtc-bfin.c index a118eb0f1e67..aafd3e6ebb0d 100644 --- a/trunk/drivers/rtc/rtc-bfin.c +++ b/trunk/drivers/rtc/rtc-bfin.c @@ -1,8 +1,8 @@ /* * Blackfin On-Chip Real Time Clock Driver - * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x + * Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789] * - * Copyright 2004-2009 Analog Devices Inc. + * Copyright 2004-2008 Analog Devices Inc. * * Enter bugs at http://blackfin.uclinux.org/ * @@ -363,7 +363,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) struct bfin_rtc *rtc; struct device *dev = &pdev->dev; int ret = 0; - unsigned long timeout = jiffies + HZ; + unsigned long timeout; dev_dbg_stamp(dev); @@ -374,32 +374,32 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); device_init_wakeup(dev, 1); - /* Register our RTC with the RTC framework */ - rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, - THIS_MODULE); - if (unlikely(IS_ERR(rtc->rtc_dev))) { - ret = PTR_ERR(rtc->rtc_dev); - goto err; - } - /* Grab the IRQ and init the hardware */ ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev); if (unlikely(ret)) - goto err_reg; + goto err; /* sometimes the bootloader touched things, but the write complete was not * enabled, so let's just do a quick timeout here since the IRQ will not fire ... */ + timeout = jiffies + HZ; while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING) if (time_after(jiffies, timeout)) break; bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE); bfin_write_RTC_SWCNT(0); + /* Register our RTC with the RTC framework */ + rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE); + if (unlikely(IS_ERR(rtc->rtc_dev))) { + ret = PTR_ERR(rtc->rtc_dev); + goto err_irq; + } + return 0; -err_reg: - rtc_device_unregister(rtc->rtc_dev); -err: + err_irq: + free_irq(IRQ_RTC, dev); + err: kfree(rtc); return ret; } diff --git a/trunk/drivers/rtc/rtc-vr41xx.c b/trunk/drivers/rtc/rtc-vr41xx.c index 2c839d0d21bd..f11297aff854 100644 --- a/trunk/drivers/rtc/rtc-vr41xx.c +++ b/trunk/drivers/rtc/rtc-vr41xx.c @@ -1,7 +1,7 @@ /* * Driver for NEC VR4100 series Real Time Clock unit. * - * Copyright (C) 2003-2008 Yoichi Yuasa + * Copyright (C) 2003-2008 Yoichi Yuasa * * 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 @@ -33,7 +33,7 @@ #include #include -MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_AUTHOR("Yoichi Yuasa "); MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 9c23122f755f..6a19ed9a1194 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -258,21 +258,10 @@ config SCSI_SCAN_ASYNC or async on the kernel's command line. config SCSI_WAIT_SCAN - tristate # No prompt here, this is an invisible symbol. + tristate default m depends on SCSI depends on MODULES -# scsi_wait_scan is a loadable module which waits until all the async scans are -# complete. The idea is to use it in initrd/ initramfs scripts. You modprobe -# it after all the modprobes of the root SCSI drivers and it will wait until -# they have all finished scanning their buses before allowing the boot to -# proceed. (This method is not applicable if targets boot independently in -# parallel with the initiator, or with transports with non-deterministic target -# discovery schemes, or if a transport driver does not support scsi_wait_scan.) -# -# This symbol is not exposed as a prompt because little is to be gained by -# disabling it, whereas people who accidentally switch it off may wonder why -# their mkinitrd gets into trouble. menu "SCSI Transports" depends on SCSI diff --git a/trunk/drivers/scsi/bnx2i/Kconfig b/trunk/drivers/scsi/bnx2i/Kconfig index 1e9f7141102b..b62b482e55e7 100644 --- a/trunk/drivers/scsi/bnx2i/Kconfig +++ b/trunk/drivers/scsi/bnx2i/Kconfig @@ -1,8 +1,6 @@ config SCSI_BNX2_ISCSI tristate "Broadcom NetXtreme II iSCSI support" select SCSI_ISCSI_ATTRS - select NETDEVICES - select NETDEV_1000 select CNIC depends on PCI ---help--- diff --git a/trunk/drivers/scsi/cxgb3i/Kbuild b/trunk/drivers/scsi/cxgb3i/Kbuild index 70d060b7ff4f..25a2032bfa26 100644 --- a/trunk/drivers/scsi/cxgb3i/Kbuild +++ b/trunk/drivers/scsi/cxgb3i/Kbuild @@ -1,4 +1,4 @@ -EXTRA_CFLAGS += -I$(srctree)/drivers/net/cxgb3 +EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/cxgb3 cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o cxgb3i_ddp.o obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i.o diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c index 344fd53b9954..99c912547902 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.c @@ -206,31 +206,6 @@ int cxgb3i_ddp_find_page_index(unsigned long pgsz) return DDP_PGIDX_MAX; } -/** - * cxgb3i_ddp_adjust_page_table - adjust page table with PAGE_SIZE - * return the ddp page index, if no match is found return DDP_PGIDX_MAX. - */ -int cxgb3i_ddp_adjust_page_table(void) -{ - int i; - unsigned int base_order, order; - - if (PAGE_SIZE < (1UL << ddp_page_shift[0])) { - ddp_log_info("PAGE_SIZE 0x%lx too small, min. 0x%lx.\n", - PAGE_SIZE, 1UL << ddp_page_shift[0]); - return -EINVAL; - } - - base_order = get_order(1UL << ddp_page_shift[0]); - order = get_order(1 << PAGE_SHIFT); - for (i = 0; i < DDP_PGIDX_MAX; i++) { - /* first is the kernel page size, then just doubling the size */ - ddp_page_order[i] = order - base_order + i; - ddp_page_shift[i] = PAGE_SHIFT + i; - } - return 0; -} - static inline void ddp_gl_unmap(struct pci_dev *pdev, struct cxgb3i_gather_list *gl) { @@ -623,40 +598,30 @@ int cxgb3i_adapter_ddp_info(struct t3cdev *tdev, * release all the resource held by the ddp pagepod manager for a given * adapter if needed */ - -static void ddp_cleanup(struct kref *kref) -{ - struct cxgb3i_ddp_info *ddp = container_of(kref, - struct cxgb3i_ddp_info, - refcnt); - int i = 0; - - ddp_log_info("kref release ddp 0x%p, t3dev 0x%p.\n", ddp, ddp->tdev); - - ddp->tdev->ulp_iscsi = NULL; - while (i < ddp->nppods) { - struct cxgb3i_gather_list *gl = ddp->gl_map[i]; - if (gl) { - int npods = (gl->nelem + PPOD_PAGES_MAX - 1) - >> PPOD_PAGES_SHIFT; - ddp_log_info("t3dev 0x%p, ddp %d + %d.\n", - ddp->tdev, i, npods); - kfree(gl); - ddp_free_gl_skb(ddp, i, npods); - i += npods; - } else - i++; - } - cxgb3i_free_big_mem(ddp); -} - void cxgb3i_ddp_cleanup(struct t3cdev *tdev) { + int i = 0; struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi; ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp); - if (ddp) - kref_put(&ddp->refcnt, ddp_cleanup); + + if (ddp) { + tdev->ulp_iscsi = NULL; + while (i < ddp->nppods) { + struct cxgb3i_gather_list *gl = ddp->gl_map[i]; + if (gl) { + int npods = (gl->nelem + PPOD_PAGES_MAX - 1) + >> PPOD_PAGES_SHIFT; + ddp_log_info("t3dev 0x%p, ddp %d + %d.\n", + tdev, i, npods); + kfree(gl); + ddp_free_gl_skb(ddp, i, npods); + i += npods; + } else + i++; + } + cxgb3i_free_big_mem(ddp); + } } /** @@ -666,13 +631,12 @@ void cxgb3i_ddp_cleanup(struct t3cdev *tdev) */ static void ddp_init(struct t3cdev *tdev) { - struct cxgb3i_ddp_info *ddp = tdev->ulp_iscsi; + struct cxgb3i_ddp_info *ddp; struct ulp_iscsi_info uinfo; unsigned int ppmax, bits; int i, err; - if (ddp) { - kref_get(&ddp->refcnt); + if (tdev->ulp_iscsi) { ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n", tdev, tdev->ulp_iscsi); return; @@ -706,7 +670,6 @@ static void ddp_init(struct t3cdev *tdev) ppmax * sizeof(struct cxgb3i_gather_list *)); spin_lock_init(&ddp->map_lock); - kref_init(&ddp->refcnt); ddp->tdev = tdev; ddp->pdev = uinfo.pdev; @@ -752,17 +715,6 @@ void cxgb3i_ddp_init(struct t3cdev *tdev) { if (page_idx == DDP_PGIDX_MAX) { page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE); - - if (page_idx == DDP_PGIDX_MAX) { - ddp_log_info("system PAGE_SIZE %lu, update hw.\n", - PAGE_SIZE); - if (cxgb3i_ddp_adjust_page_table() < 0) { - ddp_log_info("PAGE_SIZE %lu, ddp disabled.\n", - PAGE_SIZE); - return; - } - page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE); - } ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n", PAGE_SIZE, page_idx); } diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h index 87dd56b422bf..0d296de7cf32 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_ddp.h @@ -54,7 +54,6 @@ struct cxgb3i_gather_list { * struct cxgb3i_ddp_info - cxgb3i direct data placement for pdu payload * * @list: list head to link elements - * @refcnt: ref. count * @tdev: pointer to t3cdev used by cxgb3 driver * @max_txsz: max tx packet size for ddp * @max_rxsz: max rx packet size for ddp @@ -71,7 +70,6 @@ struct cxgb3i_gather_list { */ struct cxgb3i_ddp_info { struct list_head list; - struct kref refcnt; struct t3cdev *tdev; struct pci_dev *pdev; unsigned int max_txsz; diff --git a/trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index c399f485aa7d..74369a3f963b 100644 --- a/trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/trunk/drivers/scsi/cxgb3i/cxgb3i_iscsi.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -185,9 +184,6 @@ static struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *ndev) struct cxgb3i_adapter *snic; int i; - if (ndev->priv_flags & IFF_802_1Q_VLAN) - ndev = vlan_dev_real_dev(ndev); - read_lock(&cxgb3i_snic_rwlock); list_for_each_entry(snic, &cxgb3i_snic_list, list_head) { for (i = 0; i < snic->hba_cnt; i++) { diff --git a/trunk/drivers/scsi/fcoe/fcoe.c b/trunk/drivers/scsi/fcoe/fcoe.c index 0a5609bb5817..c15878e88157 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.c +++ b/trunk/drivers/scsi/fcoe/fcoe.c @@ -45,6 +45,8 @@ #include "fcoe.h" +static int debug_fcoe; + MODULE_AUTHOR("Open-FCoE.org"); MODULE_DESCRIPTION("FCoE"); MODULE_LICENSE("GPL v2"); @@ -303,22 +305,23 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) #ifdef NETIF_F_FCOE_CRC if (netdev->features & NETIF_F_FCOE_CRC) { lp->crc_offload = 1; - FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n"); + printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n", + netdev->name); } #endif #ifdef NETIF_F_FSO if (netdev->features & NETIF_F_FSO) { lp->seq_offload = 1; lp->lso_max = netdev->gso_max_size; - FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n", - lp->lso_max); + printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n", + netdev->name, lp->lso_max); } #endif if (netdev->fcoe_ddp_xid) { lp->lro_enabled = 1; lp->lro_xid = netdev->fcoe_ddp_xid; - FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n", - lp->lro_xid); + printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n", + netdev->name, lp->lro_xid); } skb_queue_head_init(&fc->fcoe_pending_queue); fc->fcoe_pending_queue_active = 0; @@ -404,8 +407,7 @@ static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost, /* add the new host to the SCSI-ml */ rc = scsi_add_host(lp->host, dev); if (rc) { - FCOE_NETDEV_DBG(fcoe_netdev(lp), "fcoe_shost_config: " - "error on scsi_add_host\n"); + FC_DBG("fcoe_shost_config:error on scsi_add_host\n"); return rc; } sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s", @@ -446,7 +448,8 @@ static int fcoe_if_destroy(struct net_device *netdev) BUG_ON(!netdev); - FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); + printk(KERN_DEBUG "fcoe_if_destroy:interface on %s\n", + netdev->name); lp = fcoe_hostlist_lookup(netdev); if (!lp) @@ -557,7 +560,8 @@ static int fcoe_if_create(struct net_device *netdev) BUG_ON(!netdev); - FCOE_NETDEV_DBG(netdev, "Create Interface\n"); + printk(KERN_DEBUG "fcoe_if_create:interface on %s\n", + netdev->name); lp = fcoe_hostlist_lookup(netdev); if (lp) @@ -566,7 +570,7 @@ static int fcoe_if_create(struct net_device *netdev) shost = libfc_host_alloc(&fcoe_shost_template, sizeof(struct fcoe_softc)); if (!shost) { - FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); + FC_DBG("Could not allocate host structure\n"); return -ENOMEM; } lp = shost_priv(shost); @@ -575,8 +579,7 @@ static int fcoe_if_create(struct net_device *netdev) /* configure fc_lport, e.g., em */ rc = fcoe_lport_config(lp); if (rc) { - FCOE_NETDEV_DBG(netdev, "Could not configure lport for the " - "interface\n"); + FC_DBG("Could not configure lport\n"); goto out_host_put; } @@ -590,32 +593,28 @@ static int fcoe_if_create(struct net_device *netdev) /* configure lport network properties */ rc = fcoe_netdev_config(lp, netdev); if (rc) { - FCOE_NETDEV_DBG(netdev, "Could not configure netdev for the " - "interface\n"); + FC_DBG("Could not configure netdev for the interface\n"); goto out_netdev_cleanup; } /* configure lport scsi host properties */ rc = fcoe_shost_config(lp, shost, &netdev->dev); if (rc) { - FCOE_NETDEV_DBG(netdev, "Could not configure shost for the " - "interface\n"); + FC_DBG("Could not configure shost for lport\n"); goto out_netdev_cleanup; } /* lport exch manager allocation */ rc = fcoe_em_config(lp); if (rc) { - FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the " - "interface\n"); + FC_DBG("Could not configure em for lport\n"); goto out_netdev_cleanup; } /* Initialize the library */ rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ); if (rc) { - FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " - "interface\n"); + FC_DBG("Could not configure libfc for lport!\n"); goto out_lp_destroy; } @@ -654,7 +653,7 @@ static int __init fcoe_if_init(void) fc_attach_transport(&fcoe_transport_function); if (!scsi_transport_fcoe_sw) { - printk(KERN_ERR "fcoe: Failed to attach to the FC transport\n"); + printk(KERN_ERR "fcoe_init:fc_attach_transport() failed\n"); return -ENODEV; } @@ -715,7 +714,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) unsigned targ_cpu = smp_processor_id(); #endif /* CONFIG_SMP */ - FCOE_DBG("Destroying receive thread for CPU %d\n", cpu); + printk(KERN_DEBUG "fcoe: Destroying receive thread for CPU %d\n", cpu); /* Prevent any new skbs from being queued for this CPU. */ p = &per_cpu(fcoe_percpu, cpu); @@ -737,8 +736,8 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) p0 = &per_cpu(fcoe_percpu, targ_cpu); spin_lock_bh(&p0->fcoe_rx_list.lock); if (p0->thread) { - FCOE_DBG("Moving frames from CPU %d to CPU %d\n", - cpu, targ_cpu); + FC_DBG("Moving frames from CPU %d to CPU %d\n", + cpu, targ_cpu); while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL) __skb_queue_tail(&p0->fcoe_rx_list, skb); @@ -804,12 +803,12 @@ static int fcoe_cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_ONLINE: case CPU_ONLINE_FROZEN: - FCOE_DBG("CPU %x online: Create Rx thread\n", cpu); + FC_DBG("CPU %x online: Create Rx thread\n", cpu); fcoe_percpu_thread_create(cpu); break; case CPU_DEAD: case CPU_DEAD_FROZEN: - FCOE_DBG("CPU %x offline: Remove Rx thread\n", cpu); + FC_DBG("CPU %x offline: Remove Rx thread\n", cpu); fcoe_percpu_thread_destroy(cpu); break; default: @@ -847,21 +846,24 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type); lp = fc->ctlr.lp; if (unlikely(lp == NULL)) { - FCOE_NETDEV_DBG(dev, "Cannot find hba structure"); + FC_DBG("cannot find hba structure"); goto err2; } if (!lp->link_up) goto err2; - FCOE_NETDEV_DBG(dev, "skb_info: len:%d data_len:%d head:%p " - "data:%p tail:%p end:%p sum:%d dev:%s", - skb->len, skb->data_len, skb->head, skb->data, - skb_tail_pointer(skb), skb_end_pointer(skb), - skb->csum, skb->dev ? skb->dev->name : ""); + if (unlikely(debug_fcoe)) { + FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p " + "end:%p sum:%d dev:%s", skb->len, skb->data_len, + skb->head, skb->data, skb_tail_pointer(skb), + skb_end_pointer(skb), skb->csum, + skb->dev ? skb->dev->name : ""); + + } /* check for FCOE packet type */ if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { - FCOE_NETDEV_DBG(dev, "Wrong FC type frame"); + FC_DBG("wrong FC type frame"); goto err; } @@ -899,9 +901,8 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, * the first CPU now. For non-SMP systems this * will check the same CPU twice. */ - FCOE_NETDEV_DBG(dev, "CPU is online, but no receive thread " - "ready for incoming skb- using first online " - "CPU.\n"); + FC_DBG("CPU is online, but no receive thread ready " + "for incoming skb- using first online CPU.\n"); spin_unlock_bh(&fps->fcoe_rx_list.lock); cpu = first_cpu(cpu_online_map); @@ -1200,17 +1201,19 @@ int fcoe_percpu_receive_thread(void *arg) fr = fcoe_dev_from_skb(skb); lp = fr->fr_dev; if (unlikely(lp == NULL)) { - FCOE_NETDEV_DBG(skb->dev, "Invalid HBA Structure"); + FC_DBG("invalid HBA Structure"); kfree_skb(skb); continue; } - FCOE_NETDEV_DBG(skb->dev, "skb_info: len:%d data_len:%d " - "head:%p data:%p tail:%p end:%p sum:%d dev:%s", - skb->len, skb->data_len, - skb->head, skb->data, skb_tail_pointer(skb), - skb_end_pointer(skb), skb->csum, - skb->dev ? skb->dev->name : ""); + if (unlikely(debug_fcoe)) { + FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p " + "tail:%p end:%p sum:%d dev:%s", + skb->len, skb->data_len, + skb->head, skb->data, skb_tail_pointer(skb), + skb_end_pointer(skb), skb->csum, + skb->dev ? skb->dev->name : ""); + } /* * Save source MAC address before discarding header. @@ -1230,7 +1233,7 @@ int fcoe_percpu_receive_thread(void *arg) stats = fc_lport_get_stats(lp); if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { if (stats->ErrorFrames < 5) - printk(KERN_WARNING "fcoe: FCoE version " + printk(KERN_WARNING "FCoE version " "mismatch: The frame has " "version %x, but the " "initiator supports version " @@ -1283,7 +1286,7 @@ int fcoe_percpu_receive_thread(void *arg) if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) { if (le32_to_cpu(fr_crc(fp)) != ~crc32(~0, skb->data, fr_len)) { - if (stats->InvalidCRCCount < 5) + if (debug_fcoe || stats->InvalidCRCCount < 5) printk(KERN_WARNING "fcoe: dropping " "frame with CRC error\n"); stats->InvalidCRCCount++; @@ -1429,8 +1432,7 @@ static int fcoe_device_notification(struct notifier_block *notifier, case NETDEV_REGISTER: break; default: - FCOE_NETDEV_DBG(real_dev, "Unknown event %ld " - "from netdev netlink\n", event); + FC_DBG("Unknown event %ld from netdev netlink\n", event); } if (link_possible && !fcoe_link_ok(lp)) fcoe_ctlr_link_up(&fc->ctlr); @@ -1503,8 +1505,8 @@ static int fcoe_ethdrv_get(const struct net_device *netdev) owner = fcoe_netdev_to_module_owner(netdev); if (owner) { - FCOE_NETDEV_DBG(netdev, "Hold driver module %s\n", - module_name(owner)); + printk(KERN_DEBUG "fcoe:hold driver module %s for %s\n", + module_name(owner), netdev->name); return try_module_get(owner); } return -ENODEV; @@ -1525,8 +1527,8 @@ static int fcoe_ethdrv_put(const struct net_device *netdev) owner = fcoe_netdev_to_module_owner(netdev); if (owner) { - FCOE_NETDEV_DBG(netdev, "Release driver module %s\n", - module_name(owner)); + printk(KERN_DEBUG "fcoe:release driver module %s for %s\n", + module_name(owner), netdev->name); module_put(owner); return 0; } @@ -1557,7 +1559,7 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) } rc = fcoe_if_destroy(netdev); if (rc) { - printk(KERN_ERR "fcoe: Failed to destroy interface (%s)\n", + printk(KERN_ERR "fcoe: fcoe_if_destroy(%s) failed\n", netdev->name); rc = -EIO; goto out_putdev; @@ -1596,7 +1598,7 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) rc = fcoe_if_create(netdev); if (rc) { - printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", + printk(KERN_ERR "fcoe: fcoe_if_create(%s) failed\n", netdev->name); fcoe_ethdrv_put(netdev); rc = -EIO; diff --git a/trunk/drivers/scsi/fcoe/fcoe.h b/trunk/drivers/scsi/fcoe/fcoe.h index 0d724fa0898f..a1eb8c1988b0 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.h +++ b/trunk/drivers/scsi/fcoe/fcoe.h @@ -40,30 +40,6 @@ #define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */ #define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */ -unsigned int fcoe_debug_logging; -module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); - -#define FCOE_LOGGING 0x01 /* General logging, not categorized */ -#define FCOE_NETDEV_LOGGING 0x02 /* Netdevice logging */ - -#define FCOE_CHECK_LOGGING(LEVEL, CMD) \ -do { \ - if (unlikely(fcoe_debug_logging & LEVEL)) \ - do { \ - CMD; \ - } while (0); \ -} while (0); - -#define FCOE_DBG(fmt, args...) \ - FCOE_CHECK_LOGGING(FCOE_LOGGING, \ - printk(KERN_INFO "fcoe: " fmt, ##args);) - -#define FCOE_NETDEV_DBG(netdev, fmt, args...) \ - FCOE_CHECK_LOGGING(FCOE_NETDEV_LOGGING, \ - printk(KERN_INFO "fcoe: %s" fmt, \ - netdev->name, ##args);) - /* * this percpu struct for fcoe */ diff --git a/trunk/drivers/scsi/fcoe/libfcoe.c b/trunk/drivers/scsi/fcoe/libfcoe.c index f544340d318b..2f5bc7fd3fa9 100644 --- a/trunk/drivers/scsi/fcoe/libfcoe.c +++ b/trunk/drivers/scsi/fcoe/libfcoe.c @@ -56,28 +56,15 @@ static void fcoe_ctlr_recv_work(struct work_struct *); static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS; -unsigned int libfcoe_debug_logging; -module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); +static u32 fcoe_ctlr_debug; /* 1 for basic, 2 for noisy debug */ -#define LIBFCOE_LOGGING 0x01 /* General logging, not categorized */ -#define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */ - -#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD) \ -do { \ - if (unlikely(libfcoe_debug_logging & LEVEL)) \ +#define FIP_DBG_LVL(level, fmt, args...) \ do { \ - CMD; \ - } while (0); \ -} while (0); - -#define LIBFCOE_DBG(fmt, args...) \ - LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \ - printk(KERN_INFO "libfcoe: " fmt, ##args);) + if (fcoe_ctlr_debug >= (level)) \ + FC_DBG(fmt, ##args); \ + } while (0) -#define LIBFCOE_FIP_DBG(fmt, args...) \ - LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING, \ - printk(KERN_INFO "fip: " fmt, ##args);) +#define FIP_DBG(fmt, args...) FIP_DBG_LVL(1, fmt, ##args) /* * Return non-zero if FCF fcoe_size has been validated. @@ -256,7 +243,7 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr *fip) fip->last_link = 1; fip->link = 1; spin_unlock_bh(&fip->lock); - LIBFCOE_FIP_DBG("%s", "setting AUTO mode.\n"); + FIP_DBG("%s", "setting AUTO mode.\n"); fc_linkup(fip->lp); fcoe_ctlr_solicit(fip, NULL); } else @@ -627,8 +614,7 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf) ((struct fip_mac_desc *)desc)->fd_mac, ETH_ALEN); if (!is_valid_ether_addr(fcf->fcf_mac)) { - LIBFCOE_FIP_DBG("Invalid MAC address " - "in FIP adv\n"); + FIP_DBG("invalid MAC addr in FIP adv\n"); return -EINVAL; } break; @@ -661,8 +647,8 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf) case FIP_DT_LOGO: case FIP_DT_ELP: default: - LIBFCOE_FIP_DBG("unexpected descriptor type %x " - "in FIP adv\n", desc->fip_dtype); + FIP_DBG("unexpected descriptor type %x in FIP adv\n", + desc->fip_dtype); /* standard says ignore unknown descriptors >= 128 */ if (desc->fip_dtype < FIP_DT_VENDOR_BASE) return -EINVAL; @@ -678,8 +664,8 @@ static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf) return 0; len_err: - LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n", - desc->fip_dtype, dlen); + FIP_DBG("FIP length error in descriptor type %x len %zu\n", + desc->fip_dtype, dlen); return -EINVAL; } @@ -742,10 +728,9 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) } mtu_valid = fcoe_ctlr_mtu_valid(fcf); fcf->time = jiffies; - if (!found) { - LIBFCOE_FIP_DBG("New FCF for fab %llx map %x val %d\n", - fcf->fabric_name, fcf->fc_map, mtu_valid); - } + FIP_DBG_LVL(found ? 2 : 1, "%s FCF for fab %llx map %x val %d\n", + found ? "old" : "new", + fcf->fabric_name, fcf->fc_map, mtu_valid); /* * If this advertisement is not solicited and our max receive size @@ -822,8 +807,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) ((struct fip_mac_desc *)desc)->fd_mac, ETH_ALEN); if (!is_valid_ether_addr(granted_mac)) { - LIBFCOE_FIP_DBG("Invalid MAC address " - "in FIP ELS\n"); + FIP_DBG("invalid MAC addrs in FIP ELS\n"); goto drop; } break; @@ -841,8 +825,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) els_dtype = desc->fip_dtype; break; default: - LIBFCOE_FIP_DBG("unexpected descriptor type %x " - "in FIP adv\n", desc->fip_dtype); + FIP_DBG("unexpected descriptor type %x " + "in FIP adv\n", desc->fip_dtype); /* standard says ignore unknown descriptors >= 128 */ if (desc->fip_dtype < FIP_DT_VENDOR_BASE) goto drop; @@ -883,8 +867,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) return; len_err: - LIBFCOE_FIP_DBG("FIP length error in descriptor type %x len %zu\n", - desc->fip_dtype, dlen); + FIP_DBG("FIP length error in descriptor type %x len %zu\n", + desc->fip_dtype, dlen); drop: kfree_skb(skb); } @@ -910,7 +894,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, struct fc_lport *lp = fip->lp; u32 desc_mask; - LIBFCOE_FIP_DBG("Clear Virtual Link received\n"); + FIP_DBG("Clear Virtual Link received\n"); if (!fcf) return; if (!fcf || !fc_host_port_id(lp->host)) @@ -968,9 +952,9 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, * reset only if all required descriptors were present and valid. */ if (desc_mask) { - LIBFCOE_FIP_DBG("missing descriptors mask %x\n", desc_mask); + FIP_DBG("missing descriptors mask %x\n", desc_mask); } else { - LIBFCOE_FIP_DBG("performing Clear Virtual Link\n"); + FIP_DBG("performing Clear Virtual Link\n"); fcoe_ctlr_reset(fip, FIP_ST_ENABLED); } } @@ -1018,6 +1002,10 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb) op = ntohs(fiph->fip_op); sub = fiph->fip_subcode; + FIP_DBG_LVL(2, "ver %x op %x/%x dl %x fl %x\n", + FIP_VER_DECAPS(fiph->fip_ver), op, sub, + ntohs(fiph->fip_dl_len), ntohs(fiph->fip_flags)); + if (FIP_VER_DECAPS(fiph->fip_ver) != FIP_VER) goto drop; if (ntohs(fiph->fip_dl_len) * FIP_BPW + sizeof(*fiph) > skb->len) @@ -1029,7 +1017,7 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb) fip->map_dest = 0; fip->state = FIP_ST_ENABLED; state = FIP_ST_ENABLED; - LIBFCOE_FIP_DBG("Using FIP mode\n"); + FIP_DBG("using FIP mode\n"); } spin_unlock_bh(&fip->lock); if (state != FIP_ST_ENABLED) @@ -1064,15 +1052,14 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip) struct fcoe_fcf *best = NULL; list_for_each_entry(fcf, &fip->fcfs, list) { - LIBFCOE_FIP_DBG("consider FCF for fab %llx VFID %d map %x " - "val %d\n", fcf->fabric_name, fcf->vfid, - fcf->fc_map, fcoe_ctlr_mtu_valid(fcf)); + FIP_DBG("consider FCF for fab %llx VFID %d map %x val %d\n", + fcf->fabric_name, fcf->vfid, + fcf->fc_map, fcoe_ctlr_mtu_valid(fcf)); if (!fcoe_ctlr_fcf_usable(fcf)) { - LIBFCOE_FIP_DBG("FCF for fab %llx map %x %svalid " - "%savailable\n", fcf->fabric_name, - fcf->fc_map, (fcf->flags & FIP_FL_SOL) - ? "" : "in", (fcf->flags & FIP_FL_AVAIL) - ? "" : "un"); + FIP_DBG("FCF for fab %llx map %x %svalid %savailable\n", + fcf->fabric_name, fcf->fc_map, + (fcf->flags & FIP_FL_SOL) ? "" : "in", + (fcf->flags & FIP_FL_AVAIL) ? "" : "un"); continue; } if (!best) { @@ -1082,8 +1069,7 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip) if (fcf->fabric_name != best->fabric_name || fcf->vfid != best->vfid || fcf->fc_map != best->fc_map) { - LIBFCOE_FIP_DBG("Conflicting fabric, VFID, " - "or FC-MAP\n"); + FIP_DBG("conflicting fabric, VFID, or FC-MAP\n"); return; } if (fcf->pri < best->pri) @@ -1127,7 +1113,7 @@ static void fcoe_ctlr_timeout(unsigned long arg) if (sel != fcf) { fcf = sel; /* the old FCF may have been freed */ if (sel) { - printk(KERN_INFO "libfcoe: host%d: FIP selected " + printk(KERN_INFO "host%d: FIP selected " "Fibre-Channel Forwarder MAC %s\n", fip->lp->host->host_no, print_mac(buf, sel->fcf_mac)); @@ -1137,7 +1123,7 @@ static void fcoe_ctlr_timeout(unsigned long arg) fip->ctlr_ka_time = jiffies + sel->fka_period; fip->link = 1; } else { - printk(KERN_NOTICE "libfcoe: host%d: " + printk(KERN_NOTICE "host%d: " "FIP Fibre-Channel Forwarder timed out. " "Starting FCF discovery.\n", fip->lp->host->host_no); @@ -1261,7 +1247,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) return -EINVAL; } fip->state = FIP_ST_NON_FIP; - LIBFCOE_FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n"); + FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n"); /* * FLOGI accepted. @@ -1290,7 +1276,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) memcpy(fip->dest_addr, sa, ETH_ALEN); fip->map_dest = 0; if (fip->state == FIP_ST_NON_FIP) - LIBFCOE_FIP_DBG("received FLOGI REQ, " + FIP_DBG("received FLOGI REQ, " "using non-FIP mode\n"); fip->state = FIP_ST_NON_FIP; } diff --git a/trunk/drivers/scsi/fnic/fnic_main.c b/trunk/drivers/scsi/fnic/fnic_main.c index 2c266c01dc5a..a84072865fc2 100644 --- a/trunk/drivers/scsi/fnic/fnic_main.c +++ b/trunk/drivers/scsi/fnic/fnic_main.c @@ -473,16 +473,16 @@ static int __devinit fnic_probe(struct pci_dev *pdev, * limitation for the device. Try 40-bit first, and * fail to 32-bit. */ - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40)); + err = pci_set_dma_mask(pdev, DMA_40BIT_MASK); if (err) { - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (err) { shost_printk(KERN_ERR, fnic->lport->host, "No usable DMA configuration " "aborting\n"); goto err_out_release_regions; } - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); if (err) { shost_printk(KERN_ERR, fnic->lport->host, "Unable to obtain 32-bit DMA " @@ -490,7 +490,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev, goto err_out_release_regions; } } else { - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)); + err = pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK); if (err) { shost_printk(KERN_ERR, fnic->lport->host, "Unable to obtain 40-bit DMA " diff --git a/trunk/drivers/scsi/fnic/fnic_scsi.c b/trunk/drivers/scsi/fnic/fnic_scsi.c index bfc996971b81..eabf36502856 100644 --- a/trunk/drivers/scsi/fnic/fnic_scsi.c +++ b/trunk/drivers/scsi/fnic/fnic_scsi.c @@ -245,7 +245,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, struct vnic_wq_copy *wq, struct fnic_io_req *io_req, struct scsi_cmnd *sc, - int sg_count) + u32 sg_count) { struct scatterlist *sg; struct fc_rport *rport = starget_to_rport(scsi_target(sc->device)); @@ -260,6 +260,9 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, char msg[2]; if (sg_count) { + BUG_ON(sg_count < 0); + BUG_ON(sg_count > FNIC_MAX_SG_DESC_CNT); + /* For each SGE, create a device desc entry */ desc = io_req->sgl_list; for_each_sg(scsi_sglist(sc), sg, sg_count, i) { @@ -341,7 +344,7 @@ int fnic_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) struct fnic *fnic; struct vnic_wq_copy *wq; int ret; - int sg_count; + u32 sg_count; unsigned long flags; unsigned long ptr; diff --git a/trunk/drivers/scsi/hosts.c b/trunk/drivers/scsi/hosts.c index 5fd2da494d08..89d41a424b33 100644 --- a/trunk/drivers/scsi/hosts.c +++ b/trunk/drivers/scsi/hosts.c @@ -40,7 +40,7 @@ #include "scsi_logging.h" -static atomic_t scsi_host_next_hn; /* host_no for next new host */ +static int scsi_host_next_hn; /* host_no for next new host */ static void scsi_host_cls_release(struct device *dev) @@ -333,11 +333,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) mutex_init(&shost->scan_mutex); - /* - * subtract one because we increment first then return, but we need to - * know what the next host number was before increment - */ - shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1; + shost->host_no = scsi_host_next_hn++; /* XXX(hch): still racy */ shost->dma_channel = 0xff; /* These three are default values which can be overridden */ diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c index 166d96450a0e..b4b805e8d7db 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2254,13 +2254,10 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, continue; if (crq->node_name && tgt->ids.node_name != crq->node_name) continue; - if (tgt->need_login && crq->event == IBMVFC_AE_ELS_LOGO) - tgt->logo_rcvd = 1; - if (!tgt->need_login || crq->event == IBMVFC_AE_ELS_PLOGI) { - ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); - ibmvfc_reinit_host(vhost); - } + ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); } + + ibmvfc_reinit_host(vhost); break; case IBMVFC_AE_LINK_DOWN: case IBMVFC_AE_ADAPTER_FAILED: @@ -2786,27 +2783,27 @@ static void ibmvfc_tasklet(void *data) spin_lock_irqsave(vhost->host->host_lock, flags); while (!done) { - /* Pull all the valid messages off the async CRQ */ - while ((async = ibmvfc_next_async_crq(vhost)) != NULL) { - ibmvfc_handle_async(async, vhost); - async->valid = 0; - } - /* Pull all the valid messages off the CRQ */ while ((crq = ibmvfc_next_crq(vhost)) != NULL) { ibmvfc_handle_crq(crq, vhost); crq->valid = 0; } - vio_enable_interrupts(vdev); - if ((async = ibmvfc_next_async_crq(vhost)) != NULL) { - vio_disable_interrupts(vdev); + /* Pull all the valid messages off the async CRQ */ + while ((async = ibmvfc_next_async_crq(vhost)) != NULL) { ibmvfc_handle_async(async, vhost); async->valid = 0; - } else if ((crq = ibmvfc_next_crq(vhost)) != NULL) { + } + + vio_enable_interrupts(vdev); + if ((crq = ibmvfc_next_crq(vhost)) != NULL) { vio_disable_interrupts(vdev); ibmvfc_handle_crq(crq, vhost); crq->valid = 0; + } else if ((async = ibmvfc_next_async_crq(vhost)) != NULL) { + vio_disable_interrupts(vdev); + ibmvfc_handle_async(async, vhost); + async->valid = 0; } else done = 1; } @@ -2930,11 +2927,7 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt) break; case IBMVFC_MAD_FAILED: default: - if ((rsp->status & IBMVFC_VIOS_FAILURE) && rsp->error == IBMVFC_PLOGI_REQUIRED) - level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi); - else if (tgt->logo_rcvd) - level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi); - else if (ibmvfc_retry_cmd(rsp->status, rsp->error)) + if (ibmvfc_retry_cmd(rsp->status, rsp->error)) level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli); else ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); @@ -3061,7 +3054,6 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt) return; kref_get(&tgt->kref); - tgt->logo_rcvd = 0; evt = ibmvfc_get_event(vhost); vhost->discovery_threads++; ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.h b/trunk/drivers/scsi/ibmvscsi/ibmvfc.h index 007fa1c9ef14..c2668d7d67f5 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.h @@ -605,7 +605,6 @@ struct ibmvfc_target { int need_login; int add_rport; int init_retries; - int logo_rcvd; u32 cancel_key; struct ibmvfc_service_parms service_parms; struct ibmvfc_service_parms service_parms_change; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index 9928704e235f..869a11bdccbd 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1095,14 +1095,9 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct) MAX_INDIRECT_BUFS); hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS; } - - if (hostdata->madapter_info.os_type == 3) { - enable_fast_fail(hostdata); - return; - } } - send_srp_login(hostdata); + enable_fast_fail(hostdata); } /** diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 5f045505a1f4..0f8bc772b112 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -131,13 +131,13 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { }; static const struct ipr_chip_t ipr_chip[] = { - { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] }, - { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] } + { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] }, + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] } }; static int ipr_max_bus_speeds [] = { @@ -7367,7 +7367,6 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, INIT_LIST_HEAD(&ioa_cfg->used_res_q); INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread); init_waitqueue_head(&ioa_cfg->reset_wait_q); - init_waitqueue_head(&ioa_cfg->msi_wait_q); ioa_cfg->sdt_state = INACTIVE; if (ipr_enable_cache) ioa_cfg->cache_state = CACHE_ENABLED; @@ -7399,107 +7398,24 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, } /** - * ipr_get_chip_info - Find adapter chip information + * ipr_get_chip_cfg - Find adapter chip configuration * @dev_id: PCI device id struct * * Return value: - * ptr to chip information on success / NULL on failure + * ptr to chip config on success / NULL on failure **/ -static const struct ipr_chip_t * __devinit -ipr_get_chip_info(const struct pci_device_id *dev_id) +static const struct ipr_chip_cfg_t * __devinit +ipr_get_chip_cfg(const struct pci_device_id *dev_id) { int i; for (i = 0; i < ARRAY_SIZE(ipr_chip); i++) if (ipr_chip[i].vendor == dev_id->vendor && ipr_chip[i].device == dev_id->device) - return &ipr_chip[i]; + return ipr_chip[i].cfg; return NULL; } -/** - * ipr_test_intr - Handle the interrupt generated in ipr_test_msi(). - * @pdev: PCI device struct - * - * Description: Simply set the msi_received flag to 1 indicating that - * Message Signaled Interrupts are supported. - * - * Return value: - * 0 on success / non-zero on failure - **/ -static irqreturn_t __devinit ipr_test_intr(int irq, void *devp) -{ - struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp; - unsigned long lock_flags = 0; - irqreturn_t rc = IRQ_HANDLED; - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - - ioa_cfg->msi_received = 1; - wake_up(&ioa_cfg->msi_wait_q); - - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return rc; -} - -/** - * ipr_test_msi - Test for Message Signaled Interrupt (MSI) support. - * @pdev: PCI device struct - * - * Description: The return value from pci_enable_msi() can not always be - * trusted. This routine sets up and initiates a test interrupt to determine - * if the interrupt is received via the ipr_test_intr() service routine. - * If the tests fails, the driver will fall back to LSI. - * - * Return value: - * 0 on success / non-zero on failure - **/ -static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, - struct pci_dev *pdev) -{ - int rc; - volatile u32 int_reg; - unsigned long lock_flags = 0; - - ENTER; - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - init_waitqueue_head(&ioa_cfg->msi_wait_q); - ioa_cfg->msi_received = 0; - ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); - writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg); - int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - - rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg); - if (rc) { - dev_err(&pdev->dev, "Can not assign irq %d\n", pdev->irq); - return rc; - } else if (ipr_debug) - dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); - - writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); - wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); - ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - if (!ioa_cfg->msi_received) { - /* MSI test failed */ - dev_info(&pdev->dev, "MSI test failed. Falling back to LSI.\n"); - rc = -EOPNOTSUPP; - } else if (ipr_debug) - dev_info(&pdev->dev, "MSI test succeeded.\n"); - - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - - free_irq(pdev->irq, ioa_cfg); - - LEAVE; - - return rc; -} - /** * ipr_probe_ioa - Allocates memory and does first stage of initialization * @pdev: PCI device struct @@ -7525,6 +7441,11 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, goto out; } + if (!(rc = pci_enable_msi(pdev))) + dev_info(&pdev->dev, "MSI enabled\n"); + else if (ipr_debug) + dev_info(&pdev->dev, "Cannot enable MSI\n"); + dev_info(&pdev->dev, "Found IOA with IRQ: %d\n", pdev->irq); host = scsi_host_alloc(&driver_template, sizeof(*ioa_cfg)); @@ -7540,16 +7461,14 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, ata_host_init(&ioa_cfg->ata_host, &pdev->dev, sata_port_info.flags, &ipr_sata_ops); - ioa_cfg->ipr_chip = ipr_get_chip_info(dev_id); + ioa_cfg->chip_cfg = ipr_get_chip_cfg(dev_id); - if (!ioa_cfg->ipr_chip) { + if (!ioa_cfg->chip_cfg) { dev_err(&pdev->dev, "Unknown adapter chipset 0x%04X 0x%04X\n", dev_id->vendor, dev_id->device); goto out_scsi_host_put; } - ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; - if (ipr_transop_timeout) ioa_cfg->transop_timeout = ipr_transop_timeout; else if (dev_id->driver_data & IPR_USE_LONG_TRANSOP_TIMEOUT) @@ -7600,18 +7519,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, goto cleanup_nomem; } - /* Enable MSI style interrupts if they are supported. */ - if (ioa_cfg->ipr_chip->intr_type == IPR_USE_MSI && !pci_enable_msi(pdev)) { - rc = ipr_test_msi(ioa_cfg, pdev); - if (rc == -EOPNOTSUPP) - pci_disable_msi(pdev); - else if (rc) - goto out_msi_disable; - else - dev_info(&pdev->dev, "MSI enabled with IRQ: %d\n", pdev->irq); - } else if (ipr_debug) - dev_info(&pdev->dev, "Cannot enable MSI.\n"); - /* Save away PCI config space for use following IOA reset */ rc = pci_save_state(pdev); @@ -7649,9 +7556,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, ioa_cfg->ioa_unit_checked = 1; ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); - rc = request_irq(pdev->irq, ipr_isr, - ioa_cfg->msi_received ? 0 : IRQF_SHARED, - IPR_NAME, ioa_cfg); + rc = request_irq(pdev->irq, ipr_isr, IRQF_SHARED, IPR_NAME, ioa_cfg); if (rc) { dev_err(&pdev->dev, "Couldn't register IRQ %d! rc=%d\n", @@ -7678,13 +7583,12 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, ipr_free_mem(ioa_cfg); cleanup_nomem: iounmap(ipr_regs); -out_msi_disable: - pci_disable_msi(pdev); out_release_regions: pci_release_regions(pdev); out_scsi_host_put: scsi_host_put(host); out_disable: + pci_disable_msi(pdev); pci_disable_device(pdev); goto out; } diff --git a/trunk/drivers/scsi/ipr.h b/trunk/drivers/scsi/ipr.h index 4b63dd6b1c81..79a3ae4fb2c7 100644 --- a/trunk/drivers/scsi/ipr.h +++ b/trunk/drivers/scsi/ipr.h @@ -37,8 +37,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.4.3" -#define IPR_DRIVER_DATE "(June 10, 2009)" +#define IPR_DRIVER_VERSION "2.4.2" +#define IPR_DRIVER_DATE "(January 21, 2009)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -1025,9 +1025,6 @@ struct ipr_chip_cfg_t { struct ipr_chip_t { u16 vendor; u16 device; - u16 intr_type; -#define IPR_USE_LSI 0x00 -#define IPR_USE_MSI 0x01 const struct ipr_chip_cfg_t *cfg; }; @@ -1097,7 +1094,6 @@ struct ipr_ioa_cfg { u8 needs_hard_reset:1; u8 dual_raid:1; u8 needs_warm_reset:1; - u8 msi_received:1; u8 revid; @@ -1163,7 +1159,6 @@ struct ipr_ioa_cfg { unsigned int transop_timeout; const struct ipr_chip_cfg_t *chip_cfg; - const struct ipr_chip_t *ipr_chip; void __iomem *hdw_dma_regs; /* iomapped PCI memory space */ unsigned long hdw_dma_regs_pci; /* raw PCI memory space */ @@ -1184,7 +1179,6 @@ struct ipr_ioa_cfg { struct work_struct work_q; wait_queue_head_t reset_wait_q; - wait_queue_head_t msi_wait_q; struct ipr_dump *dump; enum ipr_sdt_state sdt_state; diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index 518dbd91df85..b7c092d63bbe 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -253,6 +253,8 @@ static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn, if (r < 0) { iscsi_tcp_segment_unmap(segment); + if (copied || r == -EAGAIN) + break; return r; } copied += r; @@ -273,17 +275,11 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn) while (1) { rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment); - /* - * We may not have been able to send data because the conn - * is getting stopped. libiscsi will know so propogate err - * for it to do the right thing. - */ - if (rc == -EAGAIN) - return rc; - else if (rc < 0) { + if (rc < 0) { rc = ISCSI_ERR_XMIT_FAILED; goto error; - } else if (rc == 0) + } + if (rc == 0) break; consumed += rc; diff --git a/trunk/drivers/scsi/libfc/fc_disc.c b/trunk/drivers/scsi/libfc/fc_disc.c index 6fabf66972b9..4c880656990b 100644 --- a/trunk/drivers/scsi/libfc/fc_disc.c +++ b/trunk/drivers/scsi/libfc/fc_disc.c @@ -45,6 +45,14 @@ #define FC_DISC_DELAY 3 +static int fc_disc_debug; + +#define FC_DEBUG_DISC(fmt...) \ + do { \ + if (fc_disc_debug) \ + FC_DBG(fmt); \ + } while (0) + static void fc_disc_gpn_ft_req(struct fc_disc *); static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); static int fc_disc_new_target(struct fc_disc *, struct fc_rport *, @@ -129,8 +137,8 @@ static void fc_disc_rport_callback(struct fc_lport *lport, struct fc_rport_libfc_priv *rdata = rport->dd_data; struct fc_disc *disc = &lport->disc; - FC_DISC_DBG(disc, "Received a %d event for port (%6x)\n", event, - rport->port_id); + FC_DEBUG_DISC("Received a %d event for port (%6x)\n", event, + rport->port_id); switch (event) { case RPORT_EV_CREATED: @@ -183,7 +191,8 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, lport = disc->lport; - FC_DISC_DBG(disc, "Received an RSCN event\n"); + FC_DEBUG_DISC("Received an RSCN event on port (%6x)\n", + fc_host_port_id(lport->host)); /* make sure the frame contains an RSCN message */ rp = fc_frame_payload_get(fp, sizeof(*rp)); @@ -216,8 +225,8 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, */ switch (fmt) { case ELS_ADDR_FMT_PORT: - FC_DISC_DBG(disc, "Port address format for port " - "(%6x)\n", ntoh24(pp->rscn_fid)); + FC_DEBUG_DISC("Port address format for port (%6x)\n", + ntoh24(pp->rscn_fid)); dp = kzalloc(sizeof(*dp), GFP_KERNEL); if (!dp) { redisc = 1; @@ -234,19 +243,19 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, case ELS_ADDR_FMT_DOM: case ELS_ADDR_FMT_FAB: default: - FC_DISC_DBG(disc, "Address format is (%d)\n", fmt); + FC_DEBUG_DISC("Address format is (%d)\n", fmt); redisc = 1; break; } } lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); if (redisc) { - FC_DISC_DBG(disc, "RSCN received: rediscovering\n"); + FC_DEBUG_DISC("RSCN received: rediscovering\n"); fc_disc_restart(disc); } else { - FC_DISC_DBG(disc, "RSCN received: not rediscovering. " - "redisc %d state %d in_prog %d\n", - redisc, lport->state, disc->pending); + FC_DEBUG_DISC("RSCN received: not rediscovering. " + "redisc %d state %d in_prog %d\n", + redisc, lport->state, disc->pending); list_for_each_entry_safe(dp, next, &disc_ports, peers) { list_del(&dp->peers); rport = lport->tt.rport_lookup(lport, dp->ids.port_id); @@ -261,7 +270,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, fc_frame_free(fp); return; reject: - FC_DISC_DBG(disc, "Received a bad RSCN frame\n"); + FC_DEBUG_DISC("Received a bad RSCN frame\n"); rjt_data.fp = NULL; rjt_data.reason = ELS_RJT_LOGIC; rjt_data.explan = ELS_EXPL_NONE; @@ -293,8 +302,7 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp, mutex_unlock(&disc->disc_mutex); break; default: - FC_DISC_DBG(disc, "Received an unsupported request, " - "the opcode is (%x)\n", op); + FC_DBG("Received an unsupported request. opcode (%x)\n", op); break; } } @@ -312,10 +320,12 @@ static void fc_disc_restart(struct fc_disc *disc) struct fc_rport_libfc_priv *rdata, *next; struct fc_lport *lport = disc->lport; - FC_DISC_DBG(disc, "Restarting discovery\n"); + FC_DEBUG_DISC("Restarting discovery for port (%6x)\n", + fc_host_port_id(lport->host)); list_for_each_entry_safe(rdata, next, &disc->rports, peers) { rport = PRIV_TO_RPORT(rdata); + FC_DEBUG_DISC("list_del(%6x)\n", rport->port_id); list_del(&rdata->peers); lport->tt.rport_logoff(rport); } @@ -475,7 +485,8 @@ static void fc_disc_done(struct fc_disc *disc) struct fc_lport *lport = disc->lport; enum fc_disc_event event; - FC_DISC_DBG(disc, "Discovery complete\n"); + FC_DEBUG_DISC("Discovery complete for port (%6x)\n", + fc_host_port_id(lport->host)); event = disc->event; disc->event = DISC_EV_NONE; @@ -499,10 +510,10 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) { struct fc_lport *lport = disc->lport; unsigned long delay = 0; - - FC_DISC_DBG(disc, "Error %ld, retries %d/%d\n", - PTR_ERR(fp), disc->retry_count, - FC_DISC_RETRY_LIMIT); + if (fc_disc_debug) + FC_DBG("Error %ld, retries %d/%d\n", + PTR_ERR(fp), disc->retry_count, + FC_DISC_RETRY_LIMIT); if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { /* @@ -638,9 +649,9 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) &disc->rogue_rports); lport->tt.rport_login(rport); } else - printk(KERN_WARNING "libfc: Failed to allocate " - "memory for the newly discovered port " - "(%6x)\n", dp.ids.port_id); + FC_DBG("Failed to allocate memory for " + "the newly discovered port (%6x)\n", + dp.ids.port_id); } if (np->fp_flags & FC_NS_FID_LAST) { @@ -660,8 +671,9 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) */ if (error == 0 && len > 0 && len < sizeof(*np)) { if (np != &disc->partial_buf) { - FC_DISC_DBG(disc, "Partial buffer remains " - "for discovery\n"); + FC_DEBUG_DISC("Partial buffer remains " + "for discovery by (%6x)\n", + fc_host_port_id(lport->host)); memcpy(&disc->partial_buf, np, len); } disc->buf_len = (unsigned char) len; @@ -709,7 +721,8 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, int error; mutex_lock(&disc->disc_mutex); - FC_DISC_DBG(disc, "Received a GPN_FT response\n"); + FC_DEBUG_DISC("Received a GPN_FT response on port (%6x)\n", + fc_host_port_id(disc->lport->host)); if (IS_ERR(fp)) { fc_disc_error(disc, fp); @@ -725,30 +738,30 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, disc->seq_count == 0) { cp = fc_frame_payload_get(fp, sizeof(*cp)); if (!cp) { - FC_DISC_DBG(disc, "GPN_FT response too short, len %d\n", - fr_len(fp)); + FC_DBG("GPN_FT response too short, len %d\n", + fr_len(fp)); } else if (ntohs(cp->ct_cmd) == FC_FS_ACC) { /* Accepted, parse the response. */ buf = cp + 1; len -= sizeof(*cp); } else if (ntohs(cp->ct_cmd) == FC_FS_RJT) { - FC_DISC_DBG(disc, "GPN_FT rejected reason %x exp %x " - "(check zoning)\n", cp->ct_reason, - cp->ct_explan); + FC_DBG("GPN_FT rejected reason %x exp %x " + "(check zoning)\n", cp->ct_reason, + cp->ct_explan); disc->event = DISC_EV_FAILED; fc_disc_done(disc); } else { - FC_DISC_DBG(disc, "GPN_FT unexpected response code " - "%x\n", ntohs(cp->ct_cmd)); + FC_DBG("GPN_FT unexpected response code %x\n", + ntohs(cp->ct_cmd)); } } else if (fr_sof(fp) == FC_SOF_N3 && seq_cnt == disc->seq_count) { buf = fh + 1; } else { - FC_DISC_DBG(disc, "GPN_FT unexpected frame - out of sequence? " - "seq_cnt %x expected %x sof %x eof %x\n", - seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp)); + FC_DBG("GPN_FT unexpected frame - out of sequence? " + "seq_cnt %x expected %x sof %x eof %x\n", + seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp)); } if (buf) { error = fc_disc_gpn_ft_parse(disc, buf, len); diff --git a/trunk/drivers/scsi/libfc/fc_exch.c b/trunk/drivers/scsi/libfc/fc_exch.c index 2bc22be5f849..7af9bceb8aa9 100644 --- a/trunk/drivers/scsi/libfc/fc_exch.c +++ b/trunk/drivers/scsi/libfc/fc_exch.c @@ -32,7 +32,18 @@ #include #include -static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ +/* + * fc_exch_debug can be set in debugger or at compile time to get more logs. + */ +static int fc_exch_debug; + +#define FC_DEBUG_EXCH(fmt...) \ + do { \ + if (fc_exch_debug) \ + FC_DBG(fmt); \ + } while (0) + +static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ /* * Structure and function definitions for managing Fibre Channel Exchanges @@ -322,8 +333,8 @@ static inline void fc_exch_timer_set_locked(struct fc_exch *ep, if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) return; - FC_EXCH_DBG(ep, "Exchange timed out, notifying the upper layer\n"); - + FC_DEBUG_EXCH("Exchange (%4x) timed out, notifying the upper layer\n", + ep->xid); if (schedule_delayed_work(&ep->timeout_work, msecs_to_jiffies(timer_msec))) fc_exch_hold(ep); /* hold for timer */ @@ -534,7 +545,7 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, /* alloc a new xid */ xid = fc_em_alloc_xid(mp, fp); if (!xid) { - printk(KERN_WARNING "libfc: Failed to allocate an exhange\n"); + printk(KERN_ERR "fc_em_alloc_xid() failed\n"); goto err; } } @@ -809,8 +820,8 @@ static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp) struct fc_exch *ep = fc_seq_exch(sp); sp = fc_seq_alloc(ep, ep->seq_id++); - FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n", - ep->f_ctl, sp->id); + FC_DEBUG_EXCH("exch %4x f_ctl %6x seq %2x\n", + ep->xid, ep->f_ctl, sp->id); return sp; } /* @@ -890,7 +901,7 @@ void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, fc_exch_els_rec(sp, els_data->fp); break; default: - FC_EXCH_DBG(fc_seq_exch(sp), "Invalid ELS CMD:%x\n", els_cmd); + FC_DBG("Invalid ELS CMD:%x\n", els_cmd); } } EXPORT_SYMBOL(fc_seq_els_rsp_send); @@ -1123,7 +1134,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp, lp->tt.lport_recv(lp, sp, fp); fc_exch_release(ep); /* release from lookup */ } else { - FC_EM_DBG(mp, "exch/seq lookup failed: reject %x\n", reject); + FC_DEBUG_EXCH("exch/seq lookup failed: reject %x\n", reject); fc_frame_free(fp); } } @@ -1231,10 +1242,10 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */ if (!sp) { atomic_inc(&mp->stats.xid_not_found); - FC_EM_DBG(mp, "seq lookup failed\n"); + FC_DEBUG_EXCH("seq lookup failed\n"); } else { atomic_inc(&mp->stats.non_bls_resp); - FC_EM_DBG(mp, "non-BLS response to sequence"); + FC_DEBUG_EXCH("non-BLS response to sequence"); } fc_frame_free(fp); } @@ -1255,8 +1266,8 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) int rc = 1, has_rec = 0; fh = fc_frame_header_get(fp); - FC_EXCH_DBG(ep, "exch: BLS rctl %x - %s\n", fh->fh_r_ctl, - fc_exch_rctl_name(fh->fh_r_ctl)); + FC_DEBUG_EXCH("exch: BLS rctl %x - %s\n", + fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl)); if (cancel_delayed_work_sync(&ep->timeout_work)) fc_exch_release(ep); /* release from pending timer hold */ @@ -1348,9 +1359,9 @@ static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp) case FC_RCTL_ACK_0: break; default: - FC_EXCH_DBG(ep, "BLS rctl %x - %s received", - fh->fh_r_ctl, - fc_exch_rctl_name(fh->fh_r_ctl)); + FC_DEBUG_EXCH("BLS rctl %x - %s received", + fh->fh_r_ctl, + fc_exch_rctl_name(fh->fh_r_ctl)); break; } fc_frame_free(fp); @@ -1588,8 +1599,7 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg) if (err == -FC_EX_CLOSED || err == -FC_EX_TIMEOUT) goto cleanup; - FC_EXCH_DBG(aborted_ep, "Cannot process RRQ, " - "frame error %d\n", err); + FC_DBG("Cannot process RRQ, because of frame error %d\n", err); return; } @@ -1598,13 +1608,12 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg) switch (op) { case ELS_LS_RJT: - FC_EXCH_DBG(aborted_ep, "LS_RJT for RRQ"); + FC_DBG("LS_RJT for RRQ"); /* fall through */ case ELS_LS_ACC: goto cleanup; default: - FC_EXCH_DBG(aborted_ep, "unexpected response op %x " - "for RRQ", op); + FC_DBG("unexpected response op %x for RRQ", op); return; } @@ -1731,8 +1740,8 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, size_t len; if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) { - FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n", - min_xid, max_xid); + FC_DBG("Invalid min_xid 0x:%x and max_xid 0x:%x\n", + min_xid, max_xid); return NULL; } @@ -1869,8 +1878,7 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, /* lport lock ? */ if (!lp || !mp || (lp->state == LPORT_ST_NONE)) { - FC_LPORT_DBG(lp, "Receiving frames for an lport that " - "has not been initialized correctly\n"); + FC_DBG("fc_lport or EM is not allocated and configured"); fc_frame_free(fp); return; } @@ -1896,7 +1904,7 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, fc_exch_recv_req(lp, mp, fp); break; default: - FC_EM_DBG(mp, "dropping invalid frame (eof %x)", fr_eof(fp)); + FC_DBG("dropping invalid frame (eof %x)", fr_eof(fp)); fc_frame_free(fp); break; } diff --git a/trunk/drivers/scsi/libfc/fc_fcp.c b/trunk/drivers/scsi/libfc/fc_fcp.c index e303e0d12c4b..ad8b747837b0 100644 --- a/trunk/drivers/scsi/libfc/fc_fcp.c +++ b/trunk/drivers/scsi/libfc/fc_fcp.c @@ -43,9 +43,13 @@ MODULE_AUTHOR("Open-FCoE.org"); MODULE_DESCRIPTION("libfc"); MODULE_LICENSE("GPL v2"); -unsigned int fc_debug_logging; -module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); +static int fc_fcp_debug; + +#define FC_DEBUG_FCP(fmt...) \ + do { \ + if (fc_fcp_debug) \ + FC_DBG(fmt); \ + } while (0) static struct kmem_cache *scsi_pkt_cachep; @@ -343,8 +347,8 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && fc_frame_crc_check(fp)) goto crc_err; - FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx " - "data_len %x\n", len, offset, fsp->data_len); + FC_DEBUG_FCP("data received past end. len %zx offset %zx " + "data_len %x\n", len, offset, fsp->data_len); fc_fcp_retry_cmd(fsp); return; } @@ -407,8 +411,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) stats->ErrorFrames++; /* FIXME - per cpu count, not total count! */ if (stats->InvalidCRCCount++ < 5) - printk(KERN_WARNING "libfc: CRC error on data " - "frame for port (%6x)\n", + printk(KERN_WARNING "CRC error on data frame for port (%6x)\n", fc_host_port_id(lp->host)); /* * Assume the frame is total garbage. @@ -472,14 +475,14 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, WARN_ON(seq_blen <= 0); if (unlikely(offset + seq_blen > fsp->data_len)) { /* this should never happen */ - FC_FCP_DBG(fsp, "xfer-ready past end. seq_blen %zx " - "offset %zx\n", seq_blen, offset); + FC_DEBUG_FCP("xfer-ready past end. seq_blen %zx offset %zx\n", + seq_blen, offset); fc_fcp_send_abort(fsp); return 0; } else if (offset != fsp->xfer_len) { /* Out of Order Data Request - no problem, but unexpected. */ - FC_FCP_DBG(fsp, "xfer-ready non-contiguous. " - "seq_blen %zx offset %zx\n", seq_blen, offset); + FC_DEBUG_FCP("xfer-ready non-contiguous. " + "seq_blen %zx offset %zx\n", seq_blen, offset); } /* @@ -490,7 +493,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, t_blen = fsp->max_payload; if (lp->seq_offload) { t_blen = min(seq_blen, (size_t)lp->lso_max); - FC_FCP_DBG(fsp, "fsp=%p:lso:blen=%zx lso_max=0x%x t_blen=%zx\n", + FC_DEBUG_FCP("fsp=%p:lso:blen=%zx lso_max=0x%x t_blen=%zx\n", fsp, seq_blen, lp->lso_max, t_blen); } @@ -691,7 +694,7 @@ static void fc_fcp_reduce_can_queue(struct fc_lport *lp) if (!can_queue) can_queue = 1; lp->host->can_queue = can_queue; - shost_printk(KERN_ERR, lp->host, "libfc: Could not allocate frame.\n" + shost_printk(KERN_ERR, lp->host, "Could not allocate frame.\n" "Reducing can_queue to %d.\n", can_queue); done: spin_unlock_irqrestore(lp->host->host_lock, flags); @@ -765,7 +768,7 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg) fc_fcp_resp(fsp, fp); } else { - FC_FCP_DBG(fsp, "unexpected frame. r_ctl %x\n", r_ctl); + FC_DBG("unexpected frame. r_ctl %x\n", r_ctl); } unlock: fc_fcp_unlock_pkt(fsp); @@ -874,17 +877,17 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) return; } fsp->status_code = FC_DATA_OVRRUN; - FC_FCP_DBG(fsp, "tgt %6x xfer len %zx greater than expected, " - "len %x, data len %x\n", - fsp->rport->port_id, - fsp->xfer_len, expected_len, fsp->data_len); + FC_DBG("tgt %6x xfer len %zx greater than expected len %x. " + "data len %x\n", + fsp->rport->port_id, + fsp->xfer_len, expected_len, fsp->data_len); } fc_fcp_complete_locked(fsp); return; len_err: - FC_FCP_DBG(fsp, "short FCP response. flags 0x%x len %u respl %u " - "snsl %u\n", flags, fr_len(fp), respl, snsl); + FC_DBG("short FCP response. flags 0x%x len %u respl %u snsl %u\n", + flags, fr_len(fp), respl, snsl); err: fsp->status_code = FC_ERROR; fc_fcp_complete_locked(fsp); @@ -1104,11 +1107,13 @@ static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) if (fc_fcp_lock_pkt(fsp)) return; - if (error == -FC_EX_CLOSED) { + switch (error) { + case -FC_EX_CLOSED: fc_fcp_retry_cmd(fsp); goto unlock; + default: + FC_DBG("unknown error %ld\n", PTR_ERR(fp)); } - /* * clear abort pending, because the lower layer * decided to force completion. @@ -1140,10 +1145,10 @@ static int fc_fcp_pkt_abort(struct fc_lport *lp, struct fc_fcp_pkt *fsp) fsp->wait_for_comp = 0; if (!rc) { - FC_FCP_DBG(fsp, "target abort cmd failed\n"); + FC_DBG("target abort cmd failed\n"); rc = FAILED; } else if (fsp->state & FC_SRB_ABORTED) { - FC_FCP_DBG(fsp, "target abort cmd passed\n"); + FC_DBG("target abort cmd passed\n"); rc = SUCCESS; fc_fcp_complete_locked(fsp); } @@ -1208,7 +1213,7 @@ static int fc_lun_reset(struct fc_lport *lp, struct fc_fcp_pkt *fsp, spin_unlock_bh(&fsp->scsi_pkt_lock); if (!rc) { - FC_SCSI_DBG(lp, "lun reset failed\n"); + FC_DBG("lun reset failed\n"); return FAILED; } @@ -1216,7 +1221,7 @@ static int fc_lun_reset(struct fc_lport *lp, struct fc_fcp_pkt *fsp, if (fsp->cdb_status != FCP_TMF_CMPL) return FAILED; - FC_SCSI_DBG(lp, "lun reset to lun %u completed\n", lun); + FC_DBG("lun reset to lun %u completed\n", lun); fc_fcp_cleanup_each_cmd(lp, id, lun, FC_CMD_ABORTED); return SUCCESS; } @@ -1383,13 +1388,13 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) rjt = fc_frame_payload_get(fp, sizeof(*rjt)); switch (rjt->er_reason) { default: - FC_FCP_DBG(fsp, "device %x unexpected REC reject " - "reason %d expl %d\n", - fsp->rport->port_id, rjt->er_reason, - rjt->er_explan); + FC_DEBUG_FCP("device %x unexpected REC reject " + "reason %d expl %d\n", + fsp->rport->port_id, rjt->er_reason, + rjt->er_explan); /* fall through */ case ELS_RJT_UNSUP: - FC_FCP_DBG(fsp, "device does not support REC\n"); + FC_DEBUG_FCP("device does not support REC\n"); rp = fsp->rport->dd_data; /* * if we do not spport RECs or got some bogus @@ -1509,8 +1514,8 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) break; default: - FC_FCP_DBG(fsp, "REC %p fid %x error unexpected error %d\n", - fsp, fsp->rport->port_id, error); + FC_DBG("REC %p fid %x error unexpected error %d\n", + fsp, fsp->rport->port_id, error); fsp->status_code = FC_CMD_PLOGO; /* fall through */ @@ -1519,9 +1524,9 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) * Assume REC or LS_ACC was lost. * The exchange manager will have aborted REC, so retry. */ - FC_FCP_DBG(fsp, "REC fid %x error error %d retry %d/%d\n", - fsp->rport->port_id, error, fsp->recov_retry, - FC_MAX_RECOV_RETRY); + FC_DBG("REC fid %x error error %d retry %d/%d\n", + fsp->rport->port_id, error, fsp->recov_retry, + FC_MAX_RECOV_RETRY); if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) fc_fcp_rec(fsp); else @@ -2006,11 +2011,9 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd) if (lp->state != LPORT_ST_READY) return rc; - FC_SCSI_DBG(lp, "Resetting rport (%6x)\n", rport->port_id); - fsp = fc_fcp_pkt_alloc(lp, GFP_NOIO); if (fsp == NULL) { - printk(KERN_WARNING "libfc: could not allocate scsi_pkt\n"); + FC_DBG("could not allocate scsi_pkt\n"); sc_cmd->result = DID_NO_CONNECT << 16; goto out; } @@ -2045,21 +2048,17 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) struct fc_lport *lp = shost_priv(shost); unsigned long wait_tmo; - FC_SCSI_DBG(lp, "Resetting host\n"); - lp->tt.lport_reset(lp); wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT; while (!fc_fcp_lport_queue_ready(lp) && time_before(jiffies, wait_tmo)) msleep(1000); if (fc_fcp_lport_queue_ready(lp)) { - shost_printk(KERN_INFO, shost, "libfc: Host reset succeeded " - "on port (%6x)\n", fc_host_port_id(lp->host)); + shost_printk(KERN_INFO, shost, "Host reset succeeded.\n"); return SUCCESS; } else { - shost_printk(KERN_INFO, shost, "libfc: Host reset failed, " - "port (%6x) is not ready.\n", - fc_host_port_id(lp->host)); + shost_printk(KERN_INFO, shost, "Host reset failed. " + "lport not ready.\n"); return FAILED; } } @@ -2118,8 +2117,7 @@ void fc_fcp_destroy(struct fc_lport *lp) struct fc_fcp_internal *si = fc_get_scsi_internal(lp); if (!list_empty(&si->scsi_pkt_queue)) - printk(KERN_ERR "libfc: Leaked SCSI packets when destroying " - "port (%6x)\n", fc_host_port_id(lp->host)); + printk(KERN_ERR "Leaked scsi packets.\n"); mempool_destroy(si->scsi_pkt_pool); kfree(si); @@ -2168,8 +2166,7 @@ static int __init libfc_init(void) sizeof(struct fc_fcp_pkt), 0, SLAB_HWCACHE_ALIGN, NULL); if (scsi_pkt_cachep == NULL) { - printk(KERN_ERR "libfc: Unable to allocate SRB cache, " - "module load failed!"); + FC_DBG("Unable to allocate SRB cache...module load failed!"); return -ENOMEM; } diff --git a/trunk/drivers/scsi/libfc/fc_lport.c b/trunk/drivers/scsi/libfc/fc_lport.c index 745fa5555d6a..e0c247724d2b 100644 --- a/trunk/drivers/scsi/libfc/fc_lport.c +++ b/trunk/drivers/scsi/libfc/fc_lport.c @@ -101,6 +101,14 @@ #define DNS_DELAY 3 /* Discovery delay after RSCN (in seconds)*/ +static int fc_lport_debug; + +#define FC_DEBUG_LPORT(fmt...) \ + do { \ + if (fc_lport_debug) \ + FC_DBG(fmt); \ + } while (0) + static void fc_lport_error(struct fc_lport *, struct fc_frame *); static void fc_lport_enter_reset(struct fc_lport *); @@ -143,8 +151,8 @@ static void fc_lport_rport_callback(struct fc_lport *lport, struct fc_rport *rport, enum fc_rport_event event) { - FC_LPORT_DBG(lport, "Received a %d event for port (%6x)\n", event, - rport->port_id); + FC_DEBUG_LPORT("Received a %d event for port (%6x)\n", event, + rport->port_id); switch (event) { case RPORT_EV_CREATED: @@ -154,19 +162,19 @@ static void fc_lport_rport_callback(struct fc_lport *lport, lport->dns_rp = rport; fc_lport_enter_rpn_id(lport); } else { - FC_LPORT_DBG(lport, "Received an CREATED event " - "on port (%6x) for the directory " - "server, but the lport is not " - "in the DNS state, it's in the " - "%d state", rport->port_id, - lport->state); + FC_DEBUG_LPORT("Received an CREATED event on " + "port (%6x) for the directory " + "server, but the lport is not " + "in the DNS state, it's in the " + "%d state", rport->port_id, + lport->state); lport->tt.rport_logoff(rport); } mutex_unlock(&lport->lp_mutex); } else - FC_LPORT_DBG(lport, "Received an event for port (%6x) " - "which is not the directory server\n", - rport->port_id); + FC_DEBUG_LPORT("Received an event for port (%6x) " + "which is not the directory server\n", + rport->port_id); break; case RPORT_EV_LOGO: case RPORT_EV_FAILED: @@ -177,9 +185,9 @@ static void fc_lport_rport_callback(struct fc_lport *lport, mutex_unlock(&lport->lp_mutex); } else - FC_LPORT_DBG(lport, "Received an event for port (%6x) " - "which is not the directory server\n", - rport->port_id); + FC_DEBUG_LPORT("Received an event for port (%6x) " + "which is not the directory server\n", + rport->port_id); break; case RPORT_EV_NONE: break; @@ -355,8 +363,8 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type) static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp, struct fc_lport *lport) { - FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Received RLIR request while in state %s\n", + fc_lport_state(lport)); lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); fc_frame_free(fp); @@ -381,8 +389,8 @@ static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp, void *dp; u32 f_ctl; - FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Received RLIR request while in state %s\n", + fc_lport_state(lport)); len = fr_len(in_fp) - sizeof(struct fc_frame_header); pp = fc_frame_payload_get(in_fp, len); @@ -429,8 +437,8 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, size_t len; u32 f_ctl; - FC_LPORT_DBG(lport, "Received RNID request while in state %s\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Received RNID request while in state %s\n", + fc_lport_state(lport)); req = fc_frame_payload_get(in_fp, sizeof(*req)); if (!req) { @@ -490,8 +498,8 @@ static void fc_lport_recv_adisc_req(struct fc_seq *sp, struct fc_frame *in_fp, size_t len; u32 f_ctl; - FC_LPORT_DBG(lport, "Received ADISC request while in state %s\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Received ADISC request while in state %s\n", + fc_lport_state(lport)); req = fc_frame_payload_get(in_fp, sizeof(*req)); if (!req) { @@ -566,8 +574,8 @@ EXPORT_SYMBOL(fc_fabric_login); */ void fc_linkup(struct fc_lport *lport) { - printk(KERN_INFO "libfc: Link up on port (%6x)\n", - fc_host_port_id(lport->host)); + FC_DEBUG_LPORT("Link is up for port (%6x)\n", + fc_host_port_id(lport->host)); mutex_lock(&lport->lp_mutex); if (!lport->link_up) { @@ -587,8 +595,8 @@ EXPORT_SYMBOL(fc_linkup); void fc_linkdown(struct fc_lport *lport) { mutex_lock(&lport->lp_mutex); - printk(KERN_INFO "libfc: Link down on port (%6x)\n", - fc_host_port_id(lport->host)); + FC_DEBUG_LPORT("Link is down for port (%6x)\n", + fc_host_port_id(lport->host)); if (lport->link_up) { lport->link_up = 0; @@ -693,11 +701,12 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) { switch (event) { case DISC_EV_SUCCESS: - FC_LPORT_DBG(lport, "Discovery succeeded\n"); + FC_DEBUG_LPORT("Got a SUCCESS event for port (%6x)\n", + fc_host_port_id(lport->host)); break; case DISC_EV_FAILED: - printk(KERN_ERR "libfc: Discovery failed for port (%6x)\n", - fc_host_port_id(lport->host)); + FC_DEBUG_LPORT("Got a FAILED event for port (%6x)\n", + fc_host_port_id(lport->host)); mutex_lock(&lport->lp_mutex); fc_lport_enter_reset(lport); mutex_unlock(&lport->lp_mutex); @@ -717,8 +726,8 @@ void fc_lport_disc_callback(struct fc_lport *lport, enum fc_disc_event event) */ static void fc_lport_enter_ready(struct fc_lport *lport) { - FC_LPORT_DBG(lport, "Entered READY from state %s\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Port (%6x) entered Ready from state %s\n", + fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_READY); @@ -753,8 +762,8 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, u32 local_fid; u32 f_ctl; - FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Received FLOGI request while in state %s\n", + fc_lport_state(lport)); fh = fc_frame_header_get(rx_fp); remote_fid = ntoh24(fh->fh_s_id); @@ -763,11 +772,12 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, goto out; remote_wwpn = get_unaligned_be64(&flp->fl_wwpn); if (remote_wwpn == lport->wwpn) { - printk(KERN_WARNING "libfc: Received FLOGI from port " - "with same WWPN %llx\n", remote_wwpn); + FC_DBG("FLOGI from port with same WWPN %llx " + "possible configuration error\n", + (unsigned long long)remote_wwpn); goto out; } - FC_LPORT_DBG(lport, "FLOGI from port WWPN %llx\n", remote_wwpn); + FC_DBG("FLOGI from port WWPN %llx\n", (unsigned long long)remote_wwpn); /* * XXX what is the right thing to do for FIDs? @@ -899,8 +909,7 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, } } } else { - FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)\n", - fr_eof(fp)); + FC_DBG("dropping invalid frame (eof %x)\n", fr_eof(fp)); fc_frame_free(fp); } mutex_unlock(&lport->lp_mutex); @@ -938,8 +947,8 @@ EXPORT_SYMBOL(fc_lport_reset); */ static void fc_lport_enter_reset(struct fc_lport *lport) { - FC_LPORT_DBG(lport, "Entered RESET state from %s state\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Port (%6x) entered RESET state from %s state\n", + fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_RESET); @@ -973,9 +982,9 @@ static void fc_lport_enter_reset(struct fc_lport *lport) static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) { unsigned long delay = 0; - FC_LPORT_DBG(lport, "Error %ld in state %s, retries %d\n", - PTR_ERR(fp), fc_lport_state(lport), - lport->retry_count); + FC_DEBUG_LPORT("Error %ld in state %s, retries %d\n", + PTR_ERR(fp), fc_lport_state(lport), + lport->retry_count); if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { /* @@ -1031,11 +1040,11 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&lport->lp_mutex); - FC_LPORT_DBG(lport, "Received a RFT_ID response\n"); + FC_DEBUG_LPORT("Received a RFT_ID response\n"); if (lport->state != LPORT_ST_RFT_ID) { - FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state " - "%s\n", fc_lport_state(lport)); + FC_DBG("Received a RFT_ID response, but in state %s\n", + fc_lport_state(lport)); if (IS_ERR(fp)) goto err; goto out; @@ -1085,11 +1094,11 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&lport->lp_mutex); - FC_LPORT_DBG(lport, "Received a RPN_ID response\n"); + FC_DEBUG_LPORT("Received a RPN_ID response\n"); if (lport->state != LPORT_ST_RPN_ID) { - FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state " - "%s\n", fc_lport_state(lport)); + FC_DBG("Received a RPN_ID response, but in state %s\n", + fc_lport_state(lport)); if (IS_ERR(fp)) goto err; goto out; @@ -1137,11 +1146,11 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&lport->lp_mutex); - FC_LPORT_DBG(lport, "Received a SCR response\n"); + FC_DEBUG_LPORT("Received a SCR response\n"); if (lport->state != LPORT_ST_SCR) { - FC_LPORT_DBG(lport, "Received a SCR response, but in state " - "%s\n", fc_lport_state(lport)); + FC_DBG("Received a SCR response, but in state %s\n", + fc_lport_state(lport)); if (IS_ERR(fp)) goto err; goto out; @@ -1175,8 +1184,8 @@ static void fc_lport_enter_scr(struct fc_lport *lport) { struct fc_frame *fp; - FC_LPORT_DBG(lport, "Entered SCR state from %s state\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Port (%6x) entered SCR state from %s state\n", + fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_SCR); @@ -1204,8 +1213,8 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport) struct fc_ns_fts *lps; int i; - FC_LPORT_DBG(lport, "Entered RFT_ID state from %s state\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Port (%6x) entered RFT_ID state from %s state\n", + fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_RFT_ID); @@ -1244,8 +1253,8 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport) { struct fc_frame *fp; - FC_LPORT_DBG(lport, "Entered RPN_ID state from %s state\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Port (%6x) entered RPN_ID state from %s state\n", + fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_RPN_ID); @@ -1285,8 +1294,8 @@ static void fc_lport_enter_dns(struct fc_lport *lport) dp.ids.roles = FC_RPORT_ROLE_UNKNOWN; dp.lp = lport; - FC_LPORT_DBG(lport, "Entered DNS state from %s state\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Port (%6x) entered DNS state from %s state\n", + fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_DNS); @@ -1365,11 +1374,11 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&lport->lp_mutex); - FC_LPORT_DBG(lport, "Received a LOGO response\n"); + FC_DEBUG_LPORT("Received a LOGO response\n"); if (lport->state != LPORT_ST_LOGO) { - FC_LPORT_DBG(lport, "Received a LOGO response, but in state " - "%s\n", fc_lport_state(lport)); + FC_DBG("Received a LOGO response, but in state %s\n", + fc_lport_state(lport)); if (IS_ERR(fp)) goto err; goto out; @@ -1404,8 +1413,8 @@ static void fc_lport_enter_logo(struct fc_lport *lport) struct fc_frame *fp; struct fc_els_logo *logo; - FC_LPORT_DBG(lport, "Entered LOGO state from %s state\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Port (%6x) entered LOGO state from %s state\n", + fc_host_port_id(lport->host), fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_LOGO); @@ -1447,11 +1456,11 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&lport->lp_mutex); - FC_LPORT_DBG(lport, "Received a FLOGI response\n"); + FC_DEBUG_LPORT("Received a FLOGI response\n"); if (lport->state != LPORT_ST_FLOGI) { - FC_LPORT_DBG(lport, "Received a FLOGI response, but in state " - "%s\n", fc_lport_state(lport)); + FC_DBG("Received a FLOGI response, but in state %s\n", + fc_lport_state(lport)); if (IS_ERR(fp)) goto err; goto out; @@ -1466,8 +1475,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, did = ntoh24(fh->fh_d_id); if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { - printk(KERN_INFO "libfc: Assigned FID (%6x) in FLOGI response\n", - did); + FC_DEBUG_LPORT("Assigned fid %x\n", did); fc_host_port_id(lport->host) = did; flp = fc_frame_payload_get(fp, sizeof(*flp)); @@ -1486,8 +1494,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, if (e_d_tov > lport->e_d_tov) lport->e_d_tov = e_d_tov; lport->r_a_tov = 2 * e_d_tov; - printk(KERN_INFO "libfc: Port (%6x) entered " - "point to point mode\n", did); + FC_DBG("Point-to-Point mode\n"); fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id), get_unaligned_be64( &flp->fl_wwpn), @@ -1510,7 +1517,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, } } } else { - FC_LPORT_DBG(lport, "Bad FLOGI response\n"); + FC_DBG("bad FLOGI response\n"); } out: @@ -1530,8 +1537,7 @@ void fc_lport_enter_flogi(struct fc_lport *lport) { struct fc_frame *fp; - FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n", - fc_lport_state(lport)); + FC_DEBUG_LPORT("Processing FLOGI state\n"); fc_lport_state_enter(lport, LPORT_ST_FLOGI); diff --git a/trunk/drivers/scsi/libfc/fc_rport.c b/trunk/drivers/scsi/libfc/fc_rport.c index 7162385f52eb..7bfbff7e0efb 100644 --- a/trunk/drivers/scsi/libfc/fc_rport.c +++ b/trunk/drivers/scsi/libfc/fc_rport.c @@ -55,6 +55,14 @@ #include #include +static int fc_rport_debug; + +#define FC_DEBUG_RPORT(fmt...) \ + do { \ + if (fc_rport_debug) \ + FC_DBG(fmt); \ + } while (0) + struct workqueue_struct *rport_event_queue; static void fc_rport_enter_plogi(struct fc_rport *); @@ -89,7 +97,7 @@ static const char *fc_rport_state_names[] = { static void fc_rport_rogue_destroy(struct device *dev) { struct fc_rport *rport = dev_to_rport(dev); - FC_RPORT_DBG(rport, "Destroying rogue rport\n"); + FC_DEBUG_RPORT("Destroying rogue rport (%6x)\n", rport->port_id); kfree(rport); } @@ -255,8 +263,8 @@ static void fc_rport_work(struct work_struct *work) fc_rport_state_enter(new_rport, RPORT_ST_READY); } else { - printk(KERN_WARNING "libfc: Failed to allocate " - " memory for rport (%6x)\n", ids.port_id); + FC_DBG("Failed to create the rport for port " + "(%6x).\n", ids.port_id); event = RPORT_EV_FAILED; } if (rport->port_id != FC_FID_DIR_SERV) @@ -301,7 +309,7 @@ int fc_rport_login(struct fc_rport *rport) mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rport, "Login to port\n"); + FC_DEBUG_RPORT("Login to port (%6x)\n", rport->port_id); fc_rport_enter_plogi(rport); @@ -321,13 +329,16 @@ int fc_rport_login(struct fc_rport *rport) int fc_rport_logoff(struct fc_rport *rport) { struct fc_rport_libfc_priv *rdata = rport->dd_data; + struct fc_lport *lport = rdata->local_port; mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rport, "Remove port\n"); + FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id); if (rdata->rp_state == RPORT_ST_NONE) { - FC_RPORT_DBG(rport, "Port in NONE state, not removing\n"); + FC_DEBUG_RPORT("(%6x): Port (%6x) in NONE state," + " not removing", fc_host_port_id(lport->host), + rport->port_id); mutex_unlock(&rdata->rp_mutex); goto out; } @@ -368,7 +379,7 @@ static void fc_rport_enter_ready(struct fc_rport *rport) fc_rport_state_enter(rport, RPORT_ST_READY); - FC_RPORT_DBG(rport, "Port is Ready\n"); + FC_DEBUG_RPORT("Port (%6x) is Ready\n", rport->port_id); rdata->event = RPORT_EV_CREATED; queue_work(rport_event_queue, &rdata->event_work); @@ -425,8 +436,8 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) { struct fc_rport_libfc_priv *rdata = rport->dd_data; - FC_RPORT_DBG(rport, "Error %ld in state %s, retries %d\n", - PTR_ERR(fp), fc_rport_state(rport), rdata->retries); + FC_DEBUG_RPORT("Error %ld in state %s, retries %d\n", + PTR_ERR(fp), fc_rport_state(rport), rdata->retries); switch (rdata->rp_state) { case RPORT_ST_PLOGI: @@ -468,8 +479,8 @@ static void fc_rport_error_retry(struct fc_rport *rport, struct fc_frame *fp) return fc_rport_error(rport, fp); if (rdata->retries < rdata->local_port->max_rport_retry_count) { - FC_RPORT_DBG(rport, "Error %ld in state %s, retrying\n", - PTR_ERR(fp), fc_rport_state(rport)); + FC_DEBUG_RPORT("Error %ld in state %s, retrying\n", + PTR_ERR(fp), fc_rport_state(rport)); rdata->retries++; /* no additional delay on exchange timeouts */ if (PTR_ERR(fp) == -FC_EX_TIMEOUT) @@ -506,11 +517,12 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rport, "Received a PLOGI response\n"); + FC_DEBUG_RPORT("Received a PLOGI response from port (%6x)\n", + rport->port_id); if (rdata->rp_state != RPORT_ST_PLOGI) { - FC_RPORT_DBG(rport, "Received a PLOGI response, but in state " - "%s\n", fc_rport_state(rport)); + FC_DBG("Received a PLOGI response, but in state %s\n", + fc_rport_state(rport)); if (IS_ERR(fp)) goto err; goto out; @@ -571,8 +583,8 @@ static void fc_rport_enter_plogi(struct fc_rport *rport) struct fc_lport *lport = rdata->local_port; struct fc_frame *fp; - FC_RPORT_DBG(rport, "Port entered PLOGI state from %s state\n", - fc_rport_state(rport)); + FC_DEBUG_RPORT("Port (%6x) entered PLOGI state from %s state\n", + rport->port_id, fc_rport_state(rport)); fc_rport_state_enter(rport, RPORT_ST_PLOGI); @@ -616,11 +628,12 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rport, "Received a PRLI response\n"); + FC_DEBUG_RPORT("Received a PRLI response from port (%6x)\n", + rport->port_id); if (rdata->rp_state != RPORT_ST_PRLI) { - FC_RPORT_DBG(rport, "Received a PRLI response, but in state " - "%s\n", fc_rport_state(rport)); + FC_DBG("Received a PRLI response, but in state %s\n", + fc_rport_state(rport)); if (IS_ERR(fp)) goto err; goto out; @@ -650,7 +663,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, fc_rport_enter_rtv(rport); } else { - FC_RPORT_DBG(rport, "Bad ELS response for PRLI command\n"); + FC_DBG("Bad ELS response\n"); rdata->event = RPORT_EV_FAILED; fc_rport_state_enter(rport, RPORT_ST_NONE); queue_work(rport_event_queue, &rdata->event_work); @@ -682,11 +695,12 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rport, "Received a LOGO response\n"); + FC_DEBUG_RPORT("Received a LOGO response from port (%6x)\n", + rport->port_id); if (rdata->rp_state != RPORT_ST_LOGO) { - FC_RPORT_DBG(rport, "Received a LOGO response, but in state " - "%s\n", fc_rport_state(rport)); + FC_DEBUG_RPORT("Received a LOGO response, but in state %s\n", + fc_rport_state(rport)); if (IS_ERR(fp)) goto err; goto out; @@ -701,7 +715,7 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, if (op == ELS_LS_ACC) { fc_rport_enter_rtv(rport); } else { - FC_RPORT_DBG(rport, "Bad ELS response for LOGO command\n"); + FC_DBG("Bad ELS response\n"); rdata->event = RPORT_EV_LOGO; fc_rport_state_enter(rport, RPORT_ST_NONE); queue_work(rport_event_queue, &rdata->event_work); @@ -731,8 +745,8 @@ static void fc_rport_enter_prli(struct fc_rport *rport) } *pp; struct fc_frame *fp; - FC_RPORT_DBG(rport, "Port entered PRLI state from %s state\n", - fc_rport_state(rport)); + FC_DEBUG_RPORT("Port (%6x) entered PRLI state from %s state\n", + rport->port_id, fc_rport_state(rport)); fc_rport_state_enter(rport, RPORT_ST_PRLI); @@ -770,11 +784,12 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rport, "Received a RTV response\n"); + FC_DEBUG_RPORT("Received a RTV response from port (%6x)\n", + rport->port_id); if (rdata->rp_state != RPORT_ST_RTV) { - FC_RPORT_DBG(rport, "Received a RTV response, but in state " - "%s\n", fc_rport_state(rport)); + FC_DBG("Received a RTV response, but in state %s\n", + fc_rport_state(rport)); if (IS_ERR(fp)) goto err; goto out; @@ -829,8 +844,8 @@ static void fc_rport_enter_rtv(struct fc_rport *rport) struct fc_rport_libfc_priv *rdata = rport->dd_data; struct fc_lport *lport = rdata->local_port; - FC_RPORT_DBG(rport, "Port entered RTV state from %s state\n", - fc_rport_state(rport)); + FC_DEBUG_RPORT("Port (%6x) entered RTV state from %s state\n", + rport->port_id, fc_rport_state(rport)); fc_rport_state_enter(rport, RPORT_ST_RTV); @@ -860,8 +875,8 @@ static void fc_rport_enter_logo(struct fc_rport *rport) struct fc_lport *lport = rdata->local_port; struct fc_frame *fp; - FC_RPORT_DBG(rport, "Port entered LOGO state from %s state\n", - fc_rport_state(rport)); + FC_DEBUG_RPORT("Port (%6x) entered LOGO state from %s state\n", + rport->port_id, fc_rport_state(rport)); fc_rport_state_enter(rport, RPORT_ST_LOGO); @@ -968,13 +983,14 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport, fh = fc_frame_header_get(fp); - FC_RPORT_DBG(rport, "Received PLOGI request while in state %s\n", - fc_rport_state(rport)); + FC_DEBUG_RPORT("Received PLOGI request from port (%6x) " + "while in state %s\n", ntoh24(fh->fh_s_id), + fc_rport_state(rport)); sid = ntoh24(fh->fh_s_id); pl = fc_frame_payload_get(fp, sizeof(*pl)); if (!pl) { - FC_RPORT_DBG(rport, "Received PLOGI too short\n"); + FC_DBG("incoming PLOGI from %x too short\n", sid); WARN_ON(1); /* XXX TBD: send reject? */ fc_frame_free(fp); @@ -996,26 +1012,26 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport, */ switch (rdata->rp_state) { case RPORT_ST_INIT: - FC_RPORT_DBG(rport, "Received PLOGI, wwpn %llx state INIT " - "- reject\n", (unsigned long long)wwpn); + FC_DEBUG_RPORT("incoming PLOGI from %6x wwpn %llx state INIT " + "- reject\n", sid, (unsigned long long)wwpn); reject = ELS_RJT_UNSUP; break; case RPORT_ST_PLOGI: - FC_RPORT_DBG(rport, "Received PLOGI in PLOGI state %d\n", - rdata->rp_state); + FC_DEBUG_RPORT("incoming PLOGI from %x in PLOGI state %d\n", + sid, rdata->rp_state); if (wwpn < lport->wwpn) reject = ELS_RJT_INPROG; break; case RPORT_ST_PRLI: case RPORT_ST_READY: - FC_RPORT_DBG(rport, "Received PLOGI in logged-in state %d " - "- ignored for now\n", rdata->rp_state); + FC_DEBUG_RPORT("incoming PLOGI from %x in logged-in state %d " + "- ignored for now\n", sid, rdata->rp_state); /* XXX TBD - should reset */ break; case RPORT_ST_NONE: default: - FC_RPORT_DBG(rport, "Received PLOGI in unexpected " - "state %d\n", rdata->rp_state); + FC_DEBUG_RPORT("incoming PLOGI from %x in unexpected " + "state %d\n", sid, rdata->rp_state); fc_frame_free(fp); return; break; @@ -1099,8 +1115,9 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, fh = fc_frame_header_get(rx_fp); - FC_RPORT_DBG(rport, "Received PRLI request while in state %s\n", - fc_rport_state(rport)); + FC_DEBUG_RPORT("Received PRLI request from port (%6x) " + "while in state %s\n", ntoh24(fh->fh_s_id), + fc_rport_state(rport)); switch (rdata->rp_state) { case RPORT_ST_PRLI: @@ -1235,8 +1252,9 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, fh = fc_frame_header_get(fp); - FC_RPORT_DBG(rport, "Received PRLO request while in state %s\n", - fc_rport_state(rport)); + FC_DEBUG_RPORT("Received PRLO request from port (%6x) " + "while in state %s\n", ntoh24(fh->fh_s_id), + fc_rport_state(rport)); if (rdata->rp_state == RPORT_ST_NONE) { fc_frame_free(fp); @@ -1268,8 +1286,9 @@ static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp, fh = fc_frame_header_get(fp); - FC_RPORT_DBG(rport, "Received LOGO request while in state %s\n", - fc_rport_state(rport)); + FC_DEBUG_RPORT("Received LOGO request from port (%6x) " + "while in state %s\n", ntoh24(fh->fh_s_id), + fc_rport_state(rport)); if (rdata->rp_state == RPORT_ST_NONE) { fc_frame_free(fp); @@ -1289,6 +1308,7 @@ static void fc_rport_flush_queue(void) flush_workqueue(rport_event_queue); } + int fc_rport_init(struct fc_lport *lport) { if (!lport->tt.rport_create) diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 716cc344c5df..59908aead531 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -38,30 +38,15 @@ #include #include -static int iscsi_dbg_lib_conn; -module_param_named(debug_libiscsi_conn, iscsi_dbg_lib_conn, int, - S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug_libiscsi_conn, - "Turn on debugging for connections in libiscsi module. " - "Set to 1 to turn on, and zero to turn off. Default is off."); - -static int iscsi_dbg_lib_session; -module_param_named(debug_libiscsi_session, iscsi_dbg_lib_session, int, - S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug_libiscsi_session, - "Turn on debugging for sessions in libiscsi module. " - "Set to 1 to turn on, and zero to turn off. Default is off."); - -static int iscsi_dbg_lib_eh; -module_param_named(debug_libiscsi_eh, iscsi_dbg_lib_eh, int, - S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug_libiscsi_eh, - "Turn on debugging for error handling in libiscsi module. " - "Set to 1 to turn on, and zero to turn off. Default is off."); +static int iscsi_dbg_lib; +module_param_named(debug_libiscsi, iscsi_dbg_lib, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug_libiscsi, "Turn on debugging for libiscsi module. " + "Set to 1 to turn on, and zero to turn off. Default " + "is off."); #define ISCSI_DBG_CONN(_conn, dbg_fmt, arg...) \ do { \ - if (iscsi_dbg_lib_conn) \ + if (iscsi_dbg_lib) \ iscsi_conn_printk(KERN_INFO, _conn, \ "%s " dbg_fmt, \ __func__, ##arg); \ @@ -69,15 +54,7 @@ MODULE_PARM_DESC(debug_libiscsi_eh, #define ISCSI_DBG_SESSION(_session, dbg_fmt, arg...) \ do { \ - if (iscsi_dbg_lib_session) \ - iscsi_session_printk(KERN_INFO, _session, \ - "%s " dbg_fmt, \ - __func__, ##arg); \ - } while (0); - -#define ISCSI_DBG_EH(_session, dbg_fmt, arg...) \ - do { \ - if (iscsi_dbg_lib_eh) \ + if (iscsi_dbg_lib) \ iscsi_session_printk(KERN_INFO, _session, \ "%s " dbg_fmt, \ __func__, ##arg); \ @@ -977,7 +954,6 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, task = iscsi_itt_to_ctask(conn, hdr->itt); if (!task) return ISCSI_ERR_BAD_ITT; - task->last_xfer = jiffies; break; case ISCSI_OP_R2T: /* @@ -1216,12 +1192,10 @@ static int iscsi_xmit_task(struct iscsi_conn *conn) spin_unlock_bh(&conn->session->lock); rc = conn->session->tt->xmit_task(task); spin_lock_bh(&conn->session->lock); - if (!rc) { + __iscsi_put_task(task); + if (!rc) /* done with this task */ - task->last_xfer = jiffies; conn->task = NULL; - } - __iscsi_put_task(task); return rc; } @@ -1387,9 +1361,6 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, task->state = ISCSI_TASK_PENDING; task->conn = conn; task->sc = sc; - task->have_checked_conn = false; - task->last_timeout = jiffies; - task->last_xfer = jiffies; INIT_LIST_HEAD(&task->running); return task; } @@ -1584,10 +1555,10 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc) spin_lock_bh(&session->lock); if (session->state == ISCSI_STATE_TERMINATE) { failed: - ISCSI_DBG_EH(session, - "failing target reset: Could not log back into " - "target [age %d]\n", - session->age); + iscsi_session_printk(KERN_INFO, session, + "failing target reset: Could not log " + "back into target [age %d]\n", + session->age); spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); return FAILED; @@ -1601,7 +1572,7 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc) */ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - ISCSI_DBG_EH(session, "wait for relogin\n"); + ISCSI_DBG_SESSION(session, "wait for relogin\n"); wait_event_interruptible(conn->ehwait, session->state == ISCSI_STATE_TERMINATE || session->state == ISCSI_STATE_LOGGED_IN || @@ -1611,10 +1582,10 @@ int iscsi_eh_target_reset(struct scsi_cmnd *sc) mutex_lock(&session->eh_mutex); spin_lock_bh(&session->lock); - if (session->state == ISCSI_STATE_LOGGED_IN) { - ISCSI_DBG_EH(session, - "target reset succeeded\n"); - } else + if (session->state == ISCSI_STATE_LOGGED_IN) + iscsi_session_printk(KERN_INFO, session, + "target reset succeeded\n"); + else goto failed; spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); @@ -1630,7 +1601,7 @@ static void iscsi_tmf_timedout(unsigned long data) spin_lock(&session->lock); if (conn->tmf_state == TMF_QUEUED) { conn->tmf_state = TMF_TIMEDOUT; - ISCSI_DBG_EH(session, "tmf timedout\n"); + ISCSI_DBG_SESSION(session, "tmf timedout\n"); /* unblock eh_abort() */ wake_up(&conn->ehwait); } @@ -1650,7 +1621,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, spin_unlock_bh(&session->lock); iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); spin_lock_bh(&session->lock); - ISCSI_DBG_EH(session, "tmf exec failure\n"); + ISCSI_DBG_SESSION(session, "tmf exec failure\n"); return -EPERM; } conn->tmfcmd_pdus_cnt++; @@ -1658,7 +1629,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, conn->tmf_timer.function = iscsi_tmf_timedout; conn->tmf_timer.data = (unsigned long)conn; add_timer(&conn->tmf_timer); - ISCSI_DBG_EH(session, "tmf set timeout\n"); + ISCSI_DBG_SESSION(session, "tmf set timeout\n"); spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); @@ -1745,18 +1716,17 @@ static int iscsi_has_ping_timed_out(struct iscsi_conn *conn) return 0; } -static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) +static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) { - enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED; - struct iscsi_task *task = NULL; struct iscsi_cls_session *cls_session; struct iscsi_session *session; struct iscsi_conn *conn; + enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED; - cls_session = starget_to_session(scsi_target(sc->device)); + cls_session = starget_to_session(scsi_target(scmd->device)); session = cls_session->dd_data; - ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc); + ISCSI_DBG_SESSION(session, "scsi cmd %p timedout\n", scmd); spin_lock(&session->lock); if (session->state != ISCSI_STATE_LOGGED_IN) { @@ -1775,26 +1745,6 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) goto done; } - task = (struct iscsi_task *)sc->SCp.ptr; - if (!task) - goto done; - /* - * If we have sent (at least queued to the network layer) a pdu or - * recvd one for the task since the last timeout ask for - * more time. If on the next timeout we have not made progress - * we can check if it is the task or connection when we send the - * nop as a ping. - */ - if (time_after_eq(task->last_xfer, task->last_timeout)) { - ISCSI_DBG_EH(session, "Command making progress. Asking " - "scsi-ml for more time to complete. " - "Last data recv at %lu. Last timeout was at " - "%lu\n.", task->last_xfer, task->last_timeout); - task->have_checked_conn = false; - rc = BLK_EH_RESET_TIMER; - goto done; - } - if (!conn->recv_timeout && !conn->ping_timeout) goto done; /* @@ -1805,32 +1755,23 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) rc = BLK_EH_RESET_TIMER; goto done; } - - /* Assumes nop timeout is shorter than scsi cmd timeout */ - if (task->have_checked_conn) - goto done; - /* - * Checking the transport already or nop from a cmd timeout still - * running + * if we are about to check the transport then give the command + * more time */ - if (conn->ping_task) { - task->have_checked_conn = true; + if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ), + jiffies)) { rc = BLK_EH_RESET_TIMER; goto done; } - /* Make sure there is a transport check done */ - iscsi_send_nopout(conn, NULL); - task->have_checked_conn = true; - rc = BLK_EH_RESET_TIMER; - + /* if in the middle of checking the transport then give us more time */ + if (conn->ping_task) + rc = BLK_EH_RESET_TIMER; done: - if (task) - task->last_timeout = jiffies; spin_unlock(&session->lock); - ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? - "timer reset" : "nh"); + ISCSI_DBG_SESSION(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? + "timer reset" : "nh"); return rc; } @@ -1900,7 +1841,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) cls_session = starget_to_session(scsi_target(sc->device)); session = cls_session->dd_data; - ISCSI_DBG_EH(session, "aborting sc %p\n", sc); + ISCSI_DBG_SESSION(session, "aborting sc %p\n", sc); mutex_lock(&session->eh_mutex); spin_lock_bh(&session->lock); @@ -1909,8 +1850,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) * got the command. */ if (!sc->SCp.ptr) { - ISCSI_DBG_EH(session, "sc never reached iscsi layer or " - "it completed.\n"); + ISCSI_DBG_SESSION(session, "sc never reached iscsi layer or " + "it completed.\n"); spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); return SUCCESS; @@ -1924,7 +1865,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) sc->SCp.phase != session->age) { spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); - ISCSI_DBG_EH(session, "failing abort due to dropped " + ISCSI_DBG_SESSION(session, "failing abort due to dropped " "session.\n"); return FAILED; } @@ -1934,12 +1875,13 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) age = session->age; task = (struct iscsi_task *)sc->SCp.ptr; - ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", - sc, task->itt); + ISCSI_DBG_SESSION(session, "aborting [sc %p itt 0x%x]\n", + sc, task->itt); /* task completed before time out */ if (!task->sc) { - ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); + ISCSI_DBG_SESSION(session, "sc completed while abort in " + "progress\n"); goto success; } @@ -1988,8 +1930,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) if (!sc->SCp.ptr) { conn->tmf_state = TMF_INITIAL; /* task completed before tmf abort response */ - ISCSI_DBG_EH(session, "sc completed while abort in " - "progress\n"); + ISCSI_DBG_SESSION(session, "sc completed while abort " + "in progress\n"); goto success; } /* fall through */ @@ -2001,16 +1943,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) success: spin_unlock_bh(&session->lock); success_unlocked: - ISCSI_DBG_EH(session, "abort success [sc %p itt 0x%x]\n", - sc, task->itt); + ISCSI_DBG_SESSION(session, "abort success [sc %p itt 0x%x]\n", + sc, task->itt); mutex_unlock(&session->eh_mutex); return SUCCESS; failed: spin_unlock_bh(&session->lock); failed_unlocked: - ISCSI_DBG_EH(session, "abort failed [sc %p itt 0x%x]\n", sc, - task ? task->itt : 0); + ISCSI_DBG_SESSION(session, "abort failed [sc %p itt 0x%x]\n", sc, + task ? task->itt : 0); mutex_unlock(&session->eh_mutex); return FAILED; } @@ -2037,7 +1979,8 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) cls_session = starget_to_session(scsi_target(sc->device)); session = cls_session->dd_data; - ISCSI_DBG_EH(session, "LU Reset [sc %p lun %u]\n", sc, sc->device->lun); + ISCSI_DBG_SESSION(session, "LU Reset [sc %p lun %u]\n", + sc, sc->device->lun); mutex_lock(&session->eh_mutex); spin_lock_bh(&session->lock); @@ -2091,8 +2034,8 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) unlock: spin_unlock_bh(&session->lock); done: - ISCSI_DBG_EH(session, "dev reset result = %s\n", - rc == SUCCESS ? "SUCCESS" : "FAILED"); + ISCSI_DBG_SESSION(session, "dev reset result = %s\n", + rc == SUCCESS ? "SUCCESS" : "FAILED"); mutex_unlock(&session->eh_mutex); return rc; } diff --git a/trunk/drivers/scsi/libiscsi_tcp.c b/trunk/drivers/scsi/libiscsi_tcp.c index 2e0746d70303..2bc07090321d 100644 --- a/trunk/drivers/scsi/libiscsi_tcp.c +++ b/trunk/drivers/scsi/libiscsi_tcp.c @@ -686,7 +686,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) "offset=%d, datalen=%d)\n", tcp_task->data_offset, tcp_conn->in.datalen); - task->last_xfer = jiffies; rc = iscsi_segment_seek_sg(&tcp_conn->in.segment, sdb->table.sgl, sdb->table.nents, @@ -714,10 +713,9 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) rc = ISCSI_ERR_BAD_ITT; else if (ahslen) rc = ISCSI_ERR_AHSLEN; - else if (task->sc->sc_data_direction == DMA_TO_DEVICE) { - task->last_xfer = jiffies; + else if (task->sc->sc_data_direction == DMA_TO_DEVICE) rc = iscsi_tcp_r2t_rsp(conn, task); - } else + else rc = ISCSI_ERR_PROTO; spin_unlock(&conn->session->lock); break; diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.c b/trunk/drivers/scsi/qla2xxx/qla_dbg.c index cca8e4ab0372..4a990f4da4ea 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.c @@ -216,7 +216,7 @@ qla24xx_soft_reset(struct qla_hw_data *ha) static int qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram, - uint32_t ram_words, void **nxt) + uint16_t ram_words, void **nxt) { int rval; uint32_t cnt, stat, timer, words, idx; diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index f2ce8e3cc91b..262026129325 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -2301,7 +2301,7 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" }; char *link_speed; int rval; - uint16_t mb[4]; + uint16_t mb[6]; struct qla_hw_data *ha = vha->hw; if (!IS_IIDMA_CAPABLE(ha)) diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index fe69f3057671..451ece0760b0 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -1267,22 +1267,17 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states) mcp->mb[0] = MBC_GET_FIRMWARE_STATE; mcp->out_mb = MBX_0; - if (IS_FWI2_CAPABLE(vha->hw)) - mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; - else - mcp->in_mb = MBX_1|MBX_0; + mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); /* Return firmware states. */ states[0] = mcp->mb[1]; - if (IS_FWI2_CAPABLE(vha->hw)) { - states[1] = mcp->mb[2]; - states[2] = mcp->mb[3]; - states[3] = mcp->mb[4]; - states[4] = mcp->mb[5]; - } + states[1] = mcp->mb[2]; + states[2] = mcp->mb[3]; + states[3] = mcp->mb[4]; + states[4] = mcp->mb[5]; if (rval != QLA_SUCCESS) { /*EMPTY*/ @@ -2702,13 +2697,10 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, mcp->mb[0] = MBC_PORT_PARAMS; mcp->mb[1] = loop_id; mcp->mb[2] = BIT_0; - if (IS_QLA81XX(vha->hw)) - mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0); - else - mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0); - mcp->mb[9] = vha->vp_idx; - mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->in_mb = MBX_3|MBX_1|MBX_0; + mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0); + mcp->mb[4] = mcp->mb[5] = 0; + mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; + mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); @@ -2718,6 +2710,8 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id, mb[0] = mcp->mb[0]; mb[1] = mcp->mb[1]; mb[3] = mcp->mb[3]; + mb[4] = mcp->mb[4]; + mb[5] = mcp->mb[5]; } if (rval != QLA_SUCCESS) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index f0396e79b6fa..dcf011679c8b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -1663,7 +1663,7 @@ qla2x00_iospace_config(struct qla_hw_data *ha) /* queue 0 uses two msix vectors */ if (ql2xmultique_tag) { cpus = num_online_cpus(); - ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ? + ha->max_rsp_queues = (ha->msix_count - 1 - cpus) ? (cpus + 1) : (ha->msix_count - 1); ha->max_req_queues = 2; } else if (ql2xmaxqueues > 1) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index 84369705a9ad..b63feaf43126 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.01-k4" +#define QLA2XXX_VERSION "8.03.01-k3" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c index fb9af207d61d..41a21772df12 100644 --- a/trunk/drivers/scsi/scsi_debug.c +++ b/trunk/drivers/scsi/scsi_debug.c @@ -101,8 +101,6 @@ static const char * scsi_debug_version_date = "20070104"; #define DEF_DIF 0 #define DEF_GUARD 0 #define DEF_ATO 1 -#define DEF_PHYSBLK_EXP 0 -#define DEF_LOWEST_ALIGNED 0 /* bit mask values for scsi_debug_opts */ #define SCSI_DEBUG_OPT_NOISE 1 @@ -158,8 +156,6 @@ static int scsi_debug_dix = DEF_DIX; static int scsi_debug_dif = DEF_DIF; static int scsi_debug_guard = DEF_GUARD; static int scsi_debug_ato = DEF_ATO; -static int scsi_debug_physblk_exp = DEF_PHYSBLK_EXP; -static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED; static int scsi_debug_cmnd_count = 0; @@ -661,12 +657,7 @@ static unsigned char vpdb0_data[] = { static int inquiry_evpd_b0(unsigned char * arr) { - unsigned int gran; - memcpy(arr, vpdb0_data, sizeof(vpdb0_data)); - gran = 1 << scsi_debug_physblk_exp; - arr[2] = (gran >> 8) & 0xff; - arr[3] = gran & 0xff; if (sdebug_store_sectors > 0x400) { arr[4] = (sdebug_store_sectors >> 24) & 0xff; arr[5] = (sdebug_store_sectors >> 16) & 0xff; @@ -954,9 +945,6 @@ static int resp_readcap16(struct scsi_cmnd * scp, arr[9] = (scsi_debug_sector_size >> 16) & 0xff; arr[10] = (scsi_debug_sector_size >> 8) & 0xff; arr[11] = scsi_debug_sector_size & 0xff; - arr[13] = scsi_debug_physblk_exp & 0xf; - arr[14] = (scsi_debug_lowest_aligned >> 8) & 0x3f; - arr[15] = scsi_debug_lowest_aligned & 0xff; if (scsi_debug_dif) { arr[12] = (scsi_debug_dif - 1) << 1; /* P_TYPE */ @@ -2392,8 +2380,6 @@ module_param_named(dix, scsi_debug_dix, int, S_IRUGO); module_param_named(dif, scsi_debug_dif, int, S_IRUGO); module_param_named(guard, scsi_debug_guard, int, S_IRUGO); module_param_named(ato, scsi_debug_ato, int, S_IRUGO); -module_param_named(physblk_exp, scsi_debug_physblk_exp, int, S_IRUGO); -module_param_named(lowest_aligned, scsi_debug_lowest_aligned, int, S_IRUGO); MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); MODULE_DESCRIPTION("SCSI debug adapter driver"); @@ -2415,9 +2401,7 @@ MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); MODULE_PARM_DESC(vpd_use_hostno, "0 -> dev ids ignore hostno (def=1 -> unique dev ids)"); -MODULE_PARM_DESC(sector_size, "logical block size in bytes (def=512)"); -MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)"); -MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)"); +MODULE_PARM_DESC(sector_size, "hardware sector size in bytes (def=512)"); MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)"); MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)"); MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)"); @@ -2890,18 +2874,6 @@ static int __init scsi_debug_init(void) return -EINVAL; } - if (scsi_debug_physblk_exp > 15) { - printk(KERN_ERR "scsi_debug_init: invalid physblk_exp %u\n", - scsi_debug_physblk_exp); - return -EINVAL; - } - - if (scsi_debug_lowest_aligned > 0x3fff) { - printk(KERN_ERR "scsi_debug_init: lowest_aligned too big: %u\n", - scsi_debug_lowest_aligned); - return -EINVAL; - } - if (scsi_debug_dev_size_mb < 1) scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ sz = (unsigned long)scsi_debug_dev_size_mb * 1048576; diff --git a/trunk/drivers/scsi/scsi_devinfo.c b/trunk/drivers/scsi/scsi_devinfo.c index 93c2622cb969..8821df9a277b 100644 --- a/trunk/drivers/scsi/scsi_devinfo.c +++ b/trunk/drivers/scsi/scsi_devinfo.c @@ -24,13 +24,6 @@ struct scsi_dev_info_list { unsigned compatible; /* for use with scsi_static_device_list entries */ }; -struct scsi_dev_info_list_table { - struct list_head node; /* our node for being on the master list */ - struct list_head scsi_dev_info_list; /* head of dev info list */ - const char *name; /* name of list for /proc (NULL for global) */ - int key; /* unique numeric identifier */ -}; - static const char spaces[] = " "; /* 16 of them */ static unsigned scsi_default_dev_flags; @@ -254,22 +247,6 @@ static struct { { NULL, NULL, NULL, 0 }, }; -static struct scsi_dev_info_list_table *scsi_devinfo_lookup_by_key(int key) -{ - struct scsi_dev_info_list_table *devinfo_table; - int found = 0; - - list_for_each_entry(devinfo_table, &scsi_dev_info_list, node) - if (devinfo_table->key == key) { - found = 1; - break; - } - if (!found) - return ERR_PTR(-EINVAL); - - return devinfo_table; -} - /* * scsi_strcpy_devinfo: called from scsi_dev_info_list_add to copy into * devinfo vendor and model strings. @@ -318,39 +295,8 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length, **/ static int scsi_dev_info_list_add(int compatible, char *vendor, char *model, char *strflags, int flags) -{ - return scsi_dev_info_list_add_keyed(compatible, vendor, model, - strflags, flags, - SCSI_DEVINFO_GLOBAL); -} - -/** - * scsi_dev_info_list_add_keyed - add one dev_info list entry. - * @compatible: if true, null terminate short strings. Otherwise space pad. - * @vendor: vendor string - * @model: model (product) string - * @strflags: integer string - * @flags: if strflags NULL, use this flag value - * @key: specify list to use - * - * Description: - * Create and add one dev_info entry for @vendor, @model, - * @strflags or @flag in list specified by @key. If @compatible, - * add to the tail of the list, do not space pad, and set - * devinfo->compatible. The scsi_static_device_list entries are - * added with @compatible 1 and @clfags NULL. - * - * Returns: 0 OK, -error on failure. - **/ -int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model, - char *strflags, int flags, int key) { struct scsi_dev_info_list *devinfo; - struct scsi_dev_info_list_table *devinfo_table = - scsi_devinfo_lookup_by_key(key); - - if (IS_ERR(devinfo_table)) - return PTR_ERR(devinfo_table); devinfo = kmalloc(sizeof(*devinfo), GFP_KERNEL); if (!devinfo) { @@ -371,15 +317,12 @@ int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model, devinfo->compatible = compatible; if (compatible) - list_add_tail(&devinfo->dev_info_list, - &devinfo_table->scsi_dev_info_list); + list_add_tail(&devinfo->dev_info_list, &scsi_dev_info_list); else - list_add(&devinfo->dev_info_list, - &devinfo_table->scsi_dev_info_list); + list_add(&devinfo->dev_info_list, &scsi_dev_info_list); return 0; } -EXPORT_SYMBOL(scsi_dev_info_list_add_keyed); /** * scsi_dev_info_list_add_str - parse dev_list and add to the scsi_dev_info_list. @@ -439,48 +382,22 @@ static int scsi_dev_info_list_add_str(char *dev_list) * @model: model name * * Description: - * Search the global scsi_dev_info_list (specified by list zero) - * for an entry matching @vendor and @model, if found, return the - * matching flags value, else return the host or global default - * settings. Called during scan time. + * Search the scsi_dev_info_list for an entry matching @vendor and + * @model, if found, return the matching flags value, else return + * the host or global default settings. Called during scan time. **/ int scsi_get_device_flags(struct scsi_device *sdev, const unsigned char *vendor, const unsigned char *model) -{ - return scsi_get_device_flags_keyed(sdev, vendor, model, - SCSI_DEVINFO_GLOBAL); -} - - -/** - * get_device_flags_keyed - get device specific flags from the dynamic device list. - * @sdev: &scsi_device to get flags for - * @vendor: vendor name - * @model: model name - * @key: list to look up - * - * Description: - * Search the scsi_dev_info_list specified by @key for an entry - * matching @vendor and @model, if found, return the matching - * flags value, else return the host or global default settings. - * Called during scan time. - **/ -int scsi_get_device_flags_keyed(struct scsi_device *sdev, - const unsigned char *vendor, - const unsigned char *model, - int key) { struct scsi_dev_info_list *devinfo; - struct scsi_dev_info_list_table *devinfo_table; - - devinfo_table = scsi_devinfo_lookup_by_key(key); + unsigned int bflags; - if (IS_ERR(devinfo_table)) - return PTR_ERR(devinfo_table); + bflags = sdev->sdev_bflags; + if (!bflags) + bflags = scsi_default_dev_flags; - list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list, - dev_info_list) { + list_for_each_entry(devinfo, &scsi_dev_info_list, dev_info_list) { if (devinfo->compatible) { /* * Behave like the older version of get_device_flags. @@ -530,89 +447,32 @@ int scsi_get_device_flags_keyed(struct scsi_device *sdev, return devinfo->flags; } } - /* nothing found, return nothing */ - if (key != SCSI_DEVINFO_GLOBAL) - return 0; - - /* except for the global list, where we have an exception */ - if (sdev->sdev_bflags) - return sdev->sdev_bflags; - - return scsi_default_dev_flags; + return bflags; } -EXPORT_SYMBOL(scsi_get_device_flags_keyed); #ifdef CONFIG_SCSI_PROC_FS -struct double_list { - struct list_head *top; - struct list_head *bottom; -}; - static int devinfo_seq_show(struct seq_file *m, void *v) { - struct double_list *dl = v; - struct scsi_dev_info_list_table *devinfo_table = - list_entry(dl->top, struct scsi_dev_info_list_table, node); struct scsi_dev_info_list *devinfo = - list_entry(dl->bottom, struct scsi_dev_info_list, - dev_info_list); - - if (devinfo_table->scsi_dev_info_list.next == dl->bottom && - devinfo_table->name) - seq_printf(m, "[%s]:\n", devinfo_table->name); + list_entry(v, struct scsi_dev_info_list, dev_info_list); seq_printf(m, "'%.8s' '%.16s' 0x%x\n", - devinfo->vendor, devinfo->model, devinfo->flags); + devinfo->vendor, devinfo->model, devinfo->flags); return 0; } -static void *devinfo_seq_start(struct seq_file *m, loff_t *ppos) +static void * devinfo_seq_start(struct seq_file *m, loff_t *pos) { - struct double_list *dl = kmalloc(sizeof(*dl), GFP_KERNEL); - loff_t pos = *ppos; - - if (!dl) - return NULL; - - list_for_each(dl->top, &scsi_dev_info_list) { - struct scsi_dev_info_list_table *devinfo_table = - list_entry(dl->top, struct scsi_dev_info_list_table, - node); - list_for_each(dl->bottom, &devinfo_table->scsi_dev_info_list) - if (pos-- == 0) - return dl; - } - - kfree(dl); - return NULL; + return seq_list_start(&scsi_dev_info_list, *pos); } -static void *devinfo_seq_next(struct seq_file *m, void *v, loff_t *ppos) +static void * devinfo_seq_next(struct seq_file *m, void *v, loff_t *pos) { - struct double_list *dl = v; - struct scsi_dev_info_list_table *devinfo_table = - list_entry(dl->top, struct scsi_dev_info_list_table, node); - - ++*ppos; - dl->bottom = dl->bottom->next; - while (&devinfo_table->scsi_dev_info_list == dl->bottom) { - dl->top = dl->top->next; - if (dl->top == &scsi_dev_info_list) { - kfree(dl); - return NULL; - } - devinfo_table = list_entry(dl->top, - struct scsi_dev_info_list_table, - node); - dl->bottom = devinfo_table->scsi_dev_info_list.next; - } - - return dl; + return seq_list_next(v, &scsi_dev_info_list, pos); } static void devinfo_seq_stop(struct seq_file *m, void *v) { - kfree(v); } static const struct seq_operations scsi_devinfo_seq_ops = { @@ -689,78 +549,19 @@ MODULE_PARM_DESC(default_dev_flags, **/ void scsi_exit_devinfo(void) { + struct list_head *lh, *lh_next; + struct scsi_dev_info_list *devinfo; + #ifdef CONFIG_SCSI_PROC_FS remove_proc_entry("scsi/device_info", NULL); #endif - scsi_dev_info_remove_list(SCSI_DEVINFO_GLOBAL); -} - -/** - * scsi_dev_info_add_list - add a new devinfo list - * @key: key of the list to add - * @name: Name of the list to add (for /proc/scsi/device_info) - * - * Adds the requested list, returns zero on success, -EEXIST if the - * key is already registered to a list, or other error on failure. - */ -int scsi_dev_info_add_list(int key, const char *name) -{ - struct scsi_dev_info_list_table *devinfo_table = - scsi_devinfo_lookup_by_key(key); - - if (!IS_ERR(devinfo_table)) - /* list already exists */ - return -EEXIST; - - devinfo_table = kmalloc(sizeof(*devinfo_table), GFP_KERNEL); - - if (!devinfo_table) - return -ENOMEM; - - INIT_LIST_HEAD(&devinfo_table->node); - INIT_LIST_HEAD(&devinfo_table->scsi_dev_info_list); - devinfo_table->name = name; - devinfo_table->key = key; - list_add_tail(&devinfo_table->node, &scsi_dev_info_list); - - return 0; -} -EXPORT_SYMBOL(scsi_dev_info_add_list); - -/** - * scsi_dev_info_remove_list - destroy an added devinfo list - * @key: key of the list to destroy - * - * Iterates over the entire list first, freeing all the values, then - * frees the list itself. Returns 0 on success or -EINVAL if the key - * can't be found. - */ -int scsi_dev_info_remove_list(int key) -{ - struct list_head *lh, *lh_next; - struct scsi_dev_info_list_table *devinfo_table = - scsi_devinfo_lookup_by_key(key); - - if (IS_ERR(devinfo_table)) - /* no such list */ - return -EINVAL; - - /* remove from the master list */ - list_del(&devinfo_table->node); - - list_for_each_safe(lh, lh_next, &devinfo_table->scsi_dev_info_list) { - struct scsi_dev_info_list *devinfo; - + list_for_each_safe(lh, lh_next, &scsi_dev_info_list) { devinfo = list_entry(lh, struct scsi_dev_info_list, dev_info_list); kfree(devinfo); } - kfree(devinfo_table); - - return 0; } -EXPORT_SYMBOL(scsi_dev_info_remove_list); /** * scsi_init_devinfo - set up the dynamic device list. @@ -776,13 +577,9 @@ int __init scsi_init_devinfo(void) #endif int error, i; - error = scsi_dev_info_add_list(SCSI_DEVINFO_GLOBAL, NULL); - if (error) - return error; - error = scsi_dev_info_list_add_str(scsi_dev_flags); if (error) - goto out; + return error; for (i = 0; scsi_static_device_list[i].vendor; i++) { error = scsi_dev_info_list_add(1 /* compatibile */, diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index f3c40898fc7d..30f3275e119e 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1207,7 +1207,6 @@ int scsi_prep_fn(struct request_queue *q, struct request *req) ret = scsi_setup_blk_pc_cmnd(sdev, req); return scsi_prep_return(q, req, ret); } -EXPORT_SYMBOL(scsi_prep_fn); /* * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index 021e503c8c44..fbc83bebdd8e 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -39,25 +39,9 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) #endif /* scsi_devinfo.c */ - -/* list of keys for the lists */ -enum { - SCSI_DEVINFO_GLOBAL = 0, - SCSI_DEVINFO_SPI, -}; - extern int scsi_get_device_flags(struct scsi_device *sdev, const unsigned char *vendor, const unsigned char *model); -extern int scsi_get_device_flags_keyed(struct scsi_device *sdev, - const unsigned char *vendor, - const unsigned char *model, int key); -extern int scsi_dev_info_list_add_keyed(int compatible, char *vendor, - char *model, char *strflags, - int flags, int key); -extern int scsi_dev_info_add_list(int key, const char *name); -extern int scsi_dev_info_remove_list(int key); - extern int __init scsi_init_devinfo(void); extern void scsi_exit_devinfo(void); @@ -87,6 +71,7 @@ extern int scsi_init_queue(void); extern void scsi_exit_queue(void); struct request_queue; struct request; +extern int scsi_prep_fn(struct request_queue *, struct request *); extern struct kmem_cache *scsi_sdb_cache; /* scsi_proc.c */ diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index 91482f2dcc50..fa4711d12744 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -420,12 +420,29 @@ static int scsi_bus_resume(struct device * dev) return err; } +static int scsi_bus_remove(struct device *dev) +{ + struct device_driver *drv = dev->driver; + struct scsi_device *sdev = to_scsi_device(dev); + int err = 0; + + /* reset the prep_fn back to the default since the + * driver may have altered it and it's being removed */ + blk_queue_prep_rq(sdev->request_queue, scsi_prep_fn); + + if (drv && drv->remove) + err = drv->remove(dev); + + return 0; +} + struct bus_type scsi_bus_type = { .name = "scsi", .match = scsi_bus_match, .uevent = scsi_bus_uevent, .suspend = scsi_bus_suspend, .resume = scsi_bus_resume, + .remove = scsi_bus_remove, }; EXPORT_SYMBOL_GPL(scsi_bus_type); diff --git a/trunk/drivers/scsi/scsi_transport_fc.c b/trunk/drivers/scsi/scsi_transport_fc.c index 292c02f810d0..3f64d93b6c8b 100644 --- a/trunk/drivers/scsi/scsi_transport_fc.c +++ b/trunk/drivers/scsi/scsi_transport_fc.c @@ -3397,6 +3397,7 @@ fc_destroy_bsgjob(struct fc_bsg_job *job) kfree(job); } + /** * fc_bsg_jobdone - completion routine for bsg requests that the LLD has * completed @@ -3407,10 +3408,15 @@ fc_bsg_jobdone(struct fc_bsg_job *job) { struct request *req = job->req; struct request *rsp = req->next_rq; + unsigned long flags; int err; - err = job->req->errors = job->reply->result; + spin_lock_irqsave(&job->job_lock, flags); + job->state_flags |= FC_RQST_STATE_DONE; + job->ref_cnt--; + spin_unlock_irqrestore(&job->job_lock, flags); + err = job->req->errors = job->reply->result; if (err < 0) /* we're only returning the result field in the reply */ job->req->sense_len = sizeof(uint32_t); @@ -3427,27 +3433,13 @@ fc_bsg_jobdone(struct fc_bsg_job *job) rsp->resid_len -= min(job->reply->reply_payload_rcv_len, rsp->resid_len); } - blk_complete_request(req); -} - -/** - * fc_bsg_softirq_done - softirq done routine for destroying the bsg requests - * @req: BSG request that holds the job to be destroyed - */ -static void fc_bsg_softirq_done(struct request *rq) -{ - struct fc_bsg_job *job = rq->special; - unsigned long flags; - spin_lock_irqsave(&job->job_lock, flags); - job->state_flags |= FC_RQST_STATE_DONE; - job->ref_cnt--; - spin_unlock_irqrestore(&job->job_lock, flags); + blk_end_request_all(req, err); - blk_end_request_all(rq, rq->errors); fc_destroy_bsgjob(job); } + /** * fc_bsg_job_timeout - handler for when a bsg request timesout * @req: request that timed out @@ -3479,13 +3471,19 @@ fc_bsg_job_timeout(struct request *req) "abort failed with status %d\n", err); } + if (!done) { + spin_lock_irqsave(&job->job_lock, flags); + job->ref_cnt--; + spin_unlock_irqrestore(&job->job_lock, flags); + fc_destroy_bsgjob(job); + } + /* the blk_end_sync_io() doesn't check the error */ - if (done) - return BLK_EH_NOT_HANDLED; - else - return BLK_EH_HANDLED; + return BLK_EH_HANDLED; } + + static int fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req) { @@ -3670,14 +3668,13 @@ static void fc_bsg_goose_queue(struct fc_rport *rport) { int flagset; - unsigned long flags; if (!rport->rqst_q) return; get_device(&rport->dev); - spin_lock_irqsave(rport->rqst_q->queue_lock, flags); + spin_lock(rport->rqst_q->queue_lock); flagset = test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags) && !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); if (flagset) @@ -3685,7 +3682,7 @@ fc_bsg_goose_queue(struct fc_rport *rport) __blk_run_queue(rport->rqst_q); if (flagset) queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); - spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); + spin_unlock(rport->rqst_q->queue_lock); put_device(&rport->dev); } @@ -3862,7 +3859,7 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) struct fc_internal *i = to_fc_internal(shost->transportt); struct request_queue *q; int err; - char bsg_name[20]; + char bsg_name[BUS_ID_SIZE]; /*20*/ fc_host->rqst_q = NULL; @@ -3882,7 +3879,6 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) q->queuedata = shost; queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q); - blk_queue_softirq_done(q, fc_bsg_softirq_done); blk_queue_rq_timed_out(q, fc_bsg_job_timeout); blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT); @@ -3928,7 +3924,6 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport) q->queuedata = rport; queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q); - blk_queue_softirq_done(q, fc_bsg_softirq_done); blk_queue_rq_timed_out(q, fc_bsg_job_timeout); blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index 783e33c65eb7..f3e664628d7a 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -692,7 +692,6 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) "Too many iscsi targets. Max " "number of targets is %d.\n", ISCSI_MAX_TARGET - 1); - err = -EOVERFLOW; goto release_host; } } diff --git a/trunk/drivers/scsi/scsi_transport_sas.c b/trunk/drivers/scsi/scsi_transport_sas.c index 0895d3c71b03..d606452297cf 100644 --- a/trunk/drivers/scsi/scsi_transport_sas.c +++ b/trunk/drivers/scsi/scsi_transport_sas.c @@ -173,9 +173,9 @@ static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost, ret = handler(shost, rphy, req); req->errors = ret; - blk_end_request_all(req, ret); - spin_lock_irq(q->queue_lock); + + req->end_io(req, ret); } } diff --git a/trunk/drivers/scsi/scsi_transport_spi.c b/trunk/drivers/scsi/scsi_transport_spi.c index c25bd9a34e02..654a34fb04cb 100644 --- a/trunk/drivers/scsi/scsi_transport_spi.c +++ b/trunk/drivers/scsi/scsi_transport_spi.c @@ -46,22 +46,6 @@ #define DV_RETRIES 3 /* should only need at most * two cc/ua clears */ -/* Our blacklist flags */ -enum { - SPI_BLIST_NOIUS = 0x1, -}; - -/* blacklist table, modelled on scsi_devinfo.c */ -static struct { - char *vendor; - char *model; - unsigned flags; -} spi_static_device_list[] __initdata = { - {"HP", "Ultrium 3-SCSI", SPI_BLIST_NOIUS }, - {"IBM", "ULTRIUM-TD3", SPI_BLIST_NOIUS }, - {NULL, NULL, 0} -}; - /* Private data accessors (keep these out of the header file) */ #define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress) #define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex) @@ -223,9 +207,6 @@ static int spi_device_configure(struct transport_container *tc, { struct scsi_device *sdev = to_scsi_device(dev); struct scsi_target *starget = sdev->sdev_target; - unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], - &sdev->inquiry[16], - SCSI_DEVINFO_SPI); /* Populate the target capability fields with the values * gleaned from the device inquiry */ @@ -235,10 +216,6 @@ static int spi_device_configure(struct transport_container *tc, spi_support_dt(starget) = scsi_device_dt(sdev); spi_support_dt_only(starget) = scsi_device_dt_only(sdev); spi_support_ius(starget) = scsi_device_ius(sdev); - if (bflags & SPI_BLIST_NOIUS) { - dev_info(dev, "Information Units disabled by blacklist\n"); - spi_support_ius(starget) = 0; - } spi_support_qas(starget) = scsi_device_qas(sdev); return 0; @@ -856,7 +833,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) return; } - if (!spi_support_wide(starget)) { + if (!scsi_device_wide(sdev)) { spi_max_width(starget) = 0; max_width = 0; } @@ -883,7 +860,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) return; /* device can't handle synchronous */ - if (!spi_support_sync(starget) && !spi_support_dt(starget)) + if (!scsi_device_sync(sdev) && !scsi_device_dt(sdev)) return; /* len == -1 is the signal that we need to ascertain the @@ -899,14 +876,13 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) /* try QAS requests; this should be harmless to set if the * target supports it */ - if (spi_support_qas(starget) && spi_max_qas(starget)) { + if (scsi_device_qas(sdev) && spi_max_qas(starget)) { DV_SET(qas, 1); } else { DV_SET(qas, 0); } - if (spi_support_ius(starget) && spi_max_iu(starget) && - min_period < 9) { + if (scsi_device_ius(sdev) && spi_max_iu(starget) && min_period < 9) { /* This u320 (or u640). Set IU transfers */ DV_SET(iu, 1); /* Then set the optional parameters */ @@ -926,7 +902,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) i->f->get_signalling(shost); if (spi_signalling(shost) == SPI_SIGNAL_SE || spi_signalling(shost) == SPI_SIGNAL_HVD || - !spi_support_dt(starget)) { + !scsi_device_dt(sdev)) { DV_SET(dt, 0); } else { DV_SET(dt, 1); @@ -1547,21 +1523,7 @@ EXPORT_SYMBOL(spi_release_transport); static __init int spi_transport_init(void) { - int error = scsi_dev_info_add_list(SCSI_DEVINFO_SPI, - "SCSI Parallel Transport Class"); - if (!error) { - int i; - - for (i = 0; spi_static_device_list[i].vendor; i++) - scsi_dev_info_list_add_keyed(1, /* compatible */ - spi_static_device_list[i].vendor, - spi_static_device_list[i].model, - NULL, - spi_static_device_list[i].flags, - SCSI_DEVINFO_SPI); - } - - error = transport_class_register(&spi_transport_class); + int error = transport_class_register(&spi_transport_class); if (error) return error; error = anon_transport_class_register(&spi_device_class); @@ -1573,7 +1535,6 @@ static void __exit spi_transport_exit(void) transport_class_unregister(&spi_transport_class); anon_transport_class_unregister(&spi_device_class); transport_class_unregister(&spi_host_class); - scsi_dev_info_remove_list(SCSI_DEVINFO_SPI); } MODULE_AUTHOR("Martin Hicks"); diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 5616cd780ff3..878b17a9af30 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -1307,7 +1307,6 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, int sense_valid = 0; int the_result; int retries = 3; - unsigned int alignment; unsigned long long lba; unsigned sector_size; @@ -1359,16 +1358,6 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, return -EOVERFLOW; } - /* Logical blocks per physical block exponent */ - sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size; - - /* Lowest aligned logical block */ - alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size; - blk_queue_alignment_offset(sdp->request_queue, alignment); - if (alignment && sdkp->first_scan) - sd_printk(KERN_NOTICE, sdkp, - "physical block alignment offset: %u\n", alignment); - sdkp->capacity = lba + 1; return sector_size; } @@ -1420,7 +1409,6 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, } sdkp->capacity = lba + 1; - sdkp->hw_sector_size = sector_size; return sector_size; } @@ -1533,17 +1521,11 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) string_get_size(sz, STRING_UNITS_10, cap_str_10, sizeof(cap_str_10)); - if (sdkp->first_scan || old_capacity != sdkp->capacity) { + if (sdkp->first_scan || old_capacity != sdkp->capacity) sd_printk(KERN_NOTICE, sdkp, - "%llu %d-byte logical blocks: (%s/%s)\n", + "%llu %d-byte hardware sectors: (%s/%s)\n", (unsigned long long)sdkp->capacity, sector_size, cap_str_10, cap_str_2); - - if (sdkp->hw_sector_size != sector_size) - sd_printk(KERN_NOTICE, sdkp, - "%u-byte physical blocks\n", - sdkp->hw_sector_size); - } } /* Rescale capacity to 512-byte units */ @@ -1556,7 +1538,6 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) else if (sector_size == 256) sdkp->capacity >>= 1; - blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size); sdkp->device->sector_size = sector_size; } @@ -1794,52 +1775,6 @@ void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) return; } -/** - * sd_read_block_limits - Query disk device for preferred I/O sizes. - * @disk: disk to query - */ -static void sd_read_block_limits(struct scsi_disk *sdkp) -{ - unsigned int sector_sz = sdkp->device->sector_size; - char *buffer; - - /* Block Limits VPD */ - buffer = scsi_get_vpd_page(sdkp->device, 0xb0); - - if (buffer == NULL) - return; - - blk_queue_io_min(sdkp->disk->queue, - get_unaligned_be16(&buffer[6]) * sector_sz); - blk_queue_io_opt(sdkp->disk->queue, - get_unaligned_be32(&buffer[12]) * sector_sz); - - kfree(buffer); -} - -/** - * sd_read_block_characteristics - Query block dev. characteristics - * @disk: disk to query - */ -static void sd_read_block_characteristics(struct scsi_disk *sdkp) -{ - char *buffer; - u16 rot; - - /* Block Device Characteristics VPD */ - buffer = scsi_get_vpd_page(sdkp->device, 0xb1); - - if (buffer == NULL) - return; - - rot = get_unaligned_be16(&buffer[4]); - - if (rot == 1) - queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue); - - kfree(buffer); -} - /** * sd_revalidate_disk - called the first time a new disk is seen, * performs disk spin up, read_capacity, etc. @@ -1877,8 +1812,6 @@ static int sd_revalidate_disk(struct gendisk *disk) */ if (sdkp->media_present) { sd_read_capacity(sdkp, buffer); - sd_read_block_limits(sdkp); - sd_read_block_characteristics(sdkp); sd_read_write_protect_flag(sdkp, buffer); sd_read_cache_type(sdkp, buffer); sd_read_app_tag_own(sdkp, buffer); @@ -2001,8 +1934,6 @@ static void sd_probe_async(void *data, async_cookie_t cookie) add_disk(gd); sd_dif_config_host(sdkp); - sd_revalidate_disk(gd); - sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", sdp->removable ? "removable " : ""); } @@ -2123,7 +2054,6 @@ static int sd_remove(struct device *dev) async_synchronize_full(); sdkp = dev_get_drvdata(dev); - blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); device_del(&sdkp->dev); del_gendisk(sdkp->disk); sd_shutdown(dev); diff --git a/trunk/drivers/scsi/sd.h b/trunk/drivers/scsi/sd.h index 8474b5bad3fe..708778cf5f06 100644 --- a/trunk/drivers/scsi/sd.h +++ b/trunk/drivers/scsi/sd.h @@ -45,7 +45,6 @@ struct scsi_disk { unsigned int openers; /* protected by BKL for now, yuck */ sector_t capacity; /* size in 512-byte sectors */ u32 index; - unsigned short hw_sector_size; u8 media_present; u8 write_prot; u8 protection_type;/* Data Integrity Field */ diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index ef142fd47a83..8201387b4daa 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -210,11 +210,13 @@ static void sg_put_dev(Sg_device *sdp); static int sg_allow_access(struct file *filp, unsigned char *cmd) { struct sg_fd *sfp = (struct sg_fd *)filp->private_data; + struct request_queue *q = sfp->parentdp->device->request_queue; if (sfp->parentdp->device->type == TYPE_SCANNER) return 0; - return blk_verify_command(cmd, filp->f_mode & FMODE_WRITE); + return blk_verify_command(&q->cmd_filter, + cmd, filp->f_mode & FMODE_WRITE); } static int diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c index cce0fe4c8a3b..cd350dfc1216 100644 --- a/trunk/drivers/scsi/sr.c +++ b/trunk/drivers/scsi/sr.c @@ -881,7 +881,6 @@ static int sr_remove(struct device *dev) { struct scsi_cd *cd = dev_get_drvdata(dev); - blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); del_gendisk(cd->disk); mutex_lock(&sr_ref_mutex); diff --git a/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c b/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c index 297deb817a5d..69ad4945c936 100644 --- a/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/trunk/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -2321,9 +2321,8 @@ static void sym_int_par (struct sym_hcb *np, u_short sist) int phase = cmd & 7; struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa); - if (printk_ratelimit()) - printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n", - sym_name(np), hsts, dbc, sbcl); + printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n", + sym_name(np), hsts, dbc, sbcl); /* * Check that the chip is connected to the SCSI BUS. diff --git a/trunk/drivers/scsi/zalon.c b/trunk/drivers/scsi/zalon.c index 27e84e4b1fa9..97f3158fa7b5 100644 --- a/trunk/drivers/scsi/zalon.c +++ b/trunk/drivers/scsi/zalon.c @@ -134,7 +134,7 @@ zalon_probe(struct parisc_device *dev) host = ncr_attach(&zalon7xx_template, unit, &device); if (!host) - return -ENODEV; + goto fail; if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) { dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching\n ", diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index 6160e03f410c..e371a9c15341 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -398,7 +398,8 @@ static int sbs_init(struct pci_dev *dev) { u8 __iomem *p; - p = pci_ioremap_bar(dev, 0); + p = ioremap_nocache(pci_resource_start(dev, 0), + pci_resource_len(dev, 0)); if (p == NULL) return -ENOMEM; @@ -422,7 +423,8 @@ static void __devexit sbs_exit(struct pci_dev *dev) { u8 __iomem *p; - p = pci_ioremap_bar(dev, 0); + p = ioremap_nocache(pci_resource_start(dev, 0), + pci_resource_len(dev, 0)); /* FIXME: What if resource_len < OCT_REG_CR_OFF */ if (p != NULL) writeb(0, p + OCT_REG_CR_OFF); @@ -759,8 +761,6 @@ static int pci_netmos_init(struct pci_dev *dev) /* subdevice 0x00PS means

parallel, serial */ unsigned int num_serial = dev->subsystem_device & 0xf; - if (dev->device == PCI_DEVICE_ID_NETMOS_9901) - return 0; if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && dev->subsystem_device == 0x0299) return 0; @@ -3559,10 +3559,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_VENDOR_ID_IBM, 0x0299, 0, 0, pbn_b0_bt_2_115200 }, - { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, - 0xA000, 0x1000, - 0, 0, pbn_b0_1_115200 }, - /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL diff --git a/trunk/drivers/serial/icom.c b/trunk/drivers/serial/icom.c index cd1b6a45bb82..9f2891c2c4a2 100644 --- a/trunk/drivers/serial/icom.c +++ b/trunk/drivers/serial/icom.c @@ -1548,7 +1548,8 @@ 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 = ioremap(icom_adapter->base_addr_pci, + pci_resource_len(dev, 0)); if (!icom_adapter->base_addr) goto probe_exit1; diff --git a/trunk/drivers/serial/jsm/jsm_tty.c b/trunk/drivers/serial/jsm/jsm_tty.c index 00f4577d2f7f..107ce2e187b8 100644 --- a/trunk/drivers/serial/jsm/jsm_tty.c +++ b/trunk/drivers/serial/jsm/jsm_tty.c @@ -467,7 +467,7 @@ int __devinit jsm_uart_port_init(struct jsm_board *brd) printk(KERN_INFO "jsm: linemap is full, added device failed\n"); continue; } else - set_bit(line, linemap); + set_bit((int)line, linemap); brd->channels[i]->uart_port.line = line; if (uart_add_one_port (&jsm_uart_driver, &brd->channels[i]->uart_port)) printk(KERN_INFO "jsm: add device failed\n"); @@ -503,7 +503,7 @@ int jsm_remove_uart_port(struct jsm_board *brd) ch = brd->channels[i]; - clear_bit(ch->uart_port.line, linemap); + clear_bit((int)(ch->uart_port.line), linemap); uart_remove_one_port(&jsm_uart_driver, &brd->channels[i]->uart_port); } diff --git a/trunk/drivers/serial/serial_txx9.c b/trunk/drivers/serial/serial_txx9.c index 54dd16d66a4b..7313c2edcb83 100644 --- a/trunk/drivers/serial/serial_txx9.c +++ b/trunk/drivers/serial/serial_txx9.c @@ -461,94 +461,6 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&up->port.lock, flags); } -#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL) -/* - * Wait for transmitter & holding register to empty - */ -static void wait_for_xmitr(struct uart_txx9_port *up) -{ - unsigned int tmout = 10000; - - /* Wait up to 10ms for the character(s) to be sent. */ - while (--tmout && - !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS)) - udelay(1); - - /* Wait up to 1s for flow control if necessary */ - if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (--tmout && - (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS)) - udelay(1); - } -} -#endif - -#ifdef CONFIG_CONSOLE_POLL -/* - * Console polling routines for writing and reading from the uart while - * in an interrupt or debug context. - */ - -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; - - /* - * First save the IER then disable the interrupts - */ - ier = sio_in(up, TXX9_SIDICR); - sio_out(up, TXX9_SIDICR, 0); - - while (sio_in(up, TXX9_SIDISR) & TXX9_SIDISR_UVALID) - ; - - c = sio_in(up, TXX9_SIRFIFO); - - /* - * Finally, clear RX interrupt status - * and restore the IER - */ - sio_mask(up, TXX9_SIDISR, TXX9_SIDISR_RDIS); - sio_out(up, TXX9_SIDICR, ier); - return c; -} - - -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; - - /* - * First save the IER then disable the interrupts - */ - ier = sio_in(up, TXX9_SIDICR); - sio_out(up, TXX9_SIDICR, 0); - - wait_for_xmitr(up); - /* - * Send the character out. - * If a LF, also do CR... - */ - sio_out(up, TXX9_SITFIFO, c); - if (c == 10) { - wait_for_xmitr(up); - sio_out(up, TXX9_SITFIFO, 13); - } - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - sio_out(up, TXX9_SIDICR, ier); -} - -#endif /* CONFIG_CONSOLE_POLL */ - static int serial_txx9_startup(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; @@ -869,10 +781,6 @@ static struct uart_ops serial_txx9_pops = { .release_port = serial_txx9_release_port, .request_port = serial_txx9_request_port, .config_port = serial_txx9_config_port, -#ifdef CONFIG_CONSOLE_POLL - .poll_get_char = serial_txx9_get_poll_char, - .poll_put_char = serial_txx9_put_poll_char, -#endif }; static struct uart_txx9_port serial_txx9_ports[UART_NR]; @@ -895,6 +803,27 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv, #ifdef CONFIG_SERIAL_TXX9_CONSOLE +/* + * Wait for transmitter & holding register to empty + */ +static inline void wait_for_xmitr(struct uart_txx9_port *up) +{ + unsigned int tmout = 10000; + + /* Wait up to 10ms for the character(s) to be sent. */ + while (--tmout && + !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS)) + udelay(1); + + /* Wait up to 1s for flow control if necessary */ + if (up->port.flags & UPF_CONS_FLOW) { + tmout = 1000000; + while (--tmout && + (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS)) + udelay(1); + } +} + static void serial_txx9_console_putchar(struct uart_port *port, int ch) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; diff --git a/trunk/drivers/serial/vr41xx_siu.c b/trunk/drivers/serial/vr41xx_siu.c index dac550e57c29..0573f3b5175e 100644 --- a/trunk/drivers/serial/vr41xx_siu.c +++ b/trunk/drivers/serial/vr41xx_siu.c @@ -1,7 +1,7 @@ /* * Driver for NEC VR4100 series Serial Interface Unit. * - * Copyright (C) 2004-2008 Yoichi Yuasa + * Copyright (C) 2004-2008 Yoichi Yuasa * * Based on drivers/serial/8250.c, by Russell King. * diff --git a/trunk/drivers/spi/omap_uwire.c b/trunk/drivers/spi/omap_uwire.c index 8980a5640bd9..aa90ddb37066 100644 --- a/trunk/drivers/spi/omap_uwire.c +++ b/trunk/drivers/spi/omap_uwire.c @@ -514,8 +514,6 @@ static int __init uwire_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; - master->flags = SPI_MASTER_HALF_DUPLEX; - master->bus_num = 2; /* "official" */ master->num_chipselect = 4; master->setup = uwire_setup; diff --git a/trunk/drivers/spi/spi_bitbang.c b/trunk/drivers/spi/spi_bitbang.c index f1db395dd889..2a5abc08e857 100644 --- a/trunk/drivers/spi/spi_bitbang.c +++ b/trunk/drivers/spi/spi_bitbang.c @@ -258,11 +258,6 @@ static void bitbang_work(struct work_struct *work) struct spi_bitbang *bitbang = container_of(work, struct spi_bitbang, work); unsigned long flags; - int do_setup = -1; - int (*setup_transfer)(struct spi_device *, - struct spi_transfer *); - - setup_transfer = bitbang->setup_transfer; spin_lock_irqsave(&bitbang->lock, flags); bitbang->busy = 1; @@ -274,6 +269,8 @@ static void bitbang_work(struct work_struct *work) unsigned tmp; unsigned cs_change; int status; + int (*setup_transfer)(struct spi_device *, + struct spi_transfer *); m = container_of(bitbang->queue.next, struct spi_message, queue); @@ -290,19 +287,19 @@ static void bitbang_work(struct work_struct *work) tmp = 0; cs_change = 1; status = 0; + setup_transfer = NULL; list_for_each_entry (t, &m->transfers, transfer_list) { - /* override speed or wordsize? */ - if (t->speed_hz || t->bits_per_word) - do_setup = 1; - - /* init (-1) or override (1) transfer params */ - if (do_setup != 0) { + /* override or restore speed and wordsize */ + if (t->speed_hz || t->bits_per_word) { + setup_transfer = bitbang->setup_transfer; if (!setup_transfer) { status = -ENOPROTOOPT; break; } + } + if (setup_transfer) { status = setup_transfer(spi, t); if (status < 0) break; @@ -366,10 +363,9 @@ static void bitbang_work(struct work_struct *work) m->status = status; m->complete(m->context); - /* restore speed and wordsize if it was overridden */ - if (do_setup == 1) + /* restore speed and wordsize */ + if (setup_transfer) setup_transfer(spi, NULL); - do_setup = 0; /* normally deactivate chipselect ... unless no error and * cs_change has hinted that the next message will probably diff --git a/trunk/drivers/spi/spidev.c b/trunk/drivers/spi/spidev.c index 606e7a40a8da..5d869c4d3eb2 100644 --- a/trunk/drivers/spi/spidev.c +++ b/trunk/drivers/spi/spidev.c @@ -58,20 +58,15 @@ static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; /* Bit masks for spi_device.mode management. Note that incorrect - * settings for some settings can cause *lots* of trouble for other - * devices on a shared bus: + * settings for CS_HIGH and 3WIRE can cause *lots* of trouble for other + * devices on a shared bus: CS_HIGH, because this device will be + * active when it shouldn't be; 3WIRE, because when active it won't + * behave as it should. * - * - CS_HIGH ... this device will be active when it shouldn't be - * - 3WIRE ... when active, it won't behave as it should - * - NO_CS ... there will be no explicit message boundaries; this - * is completely incompatible with the shared bus model - * - READY ... transfers may proceed when they shouldn't. - * - * REVISIT should changing those flags be privileged? + * REVISIT should changing those two modes be privileged? */ #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ - | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ - | SPI_NO_CS | SPI_READY) + | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) struct spidev_data { dev_t devt; diff --git a/trunk/drivers/ssb/driver_mipscore.c b/trunk/drivers/ssb/driver_mipscore.c index 3c6feed46f6e..3fd3e3b412b6 100644 --- a/trunk/drivers/ssb/driver_mipscore.c +++ b/trunk/drivers/ssb/driver_mipscore.c @@ -49,54 +49,29 @@ static const u32 ipsflag_irq_shift[] = { static inline u32 ssb_irqflag(struct ssb_device *dev) { - u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG); - if (tpsflag) - return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG; - else - /* not irq supported */ - return 0x3f; -} - -static struct ssb_device *find_device(struct ssb_device *rdev, int irqflag) -{ - struct ssb_bus *bus = rdev->bus; - int i; - for (i = 0; i < bus->nr_devices; i++) { - struct ssb_device *dev; - dev = &(bus->devices[i]); - if (ssb_irqflag(dev) == irqflag) - return dev; - } - return NULL; + return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG; } /* Get the MIPS IRQ assignment for a specified device. * If unassigned, 0 is returned. - * If disabled, 5 is returned. - * If not supported, 6 is returned. */ unsigned int ssb_mips_irq(struct ssb_device *dev) { struct ssb_bus *bus = dev->bus; - struct ssb_device *mdev = bus->mipscore.dev; u32 irqflag; u32 ipsflag; u32 tmp; unsigned int irq; irqflag = ssb_irqflag(dev); - if (irqflag == 0x3f) - return 6; ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG); for (irq = 1; irq <= 4; irq++) { tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]); if (tmp == irqflag) break; } - if (irq == 5) { - if ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)) - irq = 0; - } + if (irq == 5) + irq = 0; return irq; } @@ -122,56 +97,25 @@ static void set_irq(struct ssb_device *dev, unsigned int irq) struct ssb_device *mdev = bus->mipscore.dev; u32 irqflag = ssb_irqflag(dev); - BUG_ON(oldirq == 6); - dev->irq = irq + 2; + ssb_dprintk(KERN_INFO PFX + "set_irq: core 0x%04x, irq %d => %d\n", + dev->id.coreid, oldirq, irq); /* clear the old irq */ if (oldirq == 0) ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))); - else if (oldirq != 5) + else clear_irq(bus, oldirq); /* assign the new one */ if (irq == 0) { ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) | ssb_read32(mdev, SSB_INTVEC))); } else { - u32 ipsflag = ssb_read32(mdev, SSB_IPSFLAG); - if ((ipsflag & ipsflag_irq_mask[irq]) != ipsflag_irq_mask[irq]) { - u32 oldipsflag = (ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]; - struct ssb_device *olddev = find_device(dev, oldipsflag); - if (olddev) - set_irq(olddev, 0); - } irqflag <<= ipsflag_irq_shift[irq]; - irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]); + irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]); ssb_write32(mdev, SSB_IPSFLAG, irqflag); } - ssb_dprintk(KERN_INFO PFX - "set_irq: core 0x%04x, irq %d => %d\n", - dev->id.coreid, oldirq+2, irq+2); -} - -static void print_irq(struct ssb_device *dev, unsigned int irq) -{ - int i; - static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; - ssb_dprintk(KERN_INFO PFX - "core 0x%04x, irq :", dev->id.coreid); - for (i = 0; i <= 6; i++) { - ssb_dprintk(" %s%s", irq_name[i], i==irq?"*":" "); - } - ssb_dprintk("\n"); -} - -static void dump_irq(struct ssb_bus *bus) -{ - int i; - for (i = 0; i < bus->nr_devices; i++) { - struct ssb_device *dev; - dev = &(bus->devices[i]); - print_irq(dev, ssb_mips_irq(dev)); - } } static void ssb_mips_serial_init(struct ssb_mipscore *mcore) @@ -253,23 +197,16 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ for (irq = 2, i = 0; i < bus->nr_devices; i++) { - int mips_irq; dev = &(bus->devices[i]); - mips_irq = ssb_mips_irq(dev); - if (mips_irq > 4) - dev->irq = 0; - else - dev->irq = mips_irq + 2; - if (dev->irq > 5) - continue; + dev->irq = ssb_mips_irq(dev) + 2; switch (dev->id.coreid) { case SSB_DEV_USB11_HOST: /* shouldn't need a separate irq line for non-4710, most of them have a proper * external usb controller on the pci */ if ((bus->chip_id == 0x4710) && (irq <= 4)) { set_irq(dev, irq++); + break; } - break; /* fallthrough */ case SSB_DEV_PCI: case SSB_DEV_ETHERNET: @@ -283,8 +220,6 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) } } } - ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n"); - dump_irq(bus); ssb_mips_serial_init(mcore); ssb_mips_flash_detect(mcore); diff --git a/trunk/drivers/staging/octeon/Makefile b/trunk/drivers/staging/octeon/Makefile index c0a583cc2227..3c839e37d37f 100644 --- a/trunk/drivers/staging/octeon/Makefile +++ b/trunk/drivers/staging/octeon/Makefile @@ -12,6 +12,7 @@ obj-${CONFIG_OCTEON_ETHERNET} := octeon-ethernet.o octeon-ethernet-objs := ethernet.o +octeon-ethernet-objs += ethernet-common.o octeon-ethernet-objs += ethernet-mdio.o octeon-ethernet-objs += ethernet-mem.o octeon-ethernet-objs += ethernet-proc.o diff --git a/trunk/drivers/staging/octeon/ethernet-common.c b/trunk/drivers/staging/octeon/ethernet-common.c new file mode 100644 index 000000000000..3e6f5b8cc63d --- /dev/null +++ b/trunk/drivers/staging/octeon/ethernet-common.c @@ -0,0 +1,328 @@ +/********************************************************************** + * Author: Cavium Networks + * + * Contact: support@caviumnetworks.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2007 Cavium Networks + * + * This file 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 file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Networks for more information +**********************************************************************/ +#include +#include +#include + +#include +#include + +#include "ethernet-defines.h" +#include "ethernet-tx.h" +#include "ethernet-mdio.h" +#include "ethernet-util.h" +#include "octeon-ethernet.h" +#include "ethernet-common.h" + +#include "cvmx-pip.h" +#include "cvmx-pko.h" +#include "cvmx-fau.h" +#include "cvmx-helper.h" + +#include "cvmx-gmxx-defs.h" + +/** + * Get the low level ethernet statistics + * + * @dev: Device to get the statistics from + * Returns Pointer to the statistics + */ +static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev) +{ + cvmx_pip_port_status_t rx_status; + cvmx_pko_port_status_t tx_status; + struct octeon_ethernet *priv = netdev_priv(dev); + + if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) { + if (octeon_is_simulation()) { + /* The simulator doesn't support statistics */ + memset(&rx_status, 0, sizeof(rx_status)); + memset(&tx_status, 0, sizeof(tx_status)); + } else { + cvmx_pip_get_port_status(priv->port, 1, &rx_status); + cvmx_pko_get_port_status(priv->port, 1, &tx_status); + } + + priv->stats.rx_packets += rx_status.inb_packets; + priv->stats.tx_packets += tx_status.packets; + priv->stats.rx_bytes += rx_status.inb_octets; + priv->stats.tx_bytes += tx_status.octets; + priv->stats.multicast += rx_status.multicast_packets; + priv->stats.rx_crc_errors += rx_status.inb_errors; + priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets; + + /* + * The drop counter must be incremented atomically + * since the RX tasklet also increments it. + */ +#ifdef CONFIG_64BIT + atomic64_add(rx_status.dropped_packets, + (atomic64_t *)&priv->stats.rx_dropped); +#else + atomic_add(rx_status.dropped_packets, + (atomic_t *)&priv->stats.rx_dropped); +#endif + } + + return &priv->stats; +} + +/** + * Set the multicast list. Currently unimplemented. + * + * @dev: Device to work on + */ +static void cvm_oct_common_set_multicast_list(struct net_device *dev) +{ + union cvmx_gmxx_prtx_cfg gmx_cfg; + struct octeon_ethernet *priv = netdev_priv(dev); + int interface = INTERFACE(priv->port); + int index = INDEX(priv->port); + + if ((interface < 2) + && (cvmx_helper_interface_get_mode(interface) != + CVMX_HELPER_INTERFACE_MODE_SPI)) { + union cvmx_gmxx_rxx_adr_ctl control; + control.u64 = 0; + control.s.bcst = 1; /* Allow broadcast MAC addresses */ + + if (dev->mc_list || (dev->flags & IFF_ALLMULTI) || + (dev->flags & IFF_PROMISC)) + /* Force accept multicast packets */ + control.s.mcst = 2; + else + /* Force reject multicat packets */ + control.s.mcst = 1; + + if (dev->flags & IFF_PROMISC) + /* + * Reject matches if promisc. Since CAM is + * shut off, should accept everything. + */ + control.s.cam_mode = 0; + else + /* Filter packets based on the CAM */ + control.s.cam_mode = 1; + + gmx_cfg.u64 = + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), + gmx_cfg.u64 & ~1ull); + + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface), + control.u64); + if (dev->flags & IFF_PROMISC) + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN + (index, interface), 0); + else + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN + (index, interface), 1); + + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), + gmx_cfg.u64); + } +} + +/** + * Set the hardware MAC address for a device + * + * @dev: Device to change the MAC address for + * @addr: Address structure to change it too. MAC address is addr + 2. + * Returns Zero on success + */ +static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) +{ + struct octeon_ethernet *priv = netdev_priv(dev); + union cvmx_gmxx_prtx_cfg gmx_cfg; + int interface = INTERFACE(priv->port); + int index = INDEX(priv->port); + + memcpy(dev->dev_addr, addr + 2, 6); + + if ((interface < 2) + && (cvmx_helper_interface_get_mode(interface) != + CVMX_HELPER_INTERFACE_MODE_SPI)) { + int i; + uint8_t *ptr = addr; + uint64_t mac = 0; + for (i = 0; i < 6; i++) + mac = (mac << 8) | (uint64_t) (ptr[i + 2]); + + gmx_cfg.u64 = + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), + gmx_cfg.u64 & ~1ull); + + cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac); + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), + ptr[2]); + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), + ptr[3]); + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), + ptr[4]); + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), + ptr[5]); + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), + ptr[6]); + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), + ptr[7]); + cvm_oct_common_set_multicast_list(dev); + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), + gmx_cfg.u64); + } + return 0; +} + +/** + * Change the link MTU. Unimplemented + * + * @dev: Device to change + * @new_mtu: The new MTU + * + * Returns Zero on success + */ +static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu) +{ + struct octeon_ethernet *priv = netdev_priv(dev); + int interface = INTERFACE(priv->port); + int index = INDEX(priv->port); +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + int vlan_bytes = 4; +#else + int vlan_bytes = 0; +#endif + + /* + * Limit the MTU to make sure the ethernet packets are between + * 64 bytes and 65535 bytes. + */ + if ((new_mtu + 14 + 4 + vlan_bytes < 64) + || (new_mtu + 14 + 4 + vlan_bytes > 65392)) { + pr_err("MTU must be between %d and %d.\n", + 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes); + return -EINVAL; + } + dev->mtu = new_mtu; + + if ((interface < 2) + && (cvmx_helper_interface_get_mode(interface) != + CVMX_HELPER_INTERFACE_MODE_SPI)) { + /* Add ethernet header and FCS, and VLAN if configured. */ + int max_packet = new_mtu + 14 + 4 + vlan_bytes; + + if (OCTEON_IS_MODEL(OCTEON_CN3XXX) + || OCTEON_IS_MODEL(OCTEON_CN58XX)) { + /* Signal errors on packets larger than the MTU */ + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface), + max_packet); + } else { + /* + * Set the hardware to truncate packets larger + * than the MTU and smaller the 64 bytes. + */ + union cvmx_pip_frm_len_chkx frm_len_chk; + frm_len_chk.u64 = 0; + frm_len_chk.s.minlen = 64; + frm_len_chk.s.maxlen = max_packet; + cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface), + frm_len_chk.u64); + } + /* + * Set the hardware to truncate packets larger than + * the MTU. The jabber register must be set to a + * multiple of 8 bytes, so round up. + */ + cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface), + (max_packet + 7) & ~7u); + } + return 0; +} + +/** + * Per network device initialization + * + * @dev: Device to initialize + * Returns Zero on success + */ +int cvm_oct_common_init(struct net_device *dev) +{ + static int count; + char mac[8] = { 0x00, 0x00, + octeon_bootinfo->mac_addr_base[0], + octeon_bootinfo->mac_addr_base[1], + octeon_bootinfo->mac_addr_base[2], + octeon_bootinfo->mac_addr_base[3], + octeon_bootinfo->mac_addr_base[4], + octeon_bootinfo->mac_addr_base[5] + count + }; + struct octeon_ethernet *priv = netdev_priv(dev); + + /* + * Force the interface to use the POW send if always_use_pow + * was specified or it is in the pow send list. + */ + if ((pow_send_group != -1) + && (always_use_pow || strstr(pow_send_list, dev->name))) + priv->queue = -1; + + if (priv->queue != -1) { + dev->hard_start_xmit = cvm_oct_xmit; + if (USE_HW_TCPUDP_CHECKSUM) + dev->features |= NETIF_F_IP_CSUM; + } else + dev->hard_start_xmit = cvm_oct_xmit_pow; + count++; + + dev->get_stats = cvm_oct_common_get_stats; + dev->set_mac_address = cvm_oct_common_set_mac_address; + dev->set_multicast_list = cvm_oct_common_set_multicast_list; + dev->change_mtu = cvm_oct_common_change_mtu; + dev->do_ioctl = cvm_oct_ioctl; + /* We do our own locking, Linux doesn't need to */ + dev->features |= NETIF_F_LLTX; + SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = cvm_oct_poll_controller; +#endif + + cvm_oct_mdio_setup_device(dev); + dev->set_mac_address(dev, mac); + dev->change_mtu(dev, dev->mtu); + + /* + * Zero out stats for port so we won't mistakenly show + * counters from the bootloader. + */ + memset(dev->get_stats(dev), 0, sizeof(struct net_device_stats)); + + return 0; +} + +void cvm_oct_common_uninit(struct net_device *dev) +{ + /* Currently nothing to do */ +} diff --git a/trunk/drivers/staging/octeon/ethernet-common.h b/trunk/drivers/staging/octeon/ethernet-common.h new file mode 100644 index 000000000000..2bd9cd76a398 --- /dev/null +++ b/trunk/drivers/staging/octeon/ethernet-common.h @@ -0,0 +1,29 @@ +/********************************************************************* + * Author: Cavium Networks + * + * Contact: support@caviumnetworks.com + * This file is part of the OCTEON SDK + * + * Copyright (c) 2003-2007 Cavium Networks + * + * This file 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 file is distributed in the hope that it will be useful, but + * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * or visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium Networks for more information +*********************************************************************/ + +int cvm_oct_common_init(struct net_device *dev); +void cvm_oct_common_uninit(struct net_device *dev); diff --git a/trunk/drivers/staging/octeon/ethernet-defines.h b/trunk/drivers/staging/octeon/ethernet-defines.h index f13131b03c33..8f7374e7664c 100644 --- a/trunk/drivers/staging/octeon/ethernet-defines.h +++ b/trunk/drivers/staging/octeon/ethernet-defines.h @@ -117,8 +117,6 @@ /* Maximum number of packets to process per interrupt. */ #define MAX_RX_PACKETS 120 -/* Maximum number of SKBs to try to free per xmit packet. */ -#define MAX_SKB_TO_FREE 10 #define MAX_OUT_QUEUE_DEPTH 1000 #ifndef CONFIG_SMP diff --git a/trunk/drivers/staging/octeon/ethernet-rgmii.c b/trunk/drivers/staging/octeon/ethernet-rgmii.c index 8704133fe127..8579f1670d1e 100644 --- a/trunk/drivers/staging/octeon/ethernet-rgmii.c +++ b/trunk/drivers/staging/octeon/ethernet-rgmii.c @@ -33,6 +33,7 @@ #include "ethernet-defines.h" #include "octeon-ethernet.h" +#include "ethernet-common.h" #include "ethernet-util.h" #include "cvmx-helper.h" @@ -264,7 +265,7 @@ static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id) return return_status; } -int cvm_oct_rgmii_open(struct net_device *dev) +static int cvm_oct_rgmii_open(struct net_device *dev) { union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); @@ -285,7 +286,7 @@ int cvm_oct_rgmii_open(struct net_device *dev) return 0; } -int cvm_oct_rgmii_stop(struct net_device *dev) +static int cvm_oct_rgmii_stop(struct net_device *dev) { union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); @@ -304,7 +305,9 @@ int cvm_oct_rgmii_init(struct net_device *dev) int r; cvm_oct_common_init(dev); - dev->netdev_ops->ndo_stop(dev); + dev->open = cvm_oct_rgmii_open; + dev->stop = cvm_oct_rgmii_stop; + dev->stop(dev); /* * Due to GMX errata in CN3XXX series chips, it is necessary diff --git a/trunk/drivers/staging/octeon/ethernet-sgmii.c b/trunk/drivers/staging/octeon/ethernet-sgmii.c index 2b54996bd85d..58fa39c1d675 100644 --- a/trunk/drivers/staging/octeon/ethernet-sgmii.c +++ b/trunk/drivers/staging/octeon/ethernet-sgmii.c @@ -34,12 +34,13 @@ #include "ethernet-defines.h" #include "octeon-ethernet.h" #include "ethernet-util.h" +#include "ethernet-common.h" #include "cvmx-helper.h" #include "cvmx-gmxx-defs.h" -int cvm_oct_sgmii_open(struct net_device *dev) +static int cvm_oct_sgmii_open(struct net_device *dev) { union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); @@ -60,7 +61,7 @@ int cvm_oct_sgmii_open(struct net_device *dev) return 0; } -int cvm_oct_sgmii_stop(struct net_device *dev) +static int cvm_oct_sgmii_stop(struct net_device *dev) { union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); @@ -112,7 +113,9 @@ int cvm_oct_sgmii_init(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); cvm_oct_common_init(dev); - dev->netdev_ops->ndo_stop(dev); + dev->open = cvm_oct_sgmii_open; + dev->stop = cvm_oct_sgmii_stop; + dev->stop(dev); if (!octeon_is_simulation()) priv->poll = cvm_oct_sgmii_poll; diff --git a/trunk/drivers/staging/octeon/ethernet-spi.c b/trunk/drivers/staging/octeon/ethernet-spi.c index 66190b0cb68f..e0971bbe4ddc 100644 --- a/trunk/drivers/staging/octeon/ethernet-spi.c +++ b/trunk/drivers/staging/octeon/ethernet-spi.c @@ -33,6 +33,7 @@ #include "ethernet-defines.h" #include "octeon-ethernet.h" +#include "ethernet-common.h" #include "ethernet-util.h" #include "cvmx-spi.h" diff --git a/trunk/drivers/staging/octeon/ethernet-tx.c b/trunk/drivers/staging/octeon/ethernet-tx.c index 81a851390f1b..77b7122c8fdb 100644 --- a/trunk/drivers/staging/octeon/ethernet-tx.c +++ b/trunk/drivers/staging/octeon/ethernet-tx.c @@ -47,7 +47,6 @@ #include "ethernet-defines.h" #include "octeon-ethernet.h" -#include "ethernet-tx.h" #include "ethernet-util.h" #include "cvmx-wqe.h" @@ -83,10 +82,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) uint64_t old_scratch2; int dropped; int qos; - int queue_it_up; struct octeon_ethernet *priv = netdev_priv(dev); - int32_t skb_to_free; - int32_t undo; + int32_t in_use; int32_t buffers_to_free; #if REUSE_SKBUFFS_WITHOUT_FREE unsigned char *fpa_head; @@ -123,15 +120,15 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8); /* - * Fetch and increment the number of packets to be - * freed. + * Assume we're going to be able t osend this + * packet. Fetch and increment the number of pending + * packets for output. */ cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8, FAU_NUM_PACKET_BUFFERS_TO_FREE, 0); cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH, - priv->fau + qos * 4, - MAX_SKB_TO_FREE); + priv->fau + qos * 4, 1); } /* @@ -256,10 +253,10 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) /* * The skbuff will be reused without ever being freed. We must - * cleanup a bunch of core things. + * cleanup a bunch of Linux stuff. */ - dst_release(skb_dst(skb)); - skb_dst_set(skb, NULL); + dst_release(skb->dst); + skb->dst = NULL; #ifdef CONFIG_XFRM secpath_put(skb->sp); skb->sp = NULL; @@ -289,29 +286,15 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) if (USE_ASYNC_IOBDMA) { /* Get the number of skbuffs in use by the hardware */ CVMX_SYNCIOBDMA; - skb_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH); + in_use = cvmx_scratch_read64(CVMX_SCR_SCRATCH); buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8); } else { /* Get the number of skbuffs in use by the hardware */ - skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4, - MAX_SKB_TO_FREE); + in_use = cvmx_fau_fetch_and_add32(priv->fau + qos * 4, 1); buffers_to_free = cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0); } - /* - * We try to claim MAX_SKB_TO_FREE buffers. If there were not - * that many available, we have to un-claim (undo) any that - * were in excess. If skb_to_free is positive we will free - * that many buffers. - */ - undo = skb_to_free > 0 ? - MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE; - if (undo > 0) - cvmx_fau_atomic_add32(priv->fau+qos*4, -undo); - skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ? - MAX_SKB_TO_FREE : -skb_to_free; - /* * If we're sending faster than the receive can free them then * don't do the HW free. @@ -347,31 +330,38 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2); } - queue_it_up = 0; if (unlikely(dropped)) { dev_kfree_skb_any(skb); + cvmx_fau_atomic_add32(priv->fau + qos * 4, -1); priv->stats.tx_dropped++; } else { if (USE_SKBUFFS_IN_HW) { /* Put this packet on the queue to be freed later */ if (pko_command.s.dontfree) - queue_it_up = 1; - else + skb_queue_tail(&priv->tx_free_list[qos], skb); + else { cvmx_fau_atomic_add32 (FAU_NUM_PACKET_BUFFERS_TO_FREE, -1); + cvmx_fau_atomic_add32(priv->fau + qos * 4, -1); + } } else { /* Put this packet on the queue to be freed later */ - queue_it_up = 1; + skb_queue_tail(&priv->tx_free_list[qos], skb); } } - if (queue_it_up) { + /* Free skbuffs not in use by the hardware, possibly two at a time */ + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) { spin_lock(&priv->tx_free_list[qos].lock); - __skb_queue_tail(&priv->tx_free_list[qos], skb); - cvm_oct_free_tx_skbs(priv, skb_to_free, qos, 0); + /* + * Check again now that we have the lock. It might + * have changed. + */ + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) + dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos])); + if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) + dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos])); spin_unlock(&priv->tx_free_list[qos].lock); - } else { - cvm_oct_free_tx_skbs(priv, skb_to_free, qos, 1); } return 0; diff --git a/trunk/drivers/staging/octeon/ethernet-tx.h b/trunk/drivers/staging/octeon/ethernet-tx.h index c0bebf750bc0..5106236fe981 100644 --- a/trunk/drivers/staging/octeon/ethernet-tx.h +++ b/trunk/drivers/staging/octeon/ethernet-tx.h @@ -30,28 +30,3 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev); int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry, int do_free, int qos); void cvm_oct_tx_shutdown(struct net_device *dev); - -/** - * Free dead transmit skbs. - * - * @priv: The driver data - * @skb_to_free: The number of SKBs to free (free none if negative). - * @qos: The queue to free from. - * @take_lock: If true, acquire the skb list lock. - */ -static inline void cvm_oct_free_tx_skbs(struct octeon_ethernet *priv, - int skb_to_free, - int qos, int take_lock) -{ - /* Free skbuffs not in use by the hardware. */ - if (skb_to_free > 0) { - if (take_lock) - spin_lock(&priv->tx_free_list[qos].lock); - while (skb_to_free > 0) { - dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos])); - skb_to_free--; - } - if (take_lock) - spin_unlock(&priv->tx_free_list[qos].lock); - } -} diff --git a/trunk/drivers/staging/octeon/ethernet-xaui.c b/trunk/drivers/staging/octeon/ethernet-xaui.c index 0c2e7cc40f35..f08eb32e04fc 100644 --- a/trunk/drivers/staging/octeon/ethernet-xaui.c +++ b/trunk/drivers/staging/octeon/ethernet-xaui.c @@ -33,13 +33,14 @@ #include "ethernet-defines.h" #include "octeon-ethernet.h" +#include "ethernet-common.h" #include "ethernet-util.h" #include "cvmx-helper.h" #include "cvmx-gmxx-defs.h" -int cvm_oct_xaui_open(struct net_device *dev) +static int cvm_oct_xaui_open(struct net_device *dev) { union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); @@ -59,7 +60,7 @@ int cvm_oct_xaui_open(struct net_device *dev) return 0; } -int cvm_oct_xaui_stop(struct net_device *dev) +static int cvm_oct_xaui_stop(struct net_device *dev) { union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); @@ -111,7 +112,9 @@ int cvm_oct_xaui_init(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); cvm_oct_common_init(dev); - dev->netdev_ops->ndo_stop(dev); + dev->open = cvm_oct_xaui_open; + dev->stop = cvm_oct_xaui_stop; + dev->stop(dev); if (!octeon_is_simulation()) priv->poll = cvm_oct_xaui_poll; diff --git a/trunk/drivers/staging/octeon/ethernet.c b/trunk/drivers/staging/octeon/ethernet.c index b8479517dce2..e8ef9e0b791f 100644 --- a/trunk/drivers/staging/octeon/ethernet.c +++ b/trunk/drivers/staging/octeon/ethernet.c @@ -37,14 +37,13 @@ #include #include "ethernet-defines.h" -#include "octeon-ethernet.h" #include "ethernet-mem.h" #include "ethernet-rx.h" #include "ethernet-tx.h" -#include "ethernet-mdio.h" #include "ethernet-util.h" #include "ethernet-proc.h" - +#include "ethernet-common.h" +#include "octeon-ethernet.h" #include "cvmx-pip.h" #include "cvmx-pko.h" @@ -52,7 +51,6 @@ #include "cvmx-ipd.h" #include "cvmx-helper.h" -#include "cvmx-gmxx-defs.h" #include "cvmx-smix-defs.h" #if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \ @@ -131,55 +129,53 @@ extern struct semaphore mdio_sem; */ static void cvm_do_timer(unsigned long arg) { - int32_t skb_to_free, undo; - int queues_per_port; - int qos; - struct octeon_ethernet *priv; static int port; + if (port < CVMX_PIP_NUM_INPUT_PORTS) { + if (cvm_oct_device[port]) { + int queues_per_port; + int qos; + struct octeon_ethernet *priv = + netdev_priv(cvm_oct_device[port]); + if (priv->poll) { + /* skip polling if we don't get the lock */ + if (!down_trylock(&mdio_sem)) { + priv->poll(cvm_oct_device[port]); + up(&mdio_sem); + } + } - if (port >= CVMX_PIP_NUM_INPUT_PORTS) { - /* - * All ports have been polled. Start the next - * iteration through the ports in one second. - */ + queues_per_port = cvmx_pko_get_num_queues(port); + /* Drain any pending packets in the free list */ + for (qos = 0; qos < queues_per_port; qos++) { + if (skb_queue_len(&priv->tx_free_list[qos])) { + spin_lock(&priv->tx_free_list[qos]. + lock); + while (skb_queue_len + (&priv->tx_free_list[qos]) > + cvmx_fau_fetch_and_add32(priv-> + fau + + qos * 4, + 0)) + dev_kfree_skb(__skb_dequeue + (&priv-> + tx_free_list + [qos])); + spin_unlock(&priv->tx_free_list[qos]. + lock); + } + } + cvm_oct_device[port]->get_stats(cvm_oct_device[port]); + } + port++; + /* Poll the next port in a 50th of a second. + This spreads the polling of ports out a little bit */ + mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50); + } else { port = 0; + /* All ports have been polled. Start the next iteration through + the ports in one second */ mod_timer(&cvm_oct_poll_timer, jiffies + HZ); - return; - } - if (!cvm_oct_device[port]) - goto out; - - priv = netdev_priv(cvm_oct_device[port]); - if (priv->poll) { - /* skip polling if we don't get the lock */ - if (!down_trylock(&mdio_sem)) { - priv->poll(cvm_oct_device[port]); - up(&mdio_sem); - } } - - queues_per_port = cvmx_pko_get_num_queues(port); - /* Drain any pending packets in the free list */ - for (qos = 0; qos < queues_per_port; qos++) { - if (skb_queue_len(&priv->tx_free_list[qos]) == 0) - continue; - skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4, - MAX_SKB_TO_FREE); - undo = skb_to_free > 0 ? - MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE; - if (undo > 0) - cvmx_fau_atomic_add32(priv->fau+qos*4, -undo); - skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ? - MAX_SKB_TO_FREE : -skb_to_free; - cvm_oct_free_tx_skbs(priv, skb_to_free, qos, 1); - } - cvm_oct_device[port]->netdev_ops->ndo_get_stats(cvm_oct_device[port]); - -out: - port++; - /* Poll the next port in a 50th of a second. - This spreads the polling of ports out a little bit */ - mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50); } /** @@ -249,362 +245,6 @@ int cvm_oct_free_work(void *work_queue_entry) } EXPORT_SYMBOL(cvm_oct_free_work); -/** - * Get the low level ethernet statistics - * - * @dev: Device to get the statistics from - * Returns Pointer to the statistics - */ -static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev) -{ - cvmx_pip_port_status_t rx_status; - cvmx_pko_port_status_t tx_status; - struct octeon_ethernet *priv = netdev_priv(dev); - - if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) { - if (octeon_is_simulation()) { - /* The simulator doesn't support statistics */ - memset(&rx_status, 0, sizeof(rx_status)); - memset(&tx_status, 0, sizeof(tx_status)); - } else { - cvmx_pip_get_port_status(priv->port, 1, &rx_status); - cvmx_pko_get_port_status(priv->port, 1, &tx_status); - } - - priv->stats.rx_packets += rx_status.inb_packets; - priv->stats.tx_packets += tx_status.packets; - priv->stats.rx_bytes += rx_status.inb_octets; - priv->stats.tx_bytes += tx_status.octets; - priv->stats.multicast += rx_status.multicast_packets; - priv->stats.rx_crc_errors += rx_status.inb_errors; - priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets; - - /* - * The drop counter must be incremented atomically - * since the RX tasklet also increments it. - */ -#ifdef CONFIG_64BIT - atomic64_add(rx_status.dropped_packets, - (atomic64_t *)&priv->stats.rx_dropped); -#else - atomic_add(rx_status.dropped_packets, - (atomic_t *)&priv->stats.rx_dropped); -#endif - } - - return &priv->stats; -} - -/** - * Change the link MTU. Unimplemented - * - * @dev: Device to change - * @new_mtu: The new MTU - * - * Returns Zero on success - */ -static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - int vlan_bytes = 4; -#else - int vlan_bytes = 0; -#endif - - /* - * Limit the MTU to make sure the ethernet packets are between - * 64 bytes and 65535 bytes. - */ - if ((new_mtu + 14 + 4 + vlan_bytes < 64) - || (new_mtu + 14 + 4 + vlan_bytes > 65392)) { - pr_err("MTU must be between %d and %d.\n", - 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes); - return -EINVAL; - } - dev->mtu = new_mtu; - - if ((interface < 2) - && (cvmx_helper_interface_get_mode(interface) != - CVMX_HELPER_INTERFACE_MODE_SPI)) { - /* Add ethernet header and FCS, and VLAN if configured. */ - int max_packet = new_mtu + 14 + 4 + vlan_bytes; - - if (OCTEON_IS_MODEL(OCTEON_CN3XXX) - || OCTEON_IS_MODEL(OCTEON_CN58XX)) { - /* Signal errors on packets larger than the MTU */ - cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface), - max_packet); - } else { - /* - * Set the hardware to truncate packets larger - * than the MTU and smaller the 64 bytes. - */ - union cvmx_pip_frm_len_chkx frm_len_chk; - frm_len_chk.u64 = 0; - frm_len_chk.s.minlen = 64; - frm_len_chk.s.maxlen = max_packet; - cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface), - frm_len_chk.u64); - } - /* - * Set the hardware to truncate packets larger than - * the MTU. The jabber register must be set to a - * multiple of 8 bytes, so round up. - */ - cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface), - (max_packet + 7) & ~7u); - } - return 0; -} - -/** - * Set the multicast list. Currently unimplemented. - * - * @dev: Device to work on - */ -static void cvm_oct_common_set_multicast_list(struct net_device *dev) -{ - union cvmx_gmxx_prtx_cfg gmx_cfg; - struct octeon_ethernet *priv = netdev_priv(dev); - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - - if ((interface < 2) - && (cvmx_helper_interface_get_mode(interface) != - CVMX_HELPER_INTERFACE_MODE_SPI)) { - union cvmx_gmxx_rxx_adr_ctl control; - control.u64 = 0; - control.s.bcst = 1; /* Allow broadcast MAC addresses */ - - if (dev->mc_list || (dev->flags & IFF_ALLMULTI) || - (dev->flags & IFF_PROMISC)) - /* Force accept multicast packets */ - control.s.mcst = 2; - else - /* Force reject multicat packets */ - control.s.mcst = 1; - - if (dev->flags & IFF_PROMISC) - /* - * Reject matches if promisc. Since CAM is - * shut off, should accept everything. - */ - control.s.cam_mode = 0; - else - /* Filter packets based on the CAM */ - control.s.cam_mode = 1; - - gmx_cfg.u64 = - cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), - gmx_cfg.u64 & ~1ull); - - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface), - control.u64); - if (dev->flags & IFF_PROMISC) - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN - (index, interface), 0); - else - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN - (index, interface), 1); - - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), - gmx_cfg.u64); - } -} - -/** - * Set the hardware MAC address for a device - * - * @dev: Device to change the MAC address for - * @addr: Address structure to change it too. MAC address is addr + 2. - * Returns Zero on success - */ -static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) -{ - struct octeon_ethernet *priv = netdev_priv(dev); - union cvmx_gmxx_prtx_cfg gmx_cfg; - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - - memcpy(dev->dev_addr, addr + 2, 6); - - if ((interface < 2) - && (cvmx_helper_interface_get_mode(interface) != - CVMX_HELPER_INTERFACE_MODE_SPI)) { - int i; - uint8_t *ptr = addr; - uint64_t mac = 0; - for (i = 0; i < 6; i++) - mac = (mac << 8) | (uint64_t) (ptr[i + 2]); - - gmx_cfg.u64 = - cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), - gmx_cfg.u64 & ~1ull); - - cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac); - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), - ptr[2]); - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), - ptr[3]); - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), - ptr[4]); - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), - ptr[5]); - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), - ptr[6]); - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), - ptr[7]); - cvm_oct_common_set_multicast_list(dev); - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), - gmx_cfg.u64); - } - return 0; -} - -/** - * Per network device initialization - * - * @dev: Device to initialize - * Returns Zero on success - */ -int cvm_oct_common_init(struct net_device *dev) -{ - static int count; - char mac[8] = { 0x00, 0x00, - octeon_bootinfo->mac_addr_base[0], - octeon_bootinfo->mac_addr_base[1], - octeon_bootinfo->mac_addr_base[2], - octeon_bootinfo->mac_addr_base[3], - octeon_bootinfo->mac_addr_base[4], - octeon_bootinfo->mac_addr_base[5] + count - }; - struct octeon_ethernet *priv = netdev_priv(dev); - - /* - * Force the interface to use the POW send if always_use_pow - * was specified or it is in the pow send list. - */ - if ((pow_send_group != -1) - && (always_use_pow || strstr(pow_send_list, dev->name))) - priv->queue = -1; - - if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM) - dev->features |= NETIF_F_IP_CSUM; - - count++; - - /* We do our own locking, Linux doesn't need to */ - dev->features |= NETIF_F_LLTX; - SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); - - cvm_oct_mdio_setup_device(dev); - dev->netdev_ops->ndo_set_mac_address(dev, mac); - dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); - - /* - * Zero out stats for port so we won't mistakenly show - * counters from the bootloader. - */ - memset(dev->netdev_ops->ndo_get_stats(dev), 0, - sizeof(struct net_device_stats)); - - return 0; -} - -void cvm_oct_common_uninit(struct net_device *dev) -{ - /* Currently nothing to do */ -} - -static const struct net_device_ops cvm_oct_npi_netdev_ops = { - .ndo_init = cvm_oct_common_init, - .ndo_uninit = cvm_oct_common_uninit, - .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, - .ndo_set_mac_address = cvm_oct_common_set_mac_address, - .ndo_do_ioctl = cvm_oct_ioctl, - .ndo_change_mtu = cvm_oct_common_change_mtu, - .ndo_get_stats = cvm_oct_common_get_stats, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = cvm_oct_poll_controller, -#endif -}; -static const struct net_device_ops cvm_oct_xaui_netdev_ops = { - .ndo_init = cvm_oct_xaui_init, - .ndo_uninit = cvm_oct_xaui_uninit, - .ndo_open = cvm_oct_xaui_open, - .ndo_stop = cvm_oct_xaui_stop, - .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, - .ndo_set_mac_address = cvm_oct_common_set_mac_address, - .ndo_do_ioctl = cvm_oct_ioctl, - .ndo_change_mtu = cvm_oct_common_change_mtu, - .ndo_get_stats = cvm_oct_common_get_stats, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = cvm_oct_poll_controller, -#endif -}; -static const struct net_device_ops cvm_oct_sgmii_netdev_ops = { - .ndo_init = cvm_oct_sgmii_init, - .ndo_uninit = cvm_oct_sgmii_uninit, - .ndo_open = cvm_oct_sgmii_open, - .ndo_stop = cvm_oct_sgmii_stop, - .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, - .ndo_set_mac_address = cvm_oct_common_set_mac_address, - .ndo_do_ioctl = cvm_oct_ioctl, - .ndo_change_mtu = cvm_oct_common_change_mtu, - .ndo_get_stats = cvm_oct_common_get_stats, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = cvm_oct_poll_controller, -#endif -}; -static const struct net_device_ops cvm_oct_spi_netdev_ops = { - .ndo_init = cvm_oct_spi_init, - .ndo_uninit = cvm_oct_spi_uninit, - .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, - .ndo_set_mac_address = cvm_oct_common_set_mac_address, - .ndo_do_ioctl = cvm_oct_ioctl, - .ndo_change_mtu = cvm_oct_common_change_mtu, - .ndo_get_stats = cvm_oct_common_get_stats, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = cvm_oct_poll_controller, -#endif -}; -static const struct net_device_ops cvm_oct_rgmii_netdev_ops = { - .ndo_init = cvm_oct_rgmii_init, - .ndo_uninit = cvm_oct_rgmii_uninit, - .ndo_open = cvm_oct_rgmii_open, - .ndo_stop = cvm_oct_rgmii_stop, - .ndo_start_xmit = cvm_oct_xmit, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, - .ndo_set_mac_address = cvm_oct_common_set_mac_address, - .ndo_do_ioctl = cvm_oct_ioctl, - .ndo_change_mtu = cvm_oct_common_change_mtu, - .ndo_get_stats = cvm_oct_common_get_stats, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = cvm_oct_poll_controller, -#endif -}; -static const struct net_device_ops cvm_oct_pow_netdev_ops = { - .ndo_init = cvm_oct_common_init, - .ndo_start_xmit = cvm_oct_xmit_pow, - .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, - .ndo_set_mac_address = cvm_oct_common_set_mac_address, - .ndo_do_ioctl = cvm_oct_ioctl, - .ndo_change_mtu = cvm_oct_common_change_mtu, - .ndo_get_stats = cvm_oct_common_get_stats, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = cvm_oct_poll_controller, -#endif -}; - /** * Module/ driver initialization. Creates the linux network * devices. @@ -663,7 +303,7 @@ static int __init cvm_oct_init_module(void) struct octeon_ethernet *priv = netdev_priv(dev); memset(priv, 0, sizeof(struct octeon_ethernet)); - dev->netdev_ops = &cvm_oct_pow_netdev_ops; + dev->init = cvm_oct_common_init; priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED; priv->port = CVMX_PIP_NUM_INPUT_PORTS; priv->queue = -1; @@ -732,38 +372,44 @@ static int __init cvm_oct_init_module(void) break; case CVMX_HELPER_INTERFACE_MODE_NPI: - dev->netdev_ops = &cvm_oct_npi_netdev_ops; + dev->init = cvm_oct_common_init; + dev->uninit = cvm_oct_common_uninit; strcpy(dev->name, "npi%d"); break; case CVMX_HELPER_INTERFACE_MODE_XAUI: - dev->netdev_ops = &cvm_oct_xaui_netdev_ops; + dev->init = cvm_oct_xaui_init; + dev->uninit = cvm_oct_xaui_uninit; strcpy(dev->name, "xaui%d"); break; case CVMX_HELPER_INTERFACE_MODE_LOOP: - dev->netdev_ops = &cvm_oct_npi_netdev_ops; + dev->init = cvm_oct_common_init; + dev->uninit = cvm_oct_common_uninit; strcpy(dev->name, "loop%d"); break; case CVMX_HELPER_INTERFACE_MODE_SGMII: - dev->netdev_ops = &cvm_oct_sgmii_netdev_ops; + dev->init = cvm_oct_sgmii_init; + dev->uninit = cvm_oct_sgmii_uninit; strcpy(dev->name, "eth%d"); break; case CVMX_HELPER_INTERFACE_MODE_SPI: - dev->netdev_ops = &cvm_oct_spi_netdev_ops; + dev->init = cvm_oct_spi_init; + dev->uninit = cvm_oct_spi_uninit; strcpy(dev->name, "spi%d"); break; case CVMX_HELPER_INTERFACE_MODE_RGMII: case CVMX_HELPER_INTERFACE_MODE_GMII: - dev->netdev_ops = &cvm_oct_rgmii_netdev_ops; + dev->init = cvm_oct_rgmii_init; + dev->uninit = cvm_oct_rgmii_uninit; strcpy(dev->name, "eth%d"); break; } - if (!dev->netdev_ops) { + if (!dev->init) { kfree(dev); } else if (register_netdev(dev) < 0) { pr_err("Failed to register ethernet device " diff --git a/trunk/drivers/staging/octeon/octeon-ethernet.h b/trunk/drivers/staging/octeon/octeon-ethernet.h index 3aef9878fc0a..b3199076ef5e 100644 --- a/trunk/drivers/staging/octeon/octeon-ethernet.h +++ b/trunk/drivers/staging/octeon/octeon-ethernet.h @@ -111,23 +111,12 @@ static inline int cvm_oct_transmit(struct net_device *dev, extern int cvm_oct_rgmii_init(struct net_device *dev); extern void cvm_oct_rgmii_uninit(struct net_device *dev); -extern int cvm_oct_rgmii_open(struct net_device *dev); -extern int cvm_oct_rgmii_stop(struct net_device *dev); - extern int cvm_oct_sgmii_init(struct net_device *dev); extern void cvm_oct_sgmii_uninit(struct net_device *dev); -extern int cvm_oct_sgmii_open(struct net_device *dev); -extern int cvm_oct_sgmii_stop(struct net_device *dev); - extern int cvm_oct_spi_init(struct net_device *dev); extern void cvm_oct_spi_uninit(struct net_device *dev); extern int cvm_oct_xaui_init(struct net_device *dev); extern void cvm_oct_xaui_uninit(struct net_device *dev); -extern int cvm_oct_xaui_open(struct net_device *dev); -extern int cvm_oct_xaui_stop(struct net_device *dev); - -extern int cvm_oct_common_init(struct net_device *dev); -extern void cvm_oct_common_uninit(struct net_device *dev); extern int always_use_pow; extern int pow_send_group; diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 3f1045993474..38bfdb0f6660 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -550,7 +550,7 @@ static void acm_waker(struct work_struct *waker) static int acm_tty_open(struct tty_struct *tty, struct file *filp) { struct acm *acm; - int rv = -ENODEV; + int rv = -EINVAL; int i; dbg("Entering acm_tty_open."); @@ -677,7 +677,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) /* Perform the closing process and see if we need to do the hardware shutdown */ - if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0) + if (tty_port_close_start(&acm->port, tty, filp) == 0) return; acm_port_down(acm, 0); tty_port_close_end(&acm->port, tty); diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index a84216464ca0..d595aa5586a7 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -333,9 +333,6 @@ static void serial_close(struct tty_struct *tty, struct file *filp) { struct usb_serial_port *port = tty->driver_data; - if (!port) - return; - dbg("%s - port %d", __func__, port->number); diff --git a/trunk/drivers/uwb/hwa-rc.c b/trunk/drivers/uwb/hwa-rc.c index 9052bcb4f528..559f8784acf3 100644 --- a/trunk/drivers/uwb/hwa-rc.c +++ b/trunk/drivers/uwb/hwa-rc.c @@ -501,7 +501,7 @@ int hwarc_filter_event_WUSB_0100(struct uwb_rc *rc, struct uwb_rceb **header, int result = -ENOANO; struct uwb_rceb *rceb = *header; int event = le16_to_cpu(rceb->wEvent); - ssize_t event_size; + size_t event_size; size_t core_size, offset; if (rceb->bEventType != UWB_RC_CET_GENERAL) diff --git a/trunk/drivers/uwb/wlp/txrx.c b/trunk/drivers/uwb/wlp/txrx.c index 86a853b84119..cd2035768b47 100644 --- a/trunk/drivers/uwb/wlp/txrx.c +++ b/trunk/drivers/uwb/wlp/txrx.c @@ -326,7 +326,7 @@ int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp, int result = -EINVAL; struct ethhdr *eth_hdr = (void *) skb->data; - if (is_multicast_ether_addr(eth_hdr->h_dest)) { + if (is_broadcast_ether_addr(eth_hdr->h_dest)) { result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb); if (result < 0) { if (printk_ratelimit()) diff --git a/trunk/drivers/video/atafb.c b/trunk/drivers/video/atafb.c index 497ff8af03ed..018850c116c6 100644 --- a/trunk/drivers/video/atafb.c +++ b/trunk/drivers/video/atafb.c @@ -2414,10 +2414,7 @@ static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) if (err) return err; memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - mutex_lock(&info->mm_lock); - err = fbhw->encode_fix(fix, &par); - mutex_unlock(&info->mm_lock); - return err; + return fbhw->encode_fix(fix, &par); } static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info) @@ -2746,9 +2743,7 @@ static int atafb_set_par(struct fb_info *info) /* Decode wanted screen parameters */ fbhw->decode_var(&info->var, par); - mutex_lock(&info->mm_lock); fbhw->encode_fix(&info->fix, par); - mutex_unlock(&info->mm_lock); /* Set new videomode */ ata_set_par(par); diff --git a/trunk/drivers/video/atmel_lcdfb.c b/trunk/drivers/video/atmel_lcdfb.c index cb88394ba995..5afd64482f55 100644 --- a/trunk/drivers/video/atmel_lcdfb.c +++ b/trunk/drivers/video/atmel_lcdfb.c @@ -270,9 +270,7 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo) smem_len = (var->xres_virtual * var->yres_virtual * ((var->bits_per_pixel + 7) / 8)); - mutex_lock(&info->mm_lock); info->fix.smem_len = max(smem_len, sinfo->smem_len); - mutex_unlock(&info->mm_lock); info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len, (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL); diff --git a/trunk/drivers/video/aty/atyfb.h b/trunk/drivers/video/aty/atyfb.h index 1f39a62f899b..7691e73823d3 100644 --- a/trunk/drivers/video/aty/atyfb.h +++ b/trunk/drivers/video/aty/atyfb.h @@ -187,8 +187,6 @@ struct atyfb_par { int mtrr_reg; #endif u32 mem_cntl; - struct crtc saved_crtc; - union aty_pll saved_pll; }; /* @@ -219,7 +217,6 @@ struct atyfb_par { #define M64F_XL_DLL 0x00080000 #define M64F_MFB_FORCE_4 0x00100000 #define M64F_HW_TRIPLE 0x00200000 -#define M64F_XL_MEM 0x00400000 /* * Register access */ diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 63d3739d43a8..1207c208a30b 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -66,8 +66,6 @@ #include #include #include -#include -#include #include #include @@ -251,6 +249,8 @@ static int aty_init(struct fb_info *info); static int store_video_par(char *videopar, unsigned char m64_num); #endif +static struct crtc saved_crtc; +static union aty_pll saved_pll; static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); @@ -261,8 +261,6 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info); static int read_aty_sense(const struct atyfb_par *par); #endif -static DEFINE_MUTEX(reboot_lock); -static struct fb_info *reboot_info; /* * Interface used by the world @@ -363,8 +361,8 @@ static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, }; #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) -#define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM) -#define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS) +#define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4) +#define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_MOBIL_BUS) static struct { u16 pci_id; @@ -541,7 +539,6 @@ static char ram_edo[] __devinitdata = "EDO"; static char ram_sdram[] __devinitdata = "SDRAM (1:1)"; static char ram_sgram[] __devinitdata = "SGRAM (1:1)"; static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)"; -static char ram_wram[] __devinitdata = "WRAM"; static char ram_off[] __devinitdata = "OFF"; #endif /* CONFIG_FB_ATY_CT */ @@ -555,10 +552,6 @@ static char *aty_gx_ram[8] __devinitdata = { #ifdef CONFIG_FB_ATY_CT static char *aty_ct_ram[8] __devinitdata = { - ram_off, ram_dram, ram_edo, ram_edo, - ram_sdram, ram_sgram, ram_wram, ram_resv -}; -static char *aty_xl_ram[8] __devinitdata = { ram_off, ram_dram, ram_edo, ram_edo, ram_sdram, ram_sgram, ram_sdram32, ram_resv }; @@ -767,17 +760,6 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) #endif /* CONFIG_FB_ATY_GENERIC_LCD */ } -static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp) -{ - u32 line_length = vxres * bpp / 8; - - if (par->ram_type == SGRAM || - (!M64_HAS(XL_MEM) && par->ram_type == WRAM)) - line_length = (line_length + 63) & ~63; - - return line_length; -} - static int aty_var_to_crtc(const struct fb_info *info, const struct fb_var_screeninfo *var, struct crtc *crtc) { @@ -787,14 +769,13 @@ static int aty_var_to_crtc(const struct fb_info *info, u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; u32 pix_width, dp_pix_width, dp_chain_mask; - u32 line_length; /* input */ - xres = (var->xres + 7) & ~7; + xres = var->xres; yres = var->yres; - vxres = (var->xres_virtual + 7) & ~7; + vxres = var->xres_virtual; vyres = var->yres_virtual; - xoffset = (var->xoffset + 7) & ~7; + xoffset = var->xoffset; yoffset = var->yoffset; bpp = var->bits_per_pixel; if (bpp == 16) @@ -846,9 +827,7 @@ static int aty_var_to_crtc(const struct fb_info *info, } else FAIL("invalid bpp"); - line_length = calc_line_length(par, vxres, bpp); - - if (vyres * line_length > info->fix.smem_len) + if (vxres * vyres * bpp / 8 > info->fix.smem_len) FAIL("not enough video RAM"); h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; @@ -990,9 +969,7 @@ static int aty_var_to_crtc(const struct fb_info *info, crtc->xoffset = xoffset; crtc->yoffset = yoffset; crtc->bpp = bpp; - crtc->off_pitch = - ((yoffset * line_length + xoffset * bpp / 8) / 8) | - ((line_length / bpp) << 22); + crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19); crtc->vline_crnt_vline = 0; crtc->h_tot_disp = h_total | (h_disp<<16); @@ -1417,9 +1394,7 @@ static int atyfb_set_par(struct fb_info *info) } aty_st_8(DAC_MASK, 0xff, par); - info->fix.line_length = calc_line_length(par, var->xres_virtual, - var->bits_per_pixel); - + info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8; info->fix.visual = var->bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; @@ -1530,12 +1505,10 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info) { u32 xoffset = info->var.xoffset; u32 yoffset = info->var.yoffset; - u32 line_length = info->fix.line_length; + u32 vxres = par->crtc.vxres; u32 bpp = info->var.bits_per_pixel; - par->crtc.off_pitch = - ((yoffset * line_length + xoffset * bpp / 8) / 8) | - ((line_length / bpp) << 22); + par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19); } @@ -2228,7 +2201,7 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) const int *refresh_tbl; int i, size; - if (M64_HAS(XL_MEM)) { + if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { refresh_tbl = ragexl_tbl; size = ARRAY_SIZE(ragexl_tbl); } else { @@ -2362,10 +2335,7 @@ static int __devinit aty_init(struct fb_info *info) par->pll_ops = &aty_pll_ct; par->bus_type = PCI; par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); - if (M64_HAS(XL_MEM)) - ramname = aty_xl_ram[par->ram_type]; - else - ramname = aty_ct_ram[par->ram_type]; + ramname = aty_ct_ram[par->ram_type]; /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) par->pll_limits.mclk = 63; @@ -2420,9 +2390,9 @@ static int __devinit aty_init(struct fb_info *info) #endif /* CONFIG_FB_ATY_CT */ /* save previous video mode */ - aty_get_crtc(par, &par->saved_crtc); + aty_get_crtc(par, &saved_crtc); if(par->pll_ops->get_pll) - par->pll_ops->get_pll(info, &par->saved_pll); + par->pll_ops->get_pll(info, &saved_pll); par->mem_cntl = aty_ld_le32(MEM_CNTL, par); gtb_memsize = M64_HAS(GTB_DSP); @@ -2697,8 +2667,8 @@ static int __devinit aty_init(struct fb_info *info) aty_init_exit: /* restore video mode */ - aty_set_crtc(par, &par->saved_crtc); - par->pll_ops->set_pll(info, &par->saved_pll); + aty_set_crtc(par, &saved_crtc); + par->pll_ops->set_pll(info, &saved_pll); #ifdef CONFIG_MTRR if (par->mtrr_reg >= 0) { @@ -3532,11 +3502,6 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi par->mmap_map[1].prot_flag = _PAGE_E; #endif /* __sparc__ */ - mutex_lock(&reboot_lock); - if (!reboot_info) - reboot_info = info; - mutex_unlock(&reboot_lock); - return 0; err_release_io: @@ -3649,8 +3614,8 @@ static void __devexit atyfb_remove(struct fb_info *info) struct atyfb_par *par = (struct atyfb_par *) info->par; /* restore video mode */ - aty_set_crtc(par, &par->saved_crtc); - par->pll_ops->set_pll(info, &par->saved_pll); + aty_set_crtc(par, &saved_crtc); + par->pll_ops->set_pll(info, &saved_pll); unregister_framebuffer(info); @@ -3696,11 +3661,6 @@ static void __devexit atyfb_pci_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); - mutex_lock(&reboot_lock); - if (reboot_info == info) - reboot_info = NULL; - mutex_unlock(&reboot_lock); - atyfb_remove(info); } @@ -3848,56 +3808,6 @@ static int __init atyfb_setup(char *options) } #endif /* MODULE */ -static int atyfb_reboot_notify(struct notifier_block *nb, - unsigned long code, void *unused) -{ - struct atyfb_par *par; - - if (code != SYS_RESTART) - return NOTIFY_DONE; - - mutex_lock(&reboot_lock); - - if (!reboot_info) - goto out; - - if (!lock_fb_info(reboot_info)) - goto out; - - par = reboot_info->par; - - /* - * HP OmniBook 500's BIOS doesn't like the state of the - * hardware after atyfb has been used. Restore the hardware - * to the original state to allow successful reboots. - */ - aty_set_crtc(par, &par->saved_crtc); - par->pll_ops->set_pll(reboot_info, &par->saved_pll); - - unlock_fb_info(reboot_info); - out: - mutex_unlock(&reboot_lock); - - return NOTIFY_DONE; -} - -static struct notifier_block atyfb_reboot_notifier = { - .notifier_call = atyfb_reboot_notify, -}; - -static const struct dmi_system_id atyfb_reboot_ids[] = { - { - .ident = "HP OmniBook 500", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"), - DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"), - }, - }, - - { } -}; - static int __init atyfb_init(void) { int err1 = 1, err2 = 1; @@ -3916,20 +3826,11 @@ static int __init atyfb_init(void) err2 = atyfb_atari_probe(); #endif - if (err1 && err2) - return -ENODEV; - - if (dmi_check_system(atyfb_reboot_ids)) - register_reboot_notifier(&atyfb_reboot_notifier); - - return 0; + return (err1 && err2) ? -ENODEV : 0; } static void __exit atyfb_exit(void) { - if (dmi_check_system(atyfb_reboot_ids)) - unregister_reboot_notifier(&atyfb_reboot_notifier); - #ifdef CONFIG_PCI pci_unregister_driver(&atyfb_driver); #endif diff --git a/trunk/drivers/video/aty/mach64_accel.c b/trunk/drivers/video/aty/mach64_accel.c index 51fcc0a2c94a..0cc9724e61a2 100644 --- a/trunk/drivers/video/aty/mach64_accel.c +++ b/trunk/drivers/video/aty/mach64_accel.c @@ -63,17 +63,14 @@ static void reset_GTC_3D_engine(const struct atyfb_par *par) void aty_init_engine(struct atyfb_par *par, struct fb_info *info) { u32 pitch_value; - u32 vxres; /* determine modal information from global mode structure */ - pitch_value = info->fix.line_length / (info->var.bits_per_pixel / 8); - vxres = info->var.xres_virtual; + pitch_value = info->var.xres_virtual; if (info->var.bits_per_pixel == 24) { /* In 24 bpp, the engine is in 8 bpp - this requires that all */ /* horizontal coordinates and widths must be adjusted */ pitch_value *= 3; - vxres *= 3; } /* On GTC (RagePro), we need to reset the 3D engine before */ @@ -136,7 +133,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info) aty_st_le32(SC_LEFT, 0, par); aty_st_le32(SC_TOP, 0, par); aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par); - aty_st_le32(SC_RIGHT, vxres - 1, par); + aty_st_le32(SC_RIGHT, pitch_value - 1, par); /* set background color to minimum value (usually BLACK) */ aty_st_le32(DP_BKGD_CLR, 0, par); diff --git a/trunk/drivers/video/backlight/tdo24m.c b/trunk/drivers/video/backlight/tdo24m.c index 51422fc4f606..1dae7f8f3c6b 100644 --- a/trunk/drivers/video/backlight/tdo24m.c +++ b/trunk/drivers/video/backlight/tdo24m.c @@ -356,7 +356,7 @@ static int __devinit tdo24m_probe(struct spi_device *spi) lcd->power = FB_BLANK_POWERDOWN; lcd->mode = MODE_VGA; /* default to VGA */ - lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, GFP_KERNEL); + lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL)); if (lcd->buf == NULL) { kfree(lcd); return -ENOMEM; diff --git a/trunk/drivers/video/cobalt_lcdfb.c b/trunk/drivers/video/cobalt_lcdfb.c index 108b89e09a80..7bad24ed04ef 100644 --- a/trunk/drivers/video/cobalt_lcdfb.c +++ b/trunk/drivers/video/cobalt_lcdfb.c @@ -1,7 +1,7 @@ /* * Cobalt server LCD frame buffer driver. * - * Copyright (C) 2008 Yoichi Yuasa + * Copyright (C) 2008 Yoichi Yuasa * * 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 diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index 53ea05645ff8..f8a09bf8d0cd 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -1310,6 +1310,8 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, static int fb_mmap(struct file *file, struct vm_area_struct * vma) +__acquires(&info->lock) +__releases(&info->lock) { int fbidx = iminor(file->f_path.dentry->d_inode); struct fb_info *info = registered_fb[fbidx]; @@ -1323,14 +1325,16 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) off = vma->vm_pgoff << PAGE_SHIFT; if (!fb) return -ENODEV; - mutex_lock(&info->mm_lock); if (fb->fb_mmap) { int res; + mutex_lock(&info->lock); res = fb->fb_mmap(info, vma); - mutex_unlock(&info->mm_lock); + mutex_unlock(&info->lock); return res; } + mutex_lock(&info->lock); + /* frame buffer memory */ start = info->fix.smem_start; len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); @@ -1338,13 +1342,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) /* memory mapped io */ off -= len; if (info->var.accel_flags) { - mutex_unlock(&info->mm_lock); + mutex_unlock(&info->lock); return -EINVAL; } start = info->fix.mmio_start; len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); } - mutex_unlock(&info->mm_lock); + mutex_unlock(&info->lock); start &= PAGE_MASK; if ((vma->vm_end - vma->vm_start + off) > len) return -EINVAL; @@ -1514,7 +1518,6 @@ register_framebuffer(struct fb_info *fb_info) break; fb_info->node = i; mutex_init(&fb_info->lock); - mutex_init(&fb_info->mm_lock); fb_info->dev = device_create(fb_class, fb_info->device, MKDEV(FB_MAJOR, i), NULL, "fb%d", i); diff --git a/trunk/drivers/video/fsl-diu-fb.c b/trunk/drivers/video/fsl-diu-fb.c index 0bf2190928d0..f153c581cbd7 100644 --- a/trunk/drivers/video/fsl-diu-fb.c +++ b/trunk/drivers/video/fsl-diu-fb.c @@ -750,26 +750,24 @@ static void update_lcdc(struct fb_info *info) static int map_video_memory(struct fb_info *info) { phys_addr_t phys; - u32 smem_len = info->fix.line_length * info->var.yres_virtual; pr_debug("info->var.xres_virtual = %d\n", info->var.xres_virtual); pr_debug("info->var.yres_virtual = %d\n", info->var.yres_virtual); pr_debug("info->fix.line_length = %d\n", info->fix.line_length); - pr_debug("MAP_VIDEO_MEMORY: smem_len = %u\n", smem_len); - info->screen_base = fsl_diu_alloc(smem_len, &phys); + info->fix.smem_len = info->fix.line_length * info->var.yres_virtual; + pr_debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->fix.smem_len); + info->screen_base = fsl_diu_alloc(info->fix.smem_len, &phys); if (info->screen_base == NULL) { printk(KERN_ERR "Unable to allocate fb memory\n"); return -ENOMEM; } - mutex_lock(&info->mm_lock); info->fix.smem_start = (unsigned long) phys; - info->fix.smem_len = smem_len; - mutex_unlock(&info->mm_lock); info->screen_size = info->fix.smem_len; pr_debug("Allocated fb @ paddr=0x%08lx, size=%d.\n", - info->fix.smem_start, info->fix.smem_len); + info->fix.smem_start, + info->fix.smem_len); pr_debug("screen base %p\n", info->screen_base); return 0; @@ -778,11 +776,9 @@ static int map_video_memory(struct fb_info *info) static void unmap_video_memory(struct fb_info *info) { fsl_diu_free(info->screen_base, info->fix.smem_len); - mutex_lock(&info->mm_lock); info->screen_base = NULL; info->fix.smem_start = 0; info->fix.smem_len = 0; - mutex_unlock(&info->mm_lock); } /* diff --git a/trunk/drivers/video/i810/i810_main.c b/trunk/drivers/video/i810/i810_main.c index 71960672d721..2e940199fc89 100644 --- a/trunk/drivers/video/i810/i810_main.c +++ b/trunk/drivers/video/i810/i810_main.c @@ -1090,10 +1090,8 @@ static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) memset(fix, 0, sizeof(struct fb_fix_screeninfo)); strcpy(fix->id, "I810"); - mutex_lock(&info->mm_lock); fix->smem_start = par->fb.physical; fix->smem_len = par->fb.size; - mutex_unlock(&info->mm_lock); fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; fix->xpanstep = 8; diff --git a/trunk/drivers/video/matrox/matroxfb_base.c b/trunk/drivers/video/matrox/matroxfb_base.c index 59c3a2e14913..8e7a275df50c 100644 --- a/trunk/drivers/video/matrox/matroxfb_base.c +++ b/trunk/drivers/video/matrox/matroxfb_base.c @@ -724,10 +724,8 @@ static void matroxfb_update_fix(WPMINFO2) struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; DBG(__func__) - mutex_lock(&ACCESS_FBINFO(fbcon).mm_lock); fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes); fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes); - mutex_unlock(&ACCESS_FBINFO(fbcon).mm_lock); } static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) @@ -2083,7 +2081,6 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm spin_lock_init(&ACCESS_FBINFO(lock.accel)); init_rwsem(&ACCESS_FBINFO(crtc2.lock)); init_rwsem(&ACCESS_FBINFO(altout.lock)); - mutex_init(&ACCESS_FBINFO(fbcon).mm_lock); ACCESS_FBINFO(irq_flags) = 0; init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait)); init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait)); diff --git a/trunk/drivers/video/matrox/matroxfb_crtc2.c b/trunk/drivers/video/matrox/matroxfb_crtc2.c index 909e10a11898..7ac4c5f6145d 100644 --- a/trunk/drivers/video/matrox/matroxfb_crtc2.c +++ b/trunk/drivers/video/matrox/matroxfb_crtc2.c @@ -289,16 +289,13 @@ static int matroxfb_dh_release(struct fb_info* info, int user) { #undef m2info } -static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) -{ +static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) { struct fb_fix_screeninfo *fix = &m2info->fbcon.fix; strcpy(fix->id, "MATROX DH"); - mutex_lock(&m2info->fbcon.mm_lock); fix->smem_start = m2info->video.base; fix->smem_len = m2info->video.len_usable; - mutex_unlock(&m2info->fbcon.mm_lock); fix->ypanstep = 1; fix->ywrapstep = 0; fix->xpanstep = 8; /* TBD */ diff --git a/trunk/drivers/video/mx3fb.c b/trunk/drivers/video/mx3fb.c index 567fb944bd2a..b7af5256e887 100644 --- a/trunk/drivers/video/mx3fb.c +++ b/trunk/drivers/video/mx3fb.c @@ -669,7 +669,7 @@ static uint32_t bpp_to_pixfmt(int bpp) } static int mx3fb_blank(int blank, struct fb_info *fbi); -static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len); +static int mx3fb_map_video_memory(struct fb_info *fbi); static int mx3fb_unmap_video_memory(struct fb_info *fbi); /** @@ -742,7 +742,8 @@ static int mx3fb_set_par(struct fb_info *fbi) if (fbi->fix.smem_start) mx3fb_unmap_video_memory(fbi); - if (mx3fb_map_video_memory(fbi, mem_len) < 0) { + fbi->fix.smem_len = mem_len; + if (mx3fb_map_video_memory(fbi) < 0) { mutex_unlock(&mx3_fbi->mutex); return -ENOMEM; } @@ -1197,7 +1198,6 @@ static int mx3fb_resume(struct platform_device *pdev) /** * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. * @fbi: framebuffer information pointer - * @mem_len: length of mapped memory * @return: Error code indicating success or failure * * This buffer is remapped into a non-cached, non-buffered, memory region to @@ -1205,26 +1205,23 @@ static int mx3fb_resume(struct platform_device *pdev) * area is remapped, all virtual memory access to the video memory should occur * at the new region. */ -static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len) +static int mx3fb_map_video_memory(struct fb_info *fbi) { int retval = 0; dma_addr_t addr; fbi->screen_base = dma_alloc_writecombine(fbi->device, - mem_len, + fbi->fix.smem_len, &addr, GFP_DMA); if (!fbi->screen_base) { dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", - mem_len); + fbi->fix.smem_len); retval = -EBUSY; goto err0; } - mutex_lock(&fbi->mm_lock); fbi->fix.smem_start = addr; - fbi->fix.smem_len = mem_len; - mutex_unlock(&fbi->mm_lock); dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); @@ -1254,10 +1251,8 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi) fbi->screen_base, fbi->fix.smem_start); fbi->screen_base = 0; - mutex_lock(&fbi->mm_lock); fbi->fix.smem_start = 0; fbi->fix.smem_len = 0; - mutex_unlock(&fbi->mm_lock); return 0; } diff --git a/trunk/drivers/video/nvidia/nv_setup.c b/trunk/drivers/video/nvidia/nv_setup.c index eef2bb298d9f..135ae18bfce8 100644 --- a/trunk/drivers/video/nvidia/nv_setup.c +++ b/trunk/drivers/video/nvidia/nv_setup.c @@ -543,7 +543,8 @@ int NVCommonSetup(struct fb_info *info) } else if (analog_on_B) { CRTCnumber = outputBfromCRTC; FlatPanel = 0; - printk("nvidiafb: CRTC %i appears to have a " + printk("nvidiafb: CRTC %i" + "appears to have a " "CRT attached\n", CRTCnumber); } else if (slaved_on_A) { CRTCnumber = 0; diff --git a/trunk/drivers/video/omap/omapfb_main.c b/trunk/drivers/video/omap/omapfb_main.c index 4ea99bfc37b4..060d72fe57cb 100644 --- a/trunk/drivers/video/omap/omapfb_main.c +++ b/trunk/drivers/video/omap/omapfb_main.c @@ -393,10 +393,8 @@ 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); fix->type = FB_TYPE_PACKED_PIXELS; bpp = var->bits_per_pixel; @@ -888,10 +886,8 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) * plane memory is dealloce'd, the other * screen parameters in var / fix are invalid. */ - mutex_lock(&fbi->mm_lock); fbi->fix.smem_start = 0; fbi->fix.smem_len = 0; - mutex_unlock(&fbi->mm_lock); } } } diff --git a/trunk/drivers/video/platinumfb.c b/trunk/drivers/video/platinumfb.c index bacfabd9ce16..03b3670130a0 100644 --- a/trunk/drivers/video/platinumfb.c +++ b/trunk/drivers/video/platinumfb.c @@ -141,9 +141,7 @@ static int platinumfb_set_par (struct fb_info *info) offset = 0x10; info->screen_base = pinfo->frame_buffer + init->fb_offset + offset; - mutex_lock(&info->mm_lock); info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset; - mutex_unlock(&info->mm_lock); info->fix.visual = (pinfo->cmode == CMODE_8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<cmode) diff --git a/trunk/drivers/video/pxafb.c b/trunk/drivers/video/pxafb.c index 6506117c134b..0889d50c3288 100644 --- a/trunk/drivers/video/pxafb.c +++ b/trunk/drivers/video/pxafb.c @@ -815,10 +815,8 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb) ofb->video_mem_phys = virt_to_phys(ofb->video_mem); ofb->video_mem_size = size; - mutex_lock(&ofb->fb.mm_lock); ofb->fb.fix.smem_start = ofb->video_mem_phys; ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; - mutex_unlock(&ofb->fb.mm_lock); ofb->fb.screen_base = ofb->video_mem; return 0; } diff --git a/trunk/drivers/video/sh7760fb.c b/trunk/drivers/video/sh7760fb.c index 9f6d6e61f0cc..653bdfee3057 100644 --- a/trunk/drivers/video/sh7760fb.c +++ b/trunk/drivers/video/sh7760fb.c @@ -120,6 +120,18 @@ static int sh7760_setcolreg (u_int regno, return 0; } +static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info, + unsigned long stride) +{ + memset(fix, 0, sizeof(struct fb_fix_screeninfo)); + strcpy(fix->id, "sh7760-lcdc"); + + fix->smem_start = (unsigned long)info->screen_base; + fix->smem_len = info->screen_size; + + fix->line_length = stride; +} + static int sh7760fb_get_color_info(struct device *dev, u16 lddfr, int *bpp, int *gray) { @@ -322,8 +334,7 @@ static int sh7760fb_set_par(struct fb_info *info) iowrite32(ldsarl, par->base + LDSARL); /* mem for lower half of DSTN */ - info->fix.line_length = stride; - + encode_fix(&info->fix, info, stride); sh7760fb_check_var(&info->var, info); sh7760fb_blank(FB_BLANK_UNBLANK, info); /* panel on! */ @@ -424,8 +435,6 @@ static int sh7760fb_alloc_mem(struct fb_info *info) info->screen_base = fbmem; info->screen_size = vram; - info->fix.smem_start = (unsigned long)info->screen_base; - info->fix.smem_len = info->screen_size; return 0; } @@ -511,8 +520,6 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev) info->var.transp.length = 0; info->var.transp.msb_right = 0; - strcpy(info->fix.id, "sh7760-lcdc"); - /* set the DON2 bit now, before cmap allocation, as it will randomize * palette memory. */ diff --git a/trunk/drivers/video/sh_mobile_lcdcfb.c b/trunk/drivers/video/sh_mobile_lcdcfb.c index da983b720f08..f10d2fbeda06 100644 --- a/trunk/drivers/video/sh_mobile_lcdcfb.c +++ b/trunk/drivers/video/sh_mobile_lcdcfb.c @@ -17,7 +17,6 @@ #include #include #include -#include #include